Chuyển đến nội dung
Diễn đàn CADViet
Học AutoCAD Online cùng CADViet
Đăng nhập để thực hiện theo  
ssg

CadViet’s AutoLisp Public Functions Library

Các bài được khuyến nghị

KẾ THỪA VÀ TÍCH LUỸ TÀI NGUYÊN TRONG LẬP TRÌNH LISP

Tôi có thể nhìn xa hơn người khác, vì tôi đang đứng trên vai những người khổng lồ - Isaac Newton

 

 

A- DẪN NHẬP

 

Bạn đã từng lập trình, đã từng biết đến cái cảm giác “khoái chí không thể diễn tả được” khi chạy thử chương trình. Mọi việc đều diễn ra tốt đẹp, mọi cái đều răm rắp hoạt động y như ý đồ bạn đã vạch ra. Bạn hứng chí muốn làm thêm vài cái như vậy nữa, vừa thoả mãn sự yêu thích, đam mê của bản thân, vừa có được những công cụ mạnh mẽ để làm việc hiệu quả hơn. Thật tuyệt vời!

Nhưng có bao giờ bạn cảm thấy ngán ngẩm vì những dòng code dài lê thê, với những dấu ngoặc xếp hàng hàng lớp lớp, đan xen, chồng chéo lên nhau (cái “món Lisp” này sao mà lắm dấu ngoặc thế không biết!)? Liệu có cách gì để công việc lập trình dễ dàng hơn, đỡ vất vả hơn mà vẫn đạt được hiệu quả cao hay không?

Câu trả lời là có, và đơn giản đến mức hiển nhiên: SỰ KẾ THỪA

 

Mọi chương trình Lisp, dù phức tạp đến đâu, cũng đều được xây dựng từ những viên gạch cực kỳ đơn giản:

 

(Function Arguments)

 

Hãy học cách tạo, cóp nhặt, sưu tầm, tích luỹ những viên gạch ấy, công việc lập trình của bạn sẽ đơn giản, nhẹ nhàng, thoải mái và hiệu quả hơn rất nhiều. Khi đó, bạn chỉ việc chọn và sắp xếp những viên gạch có sẵn ấy cho phù hợp với từng ý đồ cụ thể.

 

Một ví dụ minh hoạ:

Cho trước một polyline. Lập chương trình lấy toạ độ tất cả các đỉnh của nó và ghi kết quả dạng x/y tại mỗi đỉnh.

 

Nếu không có sự kế thừa, làm từ đầu đến cuối theo yêu cầu trên cũng… toát mồ hôi hột! May thay, trong “kho tài nguyên” của chúng ta đã có sẵn các “viên gạch” phù hợp:

- GetVert: lấy toạ độ tất cả các đỉnh của polyline, kết quả return là 1 list of points

- Wtxt: ghi text ra màn hình, với 2 đối số là text (string) và điểm chuẩn (point)

- Nếu polyline là closed, điểm đầu và cuối trùng nhau, nhưng kết quả return của GetVert vẫn lấy đủ, tức là có 1 kết quả thừa. Hàm DelSame có nhiệm vụ bỏ bớt các item trùng nhau trong một list bất kỳ.

 

;;;-------------------------------------------------------
(defun DelSame(L / Ln x) ;;;Delete Same items in List
(foreach x L (if (not (member x Ln)) (setq Ln (append Ln (list x)))))
Ln
)
;;;-------------------------------------------------------
(defun GetVert (e / i L) ;;;Return list of all vertex from Pline e
(setq i 0)
(vl-load-com)
(repeat (fix (+ (vlax-curve-getEndParam e) 1))
   (setq L (append L (list (vlax-curve-getPointAtParam e i))))
   (setq i (1+ i))
)
L
)
;;;-------------------------------------------------------
(defun Wtxt (txt p / sty d h) ;;;Write txt on graphic screen, defaul setting
(setq
   sty (getvar "textstyle")
   d (tblsearch "style" sty)
   h (cdr (assoc 40 d))
)
(if (= h 0) (setq h (cdr (assoc 42 d))))
(entmake
   (list (cons 0 "TEXT") (cons 7 sty) (cons 1 txt) (cons 10 p) (cons 40 h) (assoc 41 d))
)
)
;;;-------------------------------------------------------

 

Các “functions – viên gạch” trên mang tính tổng quát, không phụ thuộc vào đặc điểm riêng của một tình huống cụ thể nào, đã được kiểm nghiệm qua nhiều lần sử dụng và xem như đã chuẩn hoá. Ta cứ vô tư lấy ra mà dùng.

Công việc còn lại chỉ là coding mấy dòng đơn giản:

 

;;;-------------------------------------------------------
(defun C:VD( / e p)
(setq e (car (entsel "\nChon polyline:")))
(foreach p (DelSame (GetVert e)) (Wtxt (strcat (rtos (car p)) "/" (rtos (cadr p))) p))
)
;;;-------------------------------------------------------

 

Cách làm trên không riêng gì Lisp, với bất kỳ ngôn ngữ lập trình nào cũng vậy thôi. Người ta vẫn thường tạo ra các hàm, thủ tục, module… có chức năng tổng quát, có thể sử dụng được trong nhiều chương trình khác nhau, lưu trữ chúng trong các thư viện với nhiều định dạng khác nhau, cần đến cái nào cứ lôi cái đó ra mà “chơi”.

Cách gọi của những tài nguyên này tuỳ theo ngôn ngữ lập trình. Ngôn ngũ Lisp không có sự phân biệt, tất cả các hàm đều có một tên gọi chung là Function và được “đối xử” hoàn toàn bình đẳng. Người lập trình tự phân tích, nhìn nhận, chọn trong các functions mình đã lập những “chú” nào có khả năng “tái sử dụng” thì tách riêng nó ra, chăm chút, chỉnh sửa, hoàn thiện và đưa vào “kho lưu trữ”.

Để phân biệt với các functions khác (mang nhiều tính chất riêng tư, chỉ có tác dụng trong một chương trình cụ thể nào đó) ta có thể đặt cho các functions đã chọn lọc nói trên một cái tên: “Public Functions – các hàm dùng chung”.

 

 

B- ĐẶT VẤN ĐỀ

Ai đã từng lập trình với Lisp một thời gian có lẽ cũng đã tự “tích cóp” cho mình một “kho tài nguyên” về các Public Functions. Ssg lập topic này với mong muốn cộng đồng lập trình viên Lisp của CadViet cùng nhau giao lưu, chia sẻ, gom góp lại để tạo nên một kho tài nguyên lớn hơn, hoành tráng hơn, hiệu quả hơn với tên gọi CadViet’s AutoLisp Public Functions Library

 

 

C- KẾ HOẠCH THỰC HIỆN

Gồm các bước sau:

 

1. Thu thập

Rất đơn giản, ai có cái gì hay thì post lên để anh em cùng “ngâm cứu”

 

2. Phân tích và chỉnh sửa

Phân tích ưu nhược điểm, chỉnh sửa code cho hay hơn, gọn gàng hơn, tổng quát hơn, phạm vi áp dụng rộng rãi hơn… Đây là bước quan trọng, đòi hỏi trí tuệ tập thể cao nhất.

 

3. Thử nghiệm và chuẩn hoá

Mỗi người tự áp dụng trong các chương trình của mình, phát hiện các sai sót, đề xuất các sửa đổi tinh tế hơn. Khi không còn ai ý kiến ý cò gì khác, tạm thời xem như đã được chuẩn hoá, cứ y như vậy và vô tư dùng.

 

4. Hệ thống hoá

Khi đã thu thập được kha khá, cần hệ thống lại để tiện tra cứu và sử dụng. Việc này đơn giản thôi, chỉ cần lập bảng thống kê tương tự như Help của Acad đã làm theo 2 dạng:

- Theo nhóm chức năng

- Theo ABC

 

5. Phát triển

Không ngừng hoàn thiện và bổ sung trong quá trình sử dụng

 

Lưu ý:

Các bạn mới tiếp cận với Lisp cũng đừng ngại ngần. Có thể các bạn chưa hiểu hết ý tứ của các code trong chương trình, nhưng các bạn vẫn sử dụng chúng rất hiệu quả. Điều quan trọng là phải cung cấp đủ và đúng kiểu các đối số mà function đó yêu cầu. Qua sử dụng, dần dần các bạn sẽ hiểu ra nhiều vấn đề. Có khó khăn gì cứ nêu lên, anh em sẽ hỗ trợ.

 

Mong rằng các bạn sẽ ủng hộ và cùng nhau chung sức phát triển topic này.

Cám ơn tất cả các bạn,

Ssg

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
KẾ THỪA VÀ TÍCH LUỸ TÀI NGUYÊN TRONG LẬP TRÌNH LISP

Tôi có thể nhìn xa hơn người khác, vì tôi đang đứng trên vai những người khổng lồ - Isaac Newton

A- DẪN NHẬP

 

Ssg

Cám ơn SSG nhiều mình tin rằng topic này sẽ thành công ^_^

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cám ơn bác đã đưa ra ý tưởng này. Em thấy rất hay và thực tế là em đã làm nó từ khi em đến với Lisp. Cách quản lý và lập trình của em như sau: Em có 1 file lisp riêng chuyên về các hàm con (các hàm này chỉ được thêm chứ tuyệt đối không được đổi tên vì nó sẽ ảnh hưởng đến các lisp sử dụng nó mà ta không thể kiểm soát hết được), một file lisp về các lệnh tắt đơn giản (những lệnh này không đáng phải làm một file chương trình riêng), và các file lisp chương trình riêng. Cách quản lý như thế này sẽ tránh gần như tuyệt đối sự "đá nhau" giữa các hàm mà ta không kiểm soát được, làm cho chương trình lisp viết sẽ nhanh và gọn hơn, và còn nhiều nhiều cái lợi ích nữa. Với khối lượng hàm con tương đối nhiều thì em đã phân loại theo ứng dụng (hàm con về nhập số liệu, hàm con về xử lý số liệu, hàm con về xuất kết quả....) , khối lượng hàm con nhiều như thế nên em dùng Notepad++ để view và lấy nó ra (cái này em thích nhất ở thằng Notepad++ vì nó có thể ẩn các nội dung hàm đi chỉ hiện tên hàm để tìm kiếm cho nhanh).

Em cũng rất thích công việc tập hợp và quản lý "này". Chính vì vậy ngay từ khi gặp ý tưởng của bác ssg em đã "kết" ngay. Tuy nhiên ta nên tập hợp 1 nhóm người làm việc này thôi, sau khi nhóm "ưng ý" rồi mới đưa ra cho các anh em kiểm nghiệm. Với niềm đam mê cùng với một chút kiến thức, kinh nghiệm ít ỏi của mình em xin được tham gia vào nhóm công việc này.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Nhất trí 2 tay với bác Ssg.

 

gửi nataca: Theo mình ở giai đoạn này điều quan trọng nhất là đầu mục trước. Nghĩa là tên hàm, chức năng hàm sẽ làm việc rồi mới tới lisp đi kèm. Vì ai viết lisp cũng đều cũng đã có một thư viện hàm public cho mình. Muốn thống nhất thành một bộ Public Functions của CADViet thì điều đầu tiên mình nên làm là gọi mặt điểm tên trước, rồi viết code và tối ưu hóa sau.

  • Vote tăng 1

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Nhất trí 2 tay với bác Ssg.

 

gửi nataca: Theo mình ở giai đoạn này điều quan trọng nhất là đầu mục trước. Nghĩa là tên hàm, chức năng hàm sẽ làm việc rồi mới tới lisp đi kèm. Vì ai viết lisp cũng đều cũng đã có một thư viện hàm public cho mình. Muốn thống nhất thành một bộ Public Functions của CADViet thì điều đầu tiên mình nên làm là gọi mặt điểm tên trước, rồi viết code và tối ưu hóa sau.

Em đồng ý với ý kiến của bác. Việc đầu tiên ta nên làm là như thế.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Một điều nữa cần lưu ý là nên thống nhất cách đặt tên biến, tên hàm... để cho các hàm con cuả chúng ta đồng nhất, nếu kg nhìn vào cái đống hàm con đó rất lộn xộn.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Wow! Các bạn ủng hộ quá nhiệt tình làm ssg đâm hoảng! Xin cám ơn tất cả và hứa sẽ cố gắng.

Ssg đã xem kỹ các ý kiến của các bạn, và thật tình cũng chưa biết bắt đầu như thế nào. Tạm thời, xin đưa ra vài ý:

 

A- CHIA NHÓM THEO CHỨC NĂNG

(các ví dụ kèm theo là để minh hoạ cho rõ ý hơn)

 

1. Tính toán số học, đại số và hình học

Ví dụ, hàm đổi độ sang radian:

(defun DTR(x) (/ (* x pi) 180) )

 

hoặc hàm lấy chiều dài của 1 curve (đối tượng “đường” nói chung):

(defun LenCurve(e)

(vl-load-com)

(vlax-curve-getDistAtParam e (vlax-curve-getEndParam e))

)

 

2. Xử lý list, string, ss và entity

Ví dụ:

Ss2Ent anh Hoành lập và được dùng khá phổ biến trên diễn đàn, hoặc hàm DelSame trong bài đầu tiên của topic này.

 

3. Các thao tác với layer, block, textstyle, linetype, dimstyle…

Ví dụ, hàm lấy tất cả các layer có trong bản vẽ:

(defun GetLay(/ Lay Laylist)

(setq Lay (tblnext "LAYER" T) Laylist nil)

(While Lay (setq Laylist (append Laylist (list (cdr (assoc 2 Lay)))) Lay (tblnext "LAYER")))

(acad_strlsort Laylist)

)

 

4. Các thao tác nhập, xuất

Hỗ trợ nhập số liệu của user và xuất kết quả. Ví dụ, hàm Wtxt trong bài đầu tiên của topic

 

5. Bảng biểu, database và ActiveX

- Đọc và số liệu từ các file database với nhiều định dạng khác nhau, xử lý chúng theo mục đích sử dụng

- Xuất kết quả sang các file database

- Tương tác với các môi trường và phần mềm khác

 

6. Dialog

Hỗ trợ việc điều khiển các dialog trong chương trình lisp

 

7. Các thao tác liên quan đến file, folder và system

Ví dụ, thêm một Path vào Support File Search Path:

(defun AddSPath(s)

(setenv "ACAD" (strcat (getenv "ACAD") ";" s))

)

 

8. Khác

Các công việc không thuộc các nhóm trên

 

B- ĐẶT TÊN CÁC FUNCTIONS

 

Xin ghi nhận ý kiến của bạn Nộ Thiên, vấn đề đặt tên cần phải cân nhắc kỹ. Khi triển khai sẽ có một cái vướng, mỗi người đều có cách đặt tên các functions của riêng mình. Khi thống nhất tên sẽ "đụng chạm" nhiều. Theo ssg, có lẽ phải chấp nhận thôi. Từng người sẽ có 2 phương án giải quyết:

a- Sửa cái riêng của mình theo cái chung

b- Làm ngược lại.

Ssg khuyến khích dùng phương án a, khi chúng ta trao đổi chương trình với nhau sẽ thuận tiện hơn. Thật ra thì cũng không mất công nhiều lắm nếu ta dùng tính năng Find và Replace của các trình Text Editor.

 

Vấn đề là đặt tên như thế nào? Xin nêu ra các tiêu chí:

- Thể hiện được phần nào nội dung, bản chất, công dụng của function

- Ngắn gọn, rõ ràng, súc tích, dễ nhớ

- Nhất quán

Với các tiêu chí trên, dùng tên viết tắt, ghép bằng tiếng Anh và/hoặc thuật ngữ của AutoCAD-AutoLisp là hợp lý nhất. Có thể kết hợp với cách viết chữ hoa, chữ thường để phân biệt rõ các thành phần ghép.

Ví dụ:

DTR: Degree To Radian

DelSame: Delete Same item in list

Wtxt: Write Text on graphic screen

 

Nói chung là vậy nhưng không cứng nhắc. Ví dụ, trong trường hợp một số từ tiếng Anh không thông dụng có thể "chơi" bằng tiếng Việt, hoặc Anh-Việt kết hợp cũng không vấn đề gì, miễn là nó dễ hiểu!

 

C- TRÌNH TỰ TIẾN HÀNH

Ý kiến anh Hoành rất hợp lý, nên đưa ra cái tổng quát trước, chi tiết cụ thể tính sau. Tuy nhiên, ssg thấy thế này, mỗi function đều có tính độc lập riêng của nó. Ta vẫn có thể đưa ra functions trước, hệ thống hoá sau cũng chẳng hề gì. Ssg đề nghị thực hiện luôn 2 hướng cùng lúc:

 

1. Các bạn có những functions nào hay, đặc sắc, mang tính tổng quát cao, có công dụng rộng cứ nêu lên. Anh em cùng phân tích, mổ xẻ sẽ hào hứng hơn.

 

2. Việc soạn một cái list tổng thể, có lẽ trước hết nên do một vài người đảm nhiệm. Khi đã thấy tạm ổn sẽ đưa lên cho bá quan thiên hạ góp ý, bổ sung. Cụ thể, ssg đề nghị các thành viên sau vào "Ban biên tập":

- Ssg (đương nhiên, vì đã... trót đề xướng ra cái topic này!)

- Nataca (cũng đương nhiên, vì là người xung phong đầu tiên!)

- Anh Hoành (cũng đương nhiên, vì là người "đứng mũi chịu sào" của diễn đàn Lisp nói riêng và CadViet nói chung!)

- Nộ Thiên (đã có "bề dày kinh nghiệm" với Lisp, không dám nói đương nhiên, tuỳ ý riêng của bạn thôi)

Nếu các thành viên có tên trên không phản đối, tức là... đương nhiên đồng ý!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
"Kẻ liều mạng" đang hỏi SSG: Tên mình đâu...?

 

 

Chỉ muốn hỏi các bác đã có phương án quản lý sourcode và quản lý tài liệu thế nào chưa?

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Chỉ muốn hỏi các bác đã có phương án quản lý sourcode và quản lý tài liệu thế nào chưa?

Rất đồng tình với ý kiến của VNDESPERADOS ... bác SSG nên có ph.án về 2 mảng này

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
"Kẻ liều mạng" đang hỏi SSG: Tên mình đâu...?

1. Lúc ssg lên danh sách đề cử, chỉ căn cứ vào những thành viên đã có ý kiến với topic, tức là đã thể hiện sự quan tâm. Những người khác, ssg chưa dám đề cập đến (có thể người ta không quan tâm, đang bận... kiếm tiền tiêu Tết, bận tiệc tùng đình đám cuối năm v.v...). Giờ thì khác, vndes đã có ý kiến, tức là đã có sự quan tâm, ssg nhiệt liệt hoan nghênh các ý kiến tư vấn của bạn, với tư cách là một chuyên gia IT.

 

2. Về việc quản lý source code và tài liệu, ssg chưa hiểu rõ ý của vndes. Thật tình thì ssg chỉ nghĩ đơn giản: ai lập trình cũng có cái "kho tài nguyên" của riêng mình, việc đề xướng topic này thực chất là gom các "kho" đơn lẻ ấy lại, chọn lọc, chỉnh sửa... và cho vào cái kho chung của diễn đàn (như đúng tên gọi của topic). Và theo như tôn chỉ của CadViet, kho tài nguyên này hoàn toàn free, ai thích cứ việc dùng và nếu cảm thấy có trách nhiệm với cộng đồng thì đóng góp thêm vào những gì mình có.

 

3. Việc biên soạn danh mục các Functions, ssg xin đưa ra cái form như sau (lấy nhóm 1 làm ví dụ):

http://www.cadviet.com/upfiles/BangKe_01.zip

 

Các bạn xem và cho ý kiến. Về thành phần "Ban biên tập", nếu các bạn nhất trí thì theo ssg, 4 người là tạm đủ. Nhiệm vụ trước tiên là lên cái list theo form đã thống nhất. Phân công thì đơn giản thôi, có 8 nhóm functions, mỗi người 2 nhóm. Ai thấy thích hoặc sở trường về nhóm nào thì tự đăng ký, còn lại 2 nhóm cuối ssg sẽ đảm nhiệm.

Khi hoàn thành các bảng danh mục thì post lên, mọi người sẽ góp ý sửa đổi, bổ sung. Hoàn thành các bảng danh mục, ta sẽ bàn tiếp cách triển khai.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
1. Lúc ssg lên danh sách đề cử, chỉ căn cứ vào những thành viên đã có ý kiến với topic, tức là đã thể hiện sự quan tâm. Những người khác, ssg chưa dám đề cập đến (có thể người ta không quan tâm, đang bận... kiếm tiền tiêu Tết, bận tiệc tùng đình đám cuối năm v.v...). Giờ thì khác, vndes đã có ý kiến, tức là đã có sự quan tâm, ssg nhiệt liệt hoan nghênh các ý kiến tư vấn của bạn, với tư cách là một chuyên gia IT.

 

2. Về việc quản lý source code và tài liệu, ssg chưa hiểu rõ ý của vndes. Thật tình thì ssg chỉ nghĩ đơn giản: ai lập trình cũng có cái "kho tài nguyên" của riêng mình, việc đề xướng topic này thực chất là gom các "kho" đơn lẻ ấy lại, chọn lọc, chỉnh sửa... và cho vào cái kho chung của diễn đàn (như đúng tên gọi của topic). Và theo như tôn chỉ của CadViet, kho tài nguyên này hoàn toàn free, ai thích cứ việc dùng và nếu cảm thấy có trách nhiệm với cộng đồng thì đóng góp thêm vào những gì mình có.

 

3. Việc biên soạn danh mục các Functions, ssg xin đưa ra cái form như sau (lấy nhóm 1 làm ví dụ):

http://www.cadviet.com/upfiles/BangKe_01.zip

 

Các bạn xem và cho ý kiến. Về thành phần "Ban biên tập", nếu các bạn nhất trí thì theo ssg, 4 người là tạm đủ. Nhiệm vụ trước tiên là lên cái list theo form đã thống nhất. Phân công thì đơn giản thôi, có 8 nhóm functions, mỗi người 2 nhóm. Ai thấy thích hoặc sở trường về nhóm nào thì tự đăng ký, còn lại 2 nhóm cuối ssg sẽ đảm nhiệm.

Khi hoàn thành các bảng danh mục thì post lên, mọi người sẽ góp ý sửa đổi, bổ sung. Hoàn thành các bảng danh mục, ta sẽ bàn tiếp cách triển khai.

Em thì ngoài Dialog là không hay dùng đến thì nhóm chức năng nào cũng được. Tuy nhiên em thấy nhóm 2 và 3 có vẻ nặng ký nhất .

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
"Kẻ liều mạng" đang hỏi SSG: Tên mình đâu...?

 

 

Tôi chưa có ý đinh tham gia vào cái này vì không chắc là có thời gian. Chỉ xim lưu ý về các bác về cách tổ chức và quản lý.

Nếu tôi nhớ không nhầm thì đã có một project chưa hòan thành và việc đó nằm ở khâu tổ chức và quản lý (tôi đã từng lưu ý điều này).

Những gì mà các bác để lại sau cái project đó ai sẽ tiếp nhận được và ai sẽ tiếp tục được?

Dự án lần này có vẽ như kỹ thuật thì khả thi hơn nhưng quy mô lại rộng hơn rất nhiều.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Tôi chưa có ý đinh tham gia vào cái này vì không chắc là có thời gian. Chỉ xim lưu ý về các bác về cách tổ chức và quản lý.

Nếu tôi nhớ không nhầm thì đã có một project chưa hòan thành và việc đó nằm ở khâu tổ chức và quản lý (tôi đã từng lưu ý điều này).

Những gì mà các bác để lại sau cái project đó ai sẽ tiếp nhận được và ai sẽ tiếp tục được?

Dự án lần này có vẽ như kỹ thuật thì khả thi hơn nhưng quy mô lại rộng hơn rất nhiều.

Theo mình nghĩ thì cách quản lý của bác Ssg như vậy là ổn rồi, mình không cần hoành tráng làm gì. Cứ đơn giản mạch lạc là được.

 

Các dự án nói chung không hoàn thành chỉ vì không có ai làm chứ không phải vì vấn đề tổ chức.

 

Mọi người ai cũng góp 1 tay, nói ít làm nhiều tự khắc dự án sẽ đến đích. Các dự án của chúng ta bé như cái kẹo, không cần rập khuôn các dự án lớn làm gì, vì vèo một cái đã làm xong, ngồi bàn thì nhiều khi thời gian bàn nhiều hơn thời gian làm. Cái khó của chúng ta là vấn đề 'ai thực sự làm' chứ không phải 'làm như thế nào'.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cái này hay đấy, elleHCSC rất ủng hộ.

Tuy nhiên nên lưu ý tới ý kiến của VNdes... nhá quản lý code sẽ như thế nào đây? mã lisp mở mà dễ bị tam sao thất bản quá

Tên hàm thì theo mình nên đặt bằng tiếng Anh và đầy đủ (dài 1 tý cũng ko sao), vd DTR thì mình nên đặt hẳn thành DegreeToRadial, getVert thì đặt hẳn thành GetVertex cho nó dễ nhớ và dể tưởng tượng... hay như chính lisp của Autodesk này : vlax-curve-getDistAtParam đọc cái là hiểu hàm này nó định làm gì. Có thể chúng ta học ngay cách phân loại hàm theo nhóm như các ngôn ngữ khác (C, pascal) họ hay làm là chia các hàm theo nhóm : System, Math, String, List, graphic...

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Theo mình nghĩ thì cách quản lý của bác Ssg như vậy là ổn rồi, mình không cần hoành tráng làm gì. Cứ đơn giản mạch lạc là được.

 

Các dự án nói chung không hoàn thành chỉ vì không có ai làm chứ không phải vì vấn đề tổ chức.

 

Mọi người ai cũng góp 1 tay, nói ít làm nhiều tự khắc dự án sẽ đến đích. Các dự án của chúng ta bé như cái kẹo, không cần rập khuôn các dự án lớn làm gì, vì vèo một cái đã làm xong, ngồi bàn thì nhiều khi thời gian bàn nhiều hơn thời gian làm. Cái khó của chúng ta là vấn đề 'ai thực sự làm' chứ không phải 'làm như thế nào'.

Tuy nhỏ nhưng nếu chịu khó góp ý sẽ hiệu quả hơn:

Mèo tui xin mạo muội góp 1 vài ý như sau

1-Nên bàn 1 file sẽ chứa bao nhiêu hàm ??????? (Có thể chia chức năng theo các file này...vậy chỉ cần 8 file???). Và tên file phải tạo nên dấu ấn Cadviet

2-Nên có 1 hướng dẫn về file đó và có bảng liệt kê danh mục các hàm, chức năng của nó. Ví dụ: bảng liệt kê tên hàm, số đối mục của mỗi hàm: trong đó kiểu của đối mục -> chuỗi, value.., obiect ...; cách áp dụng.

3-Ví dụ 1 vài ch.trình áp dụng các hàm cho kết qủa tốt.

4-Có phương án cập nhật các hàm mỗi tuần 1 lần do các mem post lên...

5-Có mục bàn luận về các code gây lỗi để anh em cùng nhau học hỏi rút kinh nghiệm

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Người viết Lisp ai cũng có một vài hàm riêng của mình, phục vụ cho Lisp đó. Nếu ai có thì đưa vô thư viện do SSG quản lý, có chú dẫn cho người khác sử dụng dễ dàng để phát triển lisp của họ. Người nào đặt hàng thì cùng vô topic này và trao đổi với nhau.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Chân thành cám ơn ý kiến của tất cả các bạn. Mọi người nhiệt tình như vậy, ssg tin rằng mục tiêu chúng ta đặt ra sẽ thành công.

Nói chung, việc ta đang làm ssg thấy nó cũng bình thường như các việc khác đã làm trên diễn đàn thôi. Đứng quan trọng hoá vấn đề, đừng đao to búa lớn làm gì. Nói cho cùng là anh em ta hỗ trợ và học hỏi lẫn nhau để công việc lập trình đỡ vất vả hơn thôi mà. Ssg cũng không đặt ra vấn đề quản lý. Có cái gì đâu mà quản lý? Mã nguồn mở, post công khai trên diễn đàn, ai thấy thích cứ việc dùng và cho ý kiến đóng góp. Đơn giản vậy thôi.

 

@elle:

Đặt tên như bạn nêu cũng có cái hay, nhưng cái dở là code sẽ dài hơn, vừa mất công gõ phím, vừa bị xuống dòng nhiều, code bị dàn trải trên nhiều dòng sẽ làm hạn chế cái nhìn tổng thể của người lập trình cho toàn bộ chương trình. Như bạn thấy, rất nhiều các hàm chuẩn của Lisp vẫn dùng tên ghép viết tắt: entsel, ssget, getvar, getint… Tóm lại, ssg vẫn bảo lưu quan điểm đặt tên functions như đã nói trên. Ai cảm thấy không hợp thì… tự sửa! Với quan điểm đó, cũng không đặt vấn đề “tam sao thất bản”. Ai muốn dùng thống nhất để dễ trao đổi thì để yên, ai không thích thì tự sửa lấy theo ý riêng, chẳng ảnh hưởng gì đến… hoà bình thế giới!

 

@meohoang:

1. Một file muốn mấy hàm và đặt tên file là gì tuỳ ý mỗi người, quan trọng là trong hàm chứa cái gì (thói quen của ssg là cho tất cả các Public Functions vào 1 file, luôn luôn autoload khi khởi động CAD, đỡ phải lằng nhằng).

2. Tất nhiên, ssg đã nói ngay từ bài đầu tiên của topic

3. Không cần thiết, mỗi người tự áp dụng và tự chiêm nghiệm. Có khó khăn gì thì nêu lên, anh em sẽ hỗ trợ.

4. Khi có bài mới, ai quan tâm đến topic này sẽ biết. Việc update sẽ do người chịu trách nhiệm biên tập xem xét và quyết định khi thích hợp, không áp đặt định kỳ.

5. Các bạn cứ thoải mái thảo luận ngay trong topic này

 

Để các bạn hình dung rõ hơn thực chất của công việc, ssg xin post một đoạn minh hoạ. Đây là đoạn đầu của phần 1 (sẽ tiếp tục biên soạn thêm):

 

;;;=================================
;;;CadViet's AutoLisp Public Functions Library
;;;Part 1 - MATHEMATICAL AND GEOMETRIC FUNCTIONS
;;;Copyright by CadViet Forum - www.cadviet.com - January 2009
;;;Welcome all contributions for develop this Library!
;;;=================================


;;;-------------------------------------------------------------
(defun DTR (x) (/ (*  x pi) 180) ) ;;;change Degree To Radian, return Real
;;;-------------------------------------------------------------
(defun RTD (x) (/ (* x 180) pi) ) ;;;change Radian To Degree, return Real
;;;-------------------------------------------------------------
(defun Tang (x) (/ (sin x) (cos x)) ) ;;;Tang(x), return Real
;;;-------------------------------------------------------------
(defun CoTang (x) (/ (cos x) (sin x)) ) ;;;Cotang(x), return Real
;;;-------------------------------------------------------------
(defun Asin (x) ;;;Arcsin(x)
(cond 
((and (< x 1) (> x -1)) (atan (/ x (sqrt (- 1 (expt x 2))))) )
((= x 1) (/ pi 2))
((= x -1) (/ pi -2))
)
) ;;;return Real
;;;-------------------------------------------------------------
(defun Acos (x) (- (/ pi 2) (asin x))) ;;;Arccos(x), return Real
;;;-------------------------------------------------------------
(defun Rnd (x) (if (>= x 0) (fix (+ x 0.5)) (fix (- x 0.5)))) ;;;Round x, return Integer
;;;-------------------------------------------------------------
(defun Round (x i) ;;;Round x, i digit after decimal point
(/ (float (rnd (* x (expt 10 i)))) (expt 10 i)) 
) ;;;return Real
;;;-------------------------------------------------------------
(defun Aver2 (x y) (/ (+ (float x) (float y)) 2) ) ;;;Average x & y, return Real
;;;-------------------------------------------------------------
(defun AverL (L / tot x) ;;;calc Average from List of reals, return Real
(setq tot 0.0)
(foreach x L (setq tot (+ tot x)))
(if L (/ tot (length L)))
)
;;;-------------------------------------------------------------
(defun GetVert (cur / i L) ;;;Vertexs of pline, or end points of line, arc 
(setq i 0)
(vl-load-com)
(repeat (fix (+ (vlax-curve-getEndParam cur) 1))
   (setq L (append L (list (vlax-curve-getPointAtParam cur i))))
   (setq i (1+ i))
)
L
) ;;;Return List of Point
;;;-------------------------------------------------------------
(defun LenCurve (cur) ;;;Length of curve, return Real
(vl-load-com)
(vlax-curve-getDistAtParam cur (vlax-curve-getEndParam cur))
)
;;;-------------------------------------------------------------
(defun Mid2P (p1 p2) ;;Middle point from p1, p2
(list (Aver2 (car p1) (car p2)) (Aver2 (cadr p1) (cadr p2)) (Aver2 (caddr p1) (caddr p2)))
) ;;;return Point
;;;-------------------------------------------------------------
(defun Centroid (e / obj var) ;;;Centroid of Region or 3dSolid
(vl-load-com)
(setq
   obj (vlax-ename->vla-object e)
   var (vlax-variant-value (vlax-get-property obj 'centroid))
)
(vlax-safearray->list  var) ;;;return Point
)
;;;-------------------------------------------------------------
(defun Center (e) (cdr (assoc 10 (entget e)))) ;;;Center of Circle or Ellipse, return Point
;;;-------------------------------------------------------------
;;;Continue...

 

Và đây là bảng thống kê theo chức năng tương ứng:

 

http://www.cadviet.com/upfiles/Part1.zip

 

Khi hoàn thiện sẽ có 1 bảng tổng hợp theo ABC cho toàn bộ các functions để tiện tra cứu. Không cần thêm bảng hướng dẫn gì khác vì trong bảng kê đã nêu đủ cả.

 

Người chịu trách nhiệm biên tập sẽ post các functions và bảng kê như ssg đã làm ở trên. Các bạn xem xét cả bảng kê lẫn code, dùng thử, check lỗi… và cho ý kiến đóng góp, đề xuất bổ sung thêm các functions mà các bạn cho là cần thiết (có cả code càng tốt, không thì chỉ cần nêu ý tưởng). Người biên tập sẽ xem xét toàn diện và chỉnh sửa, bổ sung cho phù hợp. Cụ thể, ngay từ thời điểm này, các bạn có thể tham gia đóng góp ý kiến cho đoạn code ssg vừa post ở trên được rồi.

 

Về phân công trong Ban biên tập, không thấy ai có ý kiến cụ thể, ssg xin mạn phép phân công như sau:

1. Bạn Nataca: tiếp phần 1 mà ssg đã post trên + phần 4

2. Anh Hoành: phần 2 và 7

3. Bạn Nộ Thiên: phần 3

4. Ssg: phần 5 và 6

Phần 8 không là cái gì cụ thể, ai thấy có cái gì hay, không thuộc 7 phần trên cũng cứ nêu lên. Khi biên tập lần cuối, ta sẽ cho vào đó.

 

Có một vấn đề là, trong các phần khác, có nhiều khả năng sẽ áp dụng các functions của phần 1 và 2. Vì vậy, các bạn ưu tiên thực hiện 2 phần này trước.

Có thẻ cách làm trên còn nhiều chỗ chưa hợp lý và bất cập. Nhưng có lẽ ta cứ làm, sai đâu sửa đó hơn là chỉ bàn bạc suông!

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Chân thành cám ơn ý kiến của tất cả các bạn. Mọi người nhiệt tình như vậy, ssg tin rằng mục tiêu chúng ta đặt ra sẽ thành công.

Nói chung, việc ta đang làm ssg thấy nó cũng bình thường như các việc khác đã làm trên diễn đàn thôi. Đứng quan trọng hoá vấn đề, đừng đao to búa lớn làm gì. Nói cho cùng là anh em ta hỗ trợ và học hỏi lẫn nhau để công việc lập trình đỡ vất vả hơn thôi mà. Ssg cũng không đặt ra vấn đề quản lý. Có cái gì đâu mà quản lý? Mã nguồn mở, post công khai trên diễn đàn, ai thấy thích cứ việc dùng và cho ý kiến đóng góp. Đơn giản vậy thôi.

Ok!!!!!!!!! Công việc bắt đầu chạy rùi đấy

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cuối năm, mọi người chắc bận rộn nên có vẻ... im ắng quá? Ssg xin hâm nóng topic này bằng một câu hỏi:

 

Lisp có thể truy cập data từ file Microsoft Access *.mdb không?

 

Để biết câu trả lời, mời các bạn tham khảo:

 

http://www.cadviet.com/upfiles/ADO.zip

 

Ghi chú:

- Cái này ssg mới sưu tầm trên net, post lên để các bạn cùng "ngâm cứu"

- File ADOLISP_Library.lsp gồm các functions để làm việc với ADO (ActiveX Data Objects)

- File Example1.lsp là ví dụ của tác giả

- File Example2.lsp là thử nghiệm của ssg, lấy data từ file ThepHinh.mdb và gán cho biến Res. Res là một list, bạn muốn làm gì với nó tuỳ ý.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Gần tết bận rộn nên nhiệm vụ bác Ssg giao chưa hoàn thành được nhiều.

 

Đành phải có gì thì post lên cái đó vậy.

2. Hàm về list, string, ss và entity xin được liệt kê trước các tên hàm sau (mã lệnh sẽ chuốt lại và post lên sau):

- (Explode str ex):

Chia chuỗi str thành list các từ được phân cách bởi ex.

Ví dụ (Explode "1 2 3 4" " ") sẽ trả về list ("1" "2" "3" "4")

 

- (Implode lst ex):

Ngược lại của hàm Explode nối các từ nằm trong list thành một chuỗi.

Ví dụ (Implode '("1" "2" "3" "4")) sẽ trả về chuỗi "1 2 3 4"

 

- (Pos str sub)

Tìm vị trí của chuỗi sub trong chuỗi str, nếu không tồn tại thì trả về giá trị nil. Vị trí đầu tiên là 1.

 

- (Replace str search repby)

Tìm trong chuỗi str những cụm từ search và thay bằng repby.

 

- (ToLow str)

Biến toàn bộ chữ trong chuỗi str thành chữ thường

Ví dụ: (StrToUp "CADViet") sẽ trả về "cadviet".

 

- (StrToUp str)

Biến toàn bộ chữ trong chuỗi str thành chữ hoa

Ví dụ: (StrToUp "CADViet") sẽ trả về "CADVIET".

 

- (StrWidth lst)

Xác định chiều rộng thực tế của một đối tượng text. lst là giá trị trả về từ hàm entget.

 

- (StrHeight lst)

Xác định chiều cao thực tế của một đối tượng text. lst là giá trị trả về từ hàm entget.

 

- (Strtrans str srclst deslst)

Tìm trong chuỗi str những từ xuất hiện trong srclst và thay nó bằng những từ xuất hiện trong deslst. Hàm này giống hàm Replace nhưng nó làm với một tập hợp các từ.

Ví dụ (Strtrans "abc" '("a" "c") '("x" "y")) sẽ trả về "xby".

 

- (exec func ss)

Gọi hàm func lần lượt với tất cả các ename trong tập chọn ss. Kết quả trả về tổng tất cả các giá trị mà hàm func trả về.

Ví dụ: (exec '(lambda(e) (command ".area" "o" e)) ss) sẽ trả về tổng diện tích của tất cả các đối tượng trong tập chọn ss.

 

- (ss2ent ss)

Chuyển tập chọn ss thành tập hợp (list) các đối tượng ename.

 

- (getattr e)

Trả về tập hợp tất cả các giá trị text thuộc tính của đối tượng block có ename là e.

 

- (setattr e lst)

Gán tất cả các giá trị text thuộc tính trong block có ename là e với giá trị có trong tập hợp lst. Nếu giá trị nào là nil thì bỏ qua.

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
... Đành phải có gì thì post lên cái đó vậy...

 

1. Anh Hoành xem lại, những function đã có của lisp không cần lập nữa. Cụ thể:

Pos (đã có vl-string-search)

ToLow, StrtoUp (đã có strcase)

 

2. Không cần cầu toàn, có cái nào anh cứ post lên (cả code) cái đó, mọi người sẽ cùng hoàn thiện và bổ sung thêm.

 

3. Ssg bổ sung function xoá các thành phần trùng nhau trong 1 list:

(defun RemDupl (lst)
(if lst (cons (car lst) (RemDupl (vl-remove (car lst) (cdr lst)))))
)

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác
Lisp có thể truy cập data từ file Microsoft Access *.mdb không?

 

Để biết câu trả lời, mời các bạn tham khảo:

 

http://www.cadviet.com/upfiles/ADO.zip

 

Ghi chú:

- Cái này ssg mới sưu tầm trên net, post lên để các bạn cùng "ngâm cứu"

- File ADOLISP_Library.lsp gồm các functions để làm việc với ADO (ActiveX Data Objects)

- File Example1.lsp là ví dụ của tác giả

- File Example2.lsp là thử nghiệm của ssg, lấy data từ file ThepHinh.mdb và gán cho biến Res. Res là một list, bạn muốn làm gì với nó tuỳ ý.

Ssg đang còn vướng mắc vài điều:

 

1. Với *.mdb thì tốt rồi, nhưng ssg đã thử dùng ADOLISP_Library.lsp cho *.xls, thay đổi đủ các kiểu nhưng vẫn chưa được.

Với *.xls, ssg vẫn dùng cái GET_xl sau:

 

;;;-----------------------------------------------------
(defun rec-rem-dupl (lst)
(if lst (cons (car lst) (rec-rem-dupl (vl-remove (car lst) (cdr lst)))))
)
;;;-----------------------------------------------------
(defun GET_xl (tbl / ADOCONNECT ADORECORDSET LST)
 (setq
   ADOConnect	 (vlax-get-or-create-object "ADODB.Connection")
   ADORecordset (vlax-get-or-create-object "ADODB.Recordset")
 )
 (if
   (not
     (vl-catch-all-error-p
(vl-catch-all-apply
  (function vlax-invoke-method)
  (list	ADOConnect
	"Open"
	(strcat	"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
		tbl
		";Extended Properties=;Excel 8.0;HDR=No"
	)
	"admin"
	""
	nil
  )
)
     )
   )
    (progn
      (setq
 lst (mapcar
       (function
	 (lambda (l / i c)
	   (vlax-invoke-method
	     ADORecordset
	     "Open"
	     (strcat "SELECT * FROM [" l "]")
	     ADOConnect
	     1
	     3
	     nil
	   ) ;_  vlax-invoke-method
	   (setq
	     i (length
		 (car
		   (vlax-safearray->list
		     (vlax-variant-value
		       (vlax-invoke-method
			 ADORecordset
			 "GetRows"
			 65535
		       ) ;_  vlax-invoke-method
		     ) ;_  vlax-variant-value
		   ) ;_  vlax-safearray->list
		 ) ;_  car
	       ) ;_  length
	   ) ;_  setq
	   (vlax-invoke-method ADORecordset "Close")
	   (while (not (zerop i))
	     (vlax-invoke-method
	       ADORecordset
	       "Open"
	       (strcat "SELECT * FROM ["
		       l
		       "a"
		       (itoa i)
		       ":IV"
		       (itoa i)
		       "]"
	       )
	       ADOConnect
	       1
	       3
	       nil
	     ) ;_  vlax-invoke-method
	     (setq
	       c (cons
		   (car
		     (apply
		       (function mapcar)
		       (cons
			 'list
			 (mapcar
			   (function
			     (lambda (a)
			       (mapcar
				 (function
				   (lambda (b1)
				     (vlax-variant-value b1)
				   ) ;_  lambda
				 ) ;_  function
				 a
			       ) ;_  mapcar
			     ) ;_  lambda
			   ) ;_  function
			   (vlax-safearray->list
			     (vlax-variant-value
			       (vlax-invoke-method
				 ADORecordset
				 "GetRows"
				 65535
			       ) ;_  vlax-invoke-method
			     ) ;_  vlax-variant-value
			   ) ;_  vlax-safearray->list
			 ) ;_  mapcar
		       ) ;_  cons
		     ) ;_  apply
		   ) ;_  car
		   c
		 ) ;_  cons
	       i (1- i)
	     ) ;_  setq
	     (vlax-invoke-method ADORecordset "Close")
	   ) ;_  while
	   (if (equal c '((nil) (nil)))
	     (list l)
	     (cons l c)
	   ) ;_  if
	 ) ;_  lambda
       ) ;_  function
       (rec-rem-dupl
	 (caddr
	   (mapcar
	     (function
	       (lambda (a)
		 (mapcar
		   (function vlax-variant-value)
		   a
		 ) ;_  mapcar
	       ) ;_  lambda
	     ) ;_  function
	     (vlax-safearray->list
	       (vlax-variant-value
		 (vlax-invoke-method
		   (vlax-invoke-method
		     ADOConnect
		     "OpenSchema"
		     4
		   ) ;_  vlax-invoke-method
		   "GetRows"
		   65535
		 ) ;_  vlax-invoke-method
	       ) ;_  vlax-variant-value
	     ) ;_  vlax-safearray->list
	   ) ;_  apply
	 ) ;_  caddr
       ) ;_  rec-rem-dupl
     ) ;_  mapcar
      ) ;_  setq
      (vlax-invoke-method ADOConnect "Close")
      (vlax-release-object ADORecordset)
      (vlax-release-object ADOConnect)
      (setq ADORecordset nil
     ADOConnect	  nil
      ) ;_  setq
      lst
    ) ;_  progn
    (progn
      (vl-catch-all-apply
 'vlax-invoke-method
 (list ADOConnect "Close")
      ) ;_  vl-catch-all-apply
      (vlax-release-object ADORecordset)
      (vlax-release-object ADOConnect)
      (setq ADORecordset nil
     ADOConnect	  nil
      ) ;_  setq
      nil
    ) ;_  progn
 ) ;_  if
) ;_  defun
;;;-----------------------------------------------------

Cái này hoạt động tốt, ssg đã thử nghiệm nhiều lần. Tức ở chỗ là chưa tìm được "tiếng nói chung" giữa GET_xl và ADOLISP_Library.lsp!

 

2. Với ADO, khả năng của Lisp sẽ được mở rộng rất nhiều, giao tiếp được với nhiều phần mềm, môi trường khác nhau, cũng như sử dụng được các tài nguyên của hệ thống (như các file *.dll, *.ocx...). Các bạn tìm hiểu thêm về ADO, có phát hiện gì hay hay thì post lên để anh em cùng học hỏi.

 

Có bài này về ADO, down từ diễn GiaiPhapExcel của anh PhanTuHuong (xin chân thành cám ơn). Nội dung hợp với "dân VBA" hơn, nhưng có lẽ "dân Lisp" cũng rút tỉa được một số điều bổ ích. Gởi anh em tham khảo:

 

http://www.cadviet.com/upfiles/ADO_Toan_Tap.zip

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Cái này hay đấy, elle đang cần có cái VD về "Call external funtion" từ 1 file OCX hoặc DLL mà...để ngâm xem có dùng được gì không !

Chia sẻ bài đăng này


Liên kết tới bài đăng
Chia sẻ trên các trang web khác

Tạo một tài khoản hoặc đăng nhập để nhận xét

Bạn cần phải là một thành viên để lại một bình luận

Tạo tài khoản

Đăng ký một tài khoản mới trong cộng đồng của chúng tôi. Điều đó dễ mà.

Đăng ký tài khoản mới

Đăng nhập

Bạn có sẵn sàng để tạo một tài khoản ? Đăng nhập tại đây.

Đăng nhập ngay

Đăng nhập để thực hiện theo  

×