Đến nội dung


Hình ảnh
* - - - - 1 Bình chọn

[Thảo luận] Code lisp như thế nào để hạn chế lỗi cho người dùng?


  • Please log in to reply
44 replies to this topic

#1 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 23 May 2013 - 04:59 PM

Chúng ta đang làm việc trên Cad, và chúng ta thấy Cad hầu như ít xãy ra lỗi. Vì sao thì chắc ai cũng biết.

Chúng ta cũng thường sử dụng Lisp trên các forum, và chúng ta thấy ít Lisp viết ra mà không dính lỗi này lỗi nọ. Vì sao vậy?

Vì đa số Lisp được viết chỉ để thỏa mãn nhu cầu trước mắt của người dùng, còn việc bẫy lỗi chưa được quan tâm thỏa đáng.

Với hy vọng code Lisp của mọi người ngày càng được chỉnh chu, phục vụ cộng đồng tốt hơn; xin mạn phép mở topic này để cùng thảo luận.

Các hình thức thảo luận có thể như thế này:

- Hỏi đáp về một hàm/một đoạn lisp ngắn nào đó cần phải sửa hoặc thay đổi như thế nào để tránh lỗi.

- Các lý thuyết về nguyên lý bẫy lỗi.

- Đưa lên một hàm/đoạn lisp mẫu để mọi người tìm xem nó có thể mắc lỗi gì (kiểu câu đố).

- V.v và v.v…

- Nhưng xin đừng đưa lên các lisp dài lê thê để nhờ tìm lỗi.

Từ các ví dụ, các câu hỏi… mọi người sẽ cùng thảo luận để tìm ra phương án khả dĩ tối ưu.

Chân thành cám ơn các bạn đã hỗ trợ topic này: Ket_xu, Gia_bach, Tue_NV, Phamthanhbinh, Duy782006, NguyenNgocSon, Polyme, Tien05, Lyky...

Tôi xin được làm thư ký để tổng hợp và update liên tục các lỗi mà mọi người phát hiện, tại các dòng màu xanh này:

1). Set biến cục bộ: (bài #2 + bài #7)

Giải thích:

- Biến cục bộ của 1 hàm là các biến chỉ có tác dụng trong nội bộ hàm đó, không có tác dụng đối với các hàm khác. Nó được đặt sau dấu / trong cặp dấu () định nghĩa hàm. VD: với (defun C:AB ( / x y)...) thì x và y là các biến cục bộ.

- Đặt biến cục bộ có các lợi ích sau:

1). Giải phóng bộ nhớ cho Cad. Nghĩa là sau khi dùng lệnh AB xong Cad không còn lưu hay nhớ gì đến x và y nữa.

2). Không gây lỗi cho các lisp khác được sử dụng sau lệnh AB trong cùng phiên làm việc của Cad.

3). Ngoài biến được đặt làm biến cục bộ thì hàm cũng được đặt làm biến cục bộ. Ví dụ dưới đây cho thấy: nếu đặt hàm dxf và mid làm biến cục bộ thì sau khi dùng lệnh AB xong, các hàm dxf và mid sẽ không còn tác dụng. Nó chỉ có tác dụng trong nội bộ lệnh AB.

(defun C:AB ( / x y z… dxf mid)

(defun dxf (dxfCode En) (cdr (assoc dxfCode (entget en))))

(defun mid (ent / p1 p2)…)...)

2). Dùng tên lệnh nguyên thủy: (bài #3)

Giải thích:

Khi dùng hàm command hoặc vl-cmdf chúng ta phải có lệnh Cad đi kèm. Để tránh trường hợp người dùng đã định nghĩa một lệnh mới có tên trùng với tên lệnh Cad khiến cho việc gọi hàm bị sai mục đích, thì nên dùng lệnh Cad nguyên thủy. Lệnh Cad nguyên thủy không bị ảnh hưởng bởi tên do user đặt nên nó không gây lỗi cho lisp.

Ví dụ dưới đây cho thấy nhiều cách gọi lệnh LINE trong hàm command, được Ketxu tóm tắt như sau:

 Line : Thực hiện lệnh Line mà CAD đang lưu trong bộ nhớ, lệnh này có thể là nguyên thủy hoặc đã bị định nghĩa lại.

-Line : Thực hiện phiên bản command prompt (không dialog) của lệnh (nếu có).

.Line : Thực hiện lệnh Line nguyên thủy của CAD, bất chấp đã bị định nghĩa lại hay chưa.

_Line : Thực hiện lệnh Line của CAD + các bước thông báo, không kể tới sự khác biệt ngôn ngữ trong phiên bản CAD (English Standard)

 => Với việc thực hiện các lệnh command mà có yêu cầu truyền thêm các bước quyết định (command Lệnh "Y" "N"....) => nên dùng _.

3). Set biến hệ thống "osmode" hoặc dùng "non" ngay trong dòng lệnh. Hạn chế dùng hàm COMMAND: (bài #7)

Giải thích:

- Khi dùng các hàm command hoặc vl-cmdf có liên quan đến point (VD: copy, mirror, move, offset, scale...), để tránh hiện tượng bắt điểm nhầm nếu đã đặt osnap, cần phải set biến hệ thống "osmode" về 0 bằng hàm (setvar "osmode" 0). Set "osmode" về 0 tức là tắt toàn bộ chế độ osnap. Tuy nhiên, việc tắt này chỉ nên đặt tạm thời trong khi chạy lisp, sau đó cần set "osmode" về trạng thái ban đầu bằng hàm (setvar "osmode" osm_old), với osm_old là giá trị "osmode" đã đặt trước khi dùng lisp, được lấy bằng hàm (setq osm_old (getvar "osmode")).

- Thay vì set "osmode" về 0, có thể dùng "non" đặt trước point để vô hiệu hóa chế độ osnap, VD: (command "copy" ss "" "non" p1 "non" p2).

- Thay hàm command bằng các hàm có chức năng tương đương, ví dụ entmake(x), vla-put...v.v... Vì khi dùng các hàm này chúng không bị ảnh hưởng bởi chế độ osnap.

4). Đặt điều kiện để thực hiện các hàm tiếp theo: (bài #2)

Giải thích:

Lisp thực hiện chuỗi hàm theo thứ tự từ trong ra ngoài và từ trên xuống dưới, theo kiểu "bước 1" >> "bước 2" >> "bước 3" ... >>... "bước n".

Để thực hiện được bước thứ i nào đó thì bắt buộc các bước thứ (i-1), (i-2)... phải được thực hiện thành công. Rất có thể bước i thực hiện không thành công khiến cho bước (i+1) sẽ bị lỗi. Bởi vây, để tránh lỗi cần đặt điều kiện cho từng bước, kiểu như thế này:

(nếu "bước 1" thành công thì chuyển qua "bước 2")

(nếu "bước 2" thành công thì chuyển qua "bước 3")

v.v...

Các hàm thường được dùng để đặt điều kiện: IF, WHILE...

5). Dùng hàm INITGET: (bài #34)

Giải thích:

Acad có 1 hàm rất hay để bẫy lỗi, đó là hàm INITGET. Hàm này có chức năng như 1 password, mà chỉ khi user nhập số liệu đúng yêu cầu nó  mới chấp nhận, còn nhập sai thì nó yêu cầu nhập lại chừng nào được mới thôi. Help của Cad nói khá đầy đủ về hàm này. Dưới đây chỉ đưa ra một số các ví dụ để tham khảo, từ đó user tự rút ra và lựa chọn cách đặt initget tốt nhất cho từng trường hợp.

(initget (+ 1 2 4 128)) (setq num (getint "\nNhap so nguyen: "))

(initget (+ 1 2 4 128)) (setq rea (getreal "\nNhap so thuc: "))

(initget (+ 1 2 4 32 128 256 1024)) (setq dis (getdist "\nNhap khoang cach: "))

(initget (+ 1 2 32 128 256 1024)) (setq ang (getangle "\nNhap goc: "))

(initget (+ 1 2 32 128 256 1024)) (setq ori (getorient "\nNhap goc: "))

(initget (+ 1 8 32 128 256 512 1024)) (setq ptd (getpoint "\nNhap diem: "))

(initget (+ 1 8 32 128 256 512 1024)) (setq ptt (getcorner "\nNhap diem: "))

(initget 1 128) (setq wrd (getkword "\nNhap ky tu: "))

(getstring) : Không dùng.

Ý nghĩa:

1 : Không chấp nhận chỉ nhấn enter.

2 : Không chấp nhận số 0.

4 : Không chấp nhận số âm.

8 : Chấp nhận điểm nhập vào nằm ngoài giới hạn bản vẽ.

16 : Không dùng (?).

32 : Dùng nét đứt để thể hiện "sợi dây thun".

64 : Dùng cho hàm getdist. Hàm getdist sẽ loại bỏ tọa độ Z của 2 điểm cần tính khoảng cách.

128 : Cho phép nhập chuỗi ký tự không có trong danh sách các từ khoá.

256 : Khoảng cách trực tiếp (?).

512 : Mặt ucs (?).

1024: Không chấp nhận tọa độ Z (?).  

6). Thiếu hàm vl-load-com:

Giải thích:

Khác với các hàm Lisp, các hàm Visual Lisp thường không được tự động load khi khởi động Cad. Do đó, để sử dụng được lisp khi trong file lisp có dùng các hàm Visual Lisp như Vla-, VlaxVlr- cần phải bổ sung hàm (vl-load-com) để nó load tự động các hàm Visual Lisp.

Vị trí đặt hàm (vl-load-com) thường là đầu/cuối file Lisp hoặc đầu hàm defun, hoặc chép nó vào trong file acaddoc.lsp...

7). Do ảnh hưởng của lisp khác: (bài #35)

Đôi khi lisp của chúng ta kiểm tra kỹ không thấy lỗi, chạy hoài vẫn không thấy lỗi, nhưng một buổi đẹp trời nào đó tự dưng nó bị lỗi. Một trong nhiều lý do khi đó là cần tìm hiểu xem: liệu có "thằng hàm xóm" nào phá hoại ta không?

Sự ảnh hưởng của lisp khác - thằng hàng xóm - và gây lỗi là điều chúng ta thường ít để ý khi code lisp. Điều này cần phải được quan tâm khi trong lisp có chứa các biến toàn cục.

Và, còn tệ hại hơn lỗi, đó là cũng do thằng hàng xóm, nhưng lisp vẫn chạy ngon ơ, còn kết quả thì... sai bét nhè!

8). Hệ tọa độ không phải là WCS: (bài #38 + #44)

Thông thường, khi viết lisp chúng ta hay trích xuất hoặc gán mã DXF của 1 điểm, đó thường là DXF 10 và DXF 11. Nhưng chúng ta thường dễ bị quên rằng: mã DXF của điểm được định nghĩa trong hệ WCS chứ không phải UCS, vì vậy, chúng ta thường quên chuyển từ UCS về WCS bằng hàm (trans pt 1 0). Việc quên chuyển tọa độ khiến cho kết quả của lisp bị sai hoặc lỗi, và thường xãy ra khi có sử dụng đến hàm (assoc 10 elist) hoặc (assoc 11 elist).

9). Giá trị DIMZIN khác 0:

Khi sử dụng các hàm chuyển đổi từ Real sang String hoặc từ Angtos sang String thường cần phải khai báo độ chính xác Precision. Tuy nhiên, nhiều khi kết quả trả về không như mong muốn. Đó là do ảnh hưởng bởi biến hệ thống DIMZIN. Để hạn chế lỗi trong trường hợp dùng các hàm chuyển đổi trên, cần phải set giá trị DIMZIN về 0 bằng hàm (setvar "dimzin" 0). Tất nhiên, sau khi dùng xong cần phải reset biến DIMZIN trở lại giá trị ban đầu.

 

...

 

THAM KHẢO THÊM:

a). Các lỗi cơ bản:

Tham khảo topic này: http://www.cadviet.com/forum/topic/44879-cac-loi-thuong-gap-trong-lap-trinh-lisp/

b'). Các lỗi "oái oăm":

Tham khảo topic này: http://www.cadviet.com/forum/topic/28788-cac-loi-oai-oam-trong-lisp/

c). Các thông báo lỗi và nguyên nhân có thể:

Dưới đây là danh sách các lỗi thường nhận được khi chạy 1 chương trình lisp, và nguyên nhân có thể. Danh sách tham khảo này có thể chưa đầy đủ.

malformed list on input

Thiếu dấu ngoặc ) bên Phải

extra right paren on input

Thừa dấu ngoặc ) bên Phải

malformed string on input

Thiếu dấu phân cách chuỗi “ hoặc ”

too many arguments

Thừa tham số trong hàm

too few arguments

Thiếu tham số trong hàm

Function cancelled

Người dùng đã ấn phím Esc trong khi đang chạy 1 hàm LISP

quit / exit abort

Hoặc là (exit) hoặc là (quit) hàm

Application ERROR: Console break

Người dùng đã ấn phím Esc trong khi đang thực hiện hàm grread

bad argument type: numberp: <value>

Hàm yêu cầu 1 đối số là Numerical nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: fixnump: <value>

Hàm yêu cầu 1 đối số là Integer nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: stringp <value>

Hàm yêu cầu 1 đối số là String nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: lselsetp <value>

Hàm yêu cầu 1 đối số là Selection Set nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: lentityp <value>

Hàm yêu cầu 1 đối số là Entity nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: listp <value>

Hàm yêu cầu 1 đối số là List nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: consp <value>

Hàm yêu cầu 1 đối số là List nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: FILE <value>

Hàm yêu cầu 1 đối số là File Descriptor nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: VLA-OBJECT <value>

Hàm yêu cầu 1 đối số là VLA-Object nhưng đã cung cấp một kiểu dữ liệu khác

bad argument type: (or stringp symbolp): <value>

Hàm y/c 1 đối số là String or Symbol (như as getvar or setvar) nhưng đã cung cấp kiểu dữ liệu khác

Unknown command "example".  Press F1 for help

Lệnh command không được định nghĩa. Có thể chưa Load Lisp, có thể lệnh command không có sẵn, hoặc quá nhiều dấu (“”) trong biểu thức lệnh command

no function definition: VLAX-GET-ACAD-OBJECT
no function definition: VLAX-ENAME->VLA-OBJECT

Cần thêm hàm (vl-load-com) vào để chạy các lệnh mở rộng của Visual LISP

no function definition: <name>

Hàm không được định nghĩa, hoặc do (vl-load-com) bị lỗi mã

bad function: <name>

Một ký hiệu hoặc biến có giá trị không đúng y/c của hàm, có thể do 1 list ký tự không được định giá

Có thể nó là 1 biến đã được định giá. VD: (setq a 3) ; (a) => ; error: bad function: 3

ActiveX Server returned the error: unknown name: <name>

Chương trình truy cập VLA-Object Property or Method mà không có đối tượng đó

ActiveX Server returned an error: Invalid index

Chương trình sử dụng hàm Vlax-safearray->list để chuyển 1 Safearray rỗng đến 1List.

Automation Error. Key not found

Truy cập vào một Item của VLA Collection Object nhưng không có

vlax-safearray-fill failed.  Invalid initialization list.

Sử dụng hàm vlax-safearray-fill để đưa đến một Safearray với một số Items không chính xác

divide by zero

Chia (như rem hoặc /) bởi một số 0

bad ssget mode string

Kiểu đối số String trong hàm Ssget (như "_X") là không chính xác

bad point argument

Danh sách điểm trong hàm Ssget không chính xác hoặc không có gì cả

bad SSGET list value

Một hoặc nhiều Items trong list bộ lọc cung cấp cho hàm Ssget là không hợp lệ

-------------------------------------------------------------------------------------------------------------

Xin được nổ phát pháo đầu tiên: mời mọi người phân tích xem lisp dưới đây có thể bị những lỗi gì khi sử dụng? Lỗi ở đây bao gồm lỗi nội bộ lisp và lỗi do tàn dư lisp để lại. Rất có thể từ ví dụ đơn giản này mà nhiều nguyên lý bẫy lỗi dần được sáng tỏ!

Lisp vẽ hình chữ nhật qua 2 điểm do người dùng nhập vào.

 

(defun C:HCN()
 (setq p1 (getpoint "\nPick diem 1: "))
 (setq p3 (getcorner p1 "\nPick diem 2: "))
 (command "rectang" p1 p3))

  • 4

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#2 NguyenNgocSon

NguyenNgocSon

    biết dimbaseline

  • Members
  • PipPipPipPipPip
  • 368 Bài viết
Điểm đánh giá: 39 (tàm tạm)

Đã gửi 23 May 2013 - 05:14 PM

1.Theo tôi nếu chọn không chọn được p1, p3 đều lỗi => chỉnh sửa: bẫy lỗi khi nào pick điểm được thì thôi ?

2.Lỗi biến cục bộ nếu p1 được khai báo ở 1 lisp khác ?


  • 1

#3 Polyline

Polyline

    biết lệnh mirror

  • Members
  • PipPipPip
  • 159 Bài viết
Điểm đánh giá: 18 (tàm tạm)

Đã gửi 23 May 2013 - 05:21 PM

Đây đúng là một chủ đề thú vị và thiết thực. Với ví dụ bác HA đưa ra:

- Nếu nhập p1 không thành công -> gây lỗi cho hàm (getcorner và toàn bộ chương trình sẽ chấm dứt ở đây với thông báo lỗi.

- Nếu nhập p1 và p3 thành công, mà người dùng (hoặc ứng dụng nào đó) đã định nghĩa lại lệnh rectang với tham số truyền vào khác với lệnh rectang của AutoCAD, thì việc gọi hàm (command "rectang" p1 p3) có thể không thực hiện được. Để sử dụng lệnh gốc của AutoCAD, phải thêm dấu chấm vào trước câu lệnh, trở thành (command ".rectang" p1 p3).


  • 1

#4 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 23 May 2013 - 06:00 PM

Cám ơn 2 bạn NNS và PLM! Vì là lô hàng đầu tiên nên sẽ có khuyến mãi like. Mời các bạn khác tiếp tục, vì vẫn còn khá nhiều lỗi đang... chờ!

Và tôi sẽ tổng kết sau khi tìm ra hết lỗi.


  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#5 phongtran86

phongtran86

    biết lệnh offset

  • Members
  • PipPipPip
  • 177 Bài viết
Điểm đánh giá: 22 (tàm tạm)

Đã gửi 23 May 2013 - 08:54 PM

Topic hay. Cũng đang mày mò lisp tí. Có cơ hội học hỏi rồi :)


  • 0

#6 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 23 May 2013 - 10:17 PM

Phân tích sơ bộ:

1).Theo tôi nếu không chọn được p1, p3 đều lỗi => chỉnh sửa: bẫy lỗi khi nào pick điểm được thì thôi ?

Đề nghị bạn đưa ra code phương pháp bẫy lỗi! Bởi khái niệm "bẫy lỗi" này chưa rõ ràng vì có nhiều cách bẫy lỗi này.

 

2).Lỗi biến cục bộ nếu p1 được khai báo ở 1 lisp khác ?

p1 khai báo ở đâu thì liên quan gì tới lisp này ạ! Mong bạn giải thích?

3). Nếu nhập p1 không thành công -> gây lỗi cho hàm...

Vậy phải làm sao nếu nhập p1 không thành công, và khái niệm "nhập không thành công" là thế nào ạ?

4). Viết (command "rectang" p1 p3) là chưa sử dụng đúng lệnh gốc của Cad.... Để sử dụng lệnh gốc của AutoCAD, phải thêm dấu chấm vào trước câu lệnh, trở thành (command ".rectang" p1 p3).

OK. Nếu ai có ý kiến tốt hơn thì topic xin ghi nhận.

Và. Vẫn còn nhiều lỗi nữa, thậm chí cả những lỗi mà chủ topic chưa chắc đã biết.

Hy vọng mọi người tiếp tục đóng góp ý kiến.


  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#7 duy782006

duy782006

    PHẠM QUỐC DUY

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 2155 Bài viết
Điểm đánh giá: 1360 (rất tốt)

Đã gửi 24 May 2013 - 08:06 AM

Vì chưa nâng cao nên duy còn khả năng 88.

1. Dòng  (defun C:HCN() không khai khử biến nên ném ra môi trường p1 và p3

khắc phục:  (defun C:HCN(/ p1 p3)

2. Dòng (command "rectang" p1 p3))

a.Không kiểm soát phần bắt điểm nên kết quả có thể dính chùm lung tung xà beng.

khắc phục (command ".rectang" "_non" p1 "_non" p3))

b.Kết thúc defun chỉ bằng dấu ) dể ném ra dòng lệnh cái gì đấy linh tinh hông đẹp.

Khắc phục (command ".rectang" "_non" p1 "_non" p3) (princ))

*Tạm thế bác nào cao chém thêm mình ko có khả năng bẫy lỗi esc nên ko dám bàn đến.


  • 2

Cứ ngỡ trần gian là cõi thật.Cho nên tất bật đến bây giờ.
Tạo hộp thoại bằng lisp My blog QUY ĐỊNH ĐẶT TÊN TOPIC TRONG CHUYÊN MỤC LISPD http://ktsduy.wordpress.com/
Để cám ơn chỉ cần nhấn rep_up.png
(Là nhấn vào nút đó phía bài viết của người ta í chứ đừng có nhè cái hình này mà nhấn miết đi nha :-D


#8 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 24 May 2013 - 09:26 AM

Thank bác Duy782006. Qua 3 góp ý ở trên, sơ bộ sửa như vầy. Và hình như nó vẫn còn cần bẫy lỗi? Mời tiếp tục!

 

(defun C:HCN( / p1 p3)
 (if
  (and
   (setq p1 (getpoint "\nPick diem 1: "))
   (setq p3 (getcorner p1 "\nPick diem 2: ")))
  (command ".rectang" "non" p1 "non" p3))
 (princ))

  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#9 Tue_NV

Tue_NV

    KS Võ Quang Tuệ

  • Moderator
  • PipPipPipPipPipPipPip
  • 4296 Bài viết
Điểm đánh giá: 3804 (đỉnh cao)

Đã gửi 24 May 2013 - 10:47 AM

Thank bác Duy782006. Qua 3 góp ý ở trên, sơ bộ sửa như vầy. Và hình như nó vẫn còn cần bẫy lỗi? Mời tiếp tục!

 

(defun C:HCN( / p1 p3)
 (if
  (and
   (setq p1 (getpoint "\nPick diem 1: "))
   (setq p3 (getcorner p1 "\nPick diem 2: ")))
  (command ".rectang" "non" p1 "non" p3))
 (princ))

 

Không cần tới If đâu bác :

 

 
(defun C:HCN( / p1 p3)
  (and
   (setq p1 (getpoint "\nPick diem 1: "))
   (setq p3 (getcorner p1 "\nPick diem 2: "))
  (command ".rectang" "non" p1 "non" p3))
(princ))

  • 1

#10 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 24 May 2013 - 11:17 AM

Vâng, đúng thế! Trong bài toán đặc biệt này thì có thể không cần IF. Đưa IF vào lisp ở trên là cốt để tổng quát hóa điều kiện mà thôi.


  • 0

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#11 Polyline

Polyline

    biết lệnh mirror

  • Members
  • PipPipPip
  • 159 Bài viết
Điểm đánh giá: 18 (tàm tạm)

Đã gửi 24 May 2013 - 01:43 PM

Vẫn còn lỗi, đó là người dùng nhấn ESC ở dòng yêu cầu nhập điểm!


  • 0

#12 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 24 May 2013 - 02:37 PM

Tạm gác ví dụ vẽ HCN ở trên (trong khi chờ mọi người bổ sung), hãy tìm cách bẫy lỗi lisp vẽ đường tròn dưới đây. Điều kiện: hễ mỗi lần gọi lệnh bắt buộc phải có 1 đường tròn được vẽ.

P/S(7h15'_25/5/2013): bổ sung điều kiện: trừ trường hợp nhấn Esc. Sorry.

 

(defun C:VHT( / p r)
 (setq p (getpoint "\nSpecify center point for circle: "))
 (setq r (getreal "\nSpecify radius of circle: "))
 (command ".circle" "non" p r)
 (princ))

  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#13 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 May 2013 - 03:45 PM

Tạm gác ví dụ vẽ HCN ở trên (trong khi chờ mọi người bổ sung), hãy tìm cách bẫy lỗi lisp vẽ đường tròn dưới đây. Điều kiện: hễ mỗi lần gọi lệnh bắt buộc phải có 1 đường tròn được vẽ.

 

(defun C:VHT( / p r)
 (setq p (getpoint "\nSpecify center point for circle: "))
 (setq r (getreal "\nSpecify radius of circle: "))
 (command ".circle" "non" p r)
 (princ))

Hề hề hề,

Hoan nghênh bác DoanVanHa đưa ra chủ đề hết sức thiết thực này.

Thực tế bản thân tui, do cái sự mót nên kiền thức còn cọc cạch chắp vá nên hầu như không bao giờ nghĩ tới vấn đề bẫy lỗi này mà chi nhăm nhăm làm sao cho nó chạy được. Trong quá trình viết lisp đã nhiều lần dính đòn do việc bẫy lỗi này không có.. Tuy nhiên do kiến thức mót được còn lỗ mỗ nên chưa thể nào tự mình khắc phục được mà thường là phải nhờ các bác trên diễn đàn chỉ giáo.

Với suy nghĩ cá nhân của tui thì cái lisp vẽ vòng tròn có thể dính lỗi khi diểm tâm p và bán kinh r không được xác định. Tỷ như người dùng không pick điểm p mà nhấn enter hay esc luôn, hoặc không nhập giá trị bán kính mà nhấn enter luôn.

Vậy nên tui liều mạng sửa bẫy lỗi như vầy, trúng hay trật nhờ các bác đèn giời soi tỏ:

 

(defun C:VHT( / p r)
 (while (not p) (setq p (getpoint "\nSpecify center point for circle: ")))
 (while (or (not r) (equal r 0.0 0.00001)) (setq r (getreal "\nSpecify radius of circle: ")))
 (command ".circle" "non" p r)
 (princ))

  • 1
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#14 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 24 May 2013 - 03:57 PM

Cám ơn bác PTB đã tham gia. Cám ơn bác đã hoan nghênh bằng... "tinh thần".

Đó là 1 cách, tuy chưa hay và chưa giải quyết triệt để, chẳng hạn ai đó vô tình nhập R=-5.

Mời bác và mọi người tiếp tục!


  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#15 ketxu

ketxu

    Copier - Paster - Editor

  • Moderator
  • PipPipPipPipPipPipPip
  • 5682 Bài viết
Điểm đánh giá: 2605 (tuyệt vời)

Đã gửi 24 May 2013 - 04:25 PM

Ket k có máy, ngoáy 1 tí chỗ bên trên bác Hạ đề cập, các thứ khác chưa tính ^^

(while (not p)(setq p ...) = (while (not (setq p ...)))

(while not r = getreal     = while not r = getdist p

command     = vl-cmdf


  • 1

Thành viên nhóm CadMagic.
Mời bạn ghé thăm facebook nhóm - Page viết lisp theo yêu cầu  :
CAD MAGIC


#16 Song Nhi

Song Nhi

    biết vẽ rectang

  • Members
  • PipPip
  • 83 Bài viết
Điểm đánh giá: 52 (tàm tạm)

Đã gửi 24 May 2013 - 08:33 PM

Topic thật thú vị, bổ ích và thiết thực! Rate Topic: ★★★★★

Mong Bác Doan Van Ha sẽ dành thời gian làm "chủ xị" để tổng hợp ý kiến các Bác và giải thích lại với những anh em mới bắt đầu như chúng tôi!

 

Doan Van Ha: Bác đừng giận, dùng từ "chủ xị" cho bình dân chứ không có ý gì khác!

@ Ketxu: Bác Tùng làm ơn giải thích dzùm vì sao lại thay command bằng vl-cmdf? Có những ưu điểm gì vậy?


  • 2

#17 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 May 2013 - 08:57 PM

Cám ơn bác PTB đã tham gia. Cám ơn bác đã hoan nghênh bằng... "tinh thần".

Đó là 1 cách, tuy chưa hay và chưa giải quyết triệt để, chẳng hạn ai đó vô tình nhập R=-5.

Mời bác và mọi người tiếp tục!

Hề hề hề,

Quả thật có tí đèn nên sáng hẳn ra. Đúng là chưa triệt để thiệt. Nhưng kể cả thêm thằng (< r 0.0) vào trong hàm or thì mình cũng thấy nó vẫn chưa triệt .... sản bác ạ. Theo mình hiểu thì còn phải bẫy cái thằng cu ESC nữa, mà điều này tuy có đôi lần thấy các bác đã làm, song đầu óc linh tinh nên chả nhớ và cũng không thủng lắm nên đành "quay mặt làm ngơ" để các bác chỉ dạy tiếp.

Gì chứ cái "tinh thần" thì mình vẫn còn sung lắm nên cái vụ hoan nghênh này sẽ còn dài dài bác ạ. Dân quần cộc nên đôi khi cũng hay quên cái món "vật chất" bác nhể. thôi thì mong bác thể tất cho......


  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#18 phamthanhbinh

phamthanhbinh

    biết lệnh adcenter

  • Moderator
  • PipPipPipPipPipPipPip
  • 6009 Bài viết
Điểm đánh giá: 3113 (tuyệt vời)

Đã gửi 24 May 2013 - 09:08 PM

Topic thật thú vị, bổ ích và thiết thực! Rate Topic: ★★★★★

Mong Bác Doan Van Ha sẽ dành thời gian làm "chủ xị" để tổng hợp ý kiến các Bác và giải thích lại với những anh em mới bắt đầu như chúng tôi!

 

Doan Van Ha: Bác đừng giận, dùng từ "chủ xị" cho bình dân chứ không có ý gì khác!

@ Ketxu: Bác Tùng làm ơn giải thích dzùm vì sao lại thay command bằng vl-cmdf? Có những ưu điểm gì vậy?

Hề hề hề,

Quá đã , quá đã. Có người nêu thắc mắc giùm mình. 

Thiệt tình thì mình hiểu rằng vl-cmdf cũng chỉ là một cách gọi hàm command theo kiểu ..... vl ,.... thôi. Song cứ nghe lỏm đâu đó thì dùng kiểu nạy hay hơn là dùng hàm command kiểu (command ....). hay hơn ví dường như nó hoạt động nhanh hơn, chuẩn xác hơn và tốn ít bộ nhớ hơn thì phải. Nghe vậy, biết vậy chứ cái sự hiểu thì nó còn ngây ngô lắm. Vậy nên cứ bạ đâu dùng đó, chứ cũng chả dám suy nghĩ chi nhiều.

Nay đã có bác Song Nhi lên tiếng hộ, bác Ketxu bớt chút thời gian giải thích ky kỹ một chút để mình ngộ thêm chút chút hè.....


  • 0
Chúc các quý Anh trên diễn đàn luôn khỏe, đẻ thêm được nhiều thứ để mót.

#19 Doan Van Ha

Doan Van Ha

    biết lệnh adcenter

  • CADViet Team
  • PipPipPipPipPipPipPip
  • 5451 Bài viết
Điểm đánh giá: 2625 (tuyệt vời)

Đã gửi 24 May 2013 - 10:07 PM

@Ketxu+SongNhi+Phamthanhbinh:

1). Về hàm vl-cmdf: ai cũng hỏi Ket >> đề nghị Ket trả lời thấu đáo.

2). “Chủ xị” thì không có gì để giận, thậm chí còn mừng, vì đi nhậu hay nhận được chức này, do… già. Tuy nhiên, trên 4R lắm anh tài thì chỉ xin làm thư ký chân dài thôi.

3). Về ECS: thống nhất sẽ bàn sau cùng nhé!

4). (< r 0) chẳng qua cũng là để dẫn dắt thôi, chứ chẳng hay ho lắm.

5). Thay (while (not p)(setq p ...) bởi (while (not (setq p ...))) >> tốt, nhưng giả dụ nó là getstring thì có thể sẽ phải tìm phương án khác.

6). Thay (getreal…) bằng (getdist p…) cũng chưa giải quyết được trường hợp user nhập số <= 0 vì getdist nó chấp nhận cả số <=0.

Mời mọi người tiếp tục bẫy lỗi!


  • 1

* Chỉ nên yêu cầu Lisp khi bạn làm việc đó mất cả ngày nhưng họ chỉ viết 1 giờ. Đừng nêu yêu cầu Lisp khi bạn chỉ làm 1 giờ nhưng bắt họ phải mất cả ngày.

* Nhờ viết lisp cũng như đi khám bệnh. Chỉ gởi căn cước và than sắp chết thì không bác sỹ nào cứu sống được.


#20 tien2005

tien2005

    biết lệnh properties

  • Members
  • PipPipPipPip
  • 257 Bài viết
Điểm đánh giá: 94 (tàm tạm)

Đã gửi 24 May 2013 - 10:36 PM

dùng (initget (+ 2 4)) để bắt buộc nhập số >0


  • 0


Trở lại AutoLisp