Lee Mac 发表于 2022-7-6 17:24:00

“如果”。。。。“和”。。。。。“或”。。。。

我目前正在使用LISP绘制管道弯头的平面图。
 
在绘图程序运行之前,我需要LISP分析用户输入的角度,以确定其是否等于90度或180度。
 
如果角度不等于其中任何一个,则程序需要按计划运行。
 
我试过用这样的东西。。。。
 
然而,我真的不明白“OR”、“AND”、“WHILE”和“NOT”函数是如何工作的。
 

alanjt 发表于 2022-7-6 17:31:55

或者:如果是这个或那个,那么做一些事情(必须是其中之一)
并且:如果这个和那个,那么做一些事情(必须两者都做)
WHILE:WHILE something(=(getvar“cmdecho”0)),然后执行操作
不:如果某事不是某事,那么做某事
(如果(不等于(getvar“clayer”)0)
);不
(setvar“clayer”0)
);如果

Lee Mac 发表于 2022-7-6 17:35:35

感谢Alanjt提供的信息,非常感谢;但是你能看到我发布的代码中关于“or”的使用有什么错误吗(除了明显的no“defun”等)?

alanjt 发表于 2022-7-6 17:39:49

 
试试这个:
你有一个反斜杠。

CAB 发表于 2022-7-6 17:46:01

李·麦克
有很多方法可以解决这个问题,但在找到解决方案之前,您需要
澄清流程。在您的示例中,您使用的是整数90和180。对我来说这意味着
它们是用户输入的值,因为从实体(如直线)获得的任何角度
将是一个实数&可能以弧度而不是度为单位。
那是哪一个?
 
请注意,对于接近所需值的值,通常也必须使用模糊因子。
由于存在舍入误差,ACAD尤其如此。
 
这是您的示例已更正&没有给出正确的结果,您使用了错误的斜杠字符
(if (or (/= elbang 90) (/= elbang 180))
   (progn
       "run elbow draw program"
   )
) ; end if
 
在您给出的简单示例中,我会这样做,假设只测试整数。
;;elbang is /= 90 AND /= 180
(if (and (/= elbang 90) (/= elbang 180))
   (progn
      (princ "run elbow draw program")
   )
) ; end if
 
;;OR returns true if either is true
;;OR returns nil if Both are false
;;so if Both are false, NOT returns True
(if (not (or (= elbang 90) (= elbang 180)))
   (progn
   (princ "run elbow draw program")
   )
) ; end if
 
;; Another way to test
;;if var is not a member of the list
(if (not (member elbang '(90 180)))
   (progn
   (princ "run elbow draw program")
   )
) ; end if
 
;; Another way to test
;;if var is not a member of the list
(if (not (vl-position elbang '(90 180)))
   (progn
   (princ "run elbow draw program")
   )
) ; end if
 
;; This one is a little tricky
;;returns True if both test are true, like this
;;(setq elbang 20)
;;(/= 90 elbang) -> true
;;(/= elbang 180) -> true
;;both true then the prg will execute
;;(setq elbang 90)
;;(/= 90 elbang) -> flase
;;(/= elbang 180) -> true
;;any false will return false then the prg will NOT execute
;;This is like an AND,
(if (/= 90 elbang 180) ; elbang must be in the middle
   (progn
   (princ "run elbow draw program")
   )
) ; end if

Lee Mac 发表于 2022-7-6 17:53:09

谢谢大家提供的信息,(CAB,你真的带着最后一篇帖子进城了-非常有信息,谢谢)。
 
现在我对函数的理解好多了。
 
我意识到我的错误与张贴Lisp程序,但谢谢你花时间指出它。
 
为了更好地阐明我的意图-
运行初始“用户输入程序”以获得用户值,包括
[列表]
[*]设备类型
[*]视图(平面/立面)
[*]插入点
[*]管道标称孔径(50/80/100/…等)
[*](用于弯头)-半径(长/短/5D)
[*](用于弯头)-角度
根据输入的设备类型,各种其他程序将运行并根据所选视图和尺寸构建所选设备。
 
为了解决使用“and/or”命令的问题,我对每个场景进行了限定,并使用“if”函数来分隔每个场景。
 

 
(if (and (/= elbang 90.0) (< elbang 180.0))
    (progn
       "draw elbow"
    ) ; end progn
) ; end if


(if (= elbang 90.0)
   (progn
      "draw 90.0 elbow"
   ) ; end progn
) ; end if


etc etc
这似乎很有效。
再次感谢你的帮助。

CAB 发表于 2022-7-6 17:54:21

很高兴我能解释一下这个问题。
当您有几个测试并且只有一个是真的时,或者如果在中进行测试,您希望其中一个是真的
一个特定的顺序,那么COND就是要使用的函数。请参见此示例。
(cond
((equal elbang 90.0 0.0001) ; this will catch rounding errors
(princ "draw 90.0 elbow") ; go do it
)
((< 90.0 elbang 180.0) ; it is between 90 and 180
(princ "draw elbow")
)
(t ; elbang is < 90 OR >= 180
;; Do what ever
)
)

Lee Mac 发表于 2022-7-6 18:03:07

我假设“cond”函数比“if”函数整洁——尽管我发现“if”函数仍然可以产生所需的结果。我不知道为此目的使用这样的函数有任何缺点。
 
还有一个问题我想问-它已经在我脑海里一段时间了。。。
 
“progn”前缀的确切含义是什么?
 
起初,我认为“progn”前缀专门用于“if”函数,以通知程序在“if”命令决定如何处理数据之前,将有多行编程。然而,在前一个线程中,我注意到您使用了带有“while”函数的“progn”前缀。。。

CAB 发表于 2022-7-6 18:06:25

嗯,COND是这项工作的正确工具。只是选择的问题。
 
PROGN是一组代码的包装器。
 

计算一个测试表达式,如果它不是零,则计算其他表达式;
重复此过程,直到测试表达式的计算结果为零
 
PROGN使整个组成为测试表达式。
 
在WHILE循环中使用的其他方法是使用COND或AND
 
如果将一组代码包装在中,则每行都将执行,直到出现零。在这一点上
并以零退出返回到退出循环的WHILE。
 
COND的使用方法相同。

CAB 发表于 2022-7-6 18:12:43

LISP Logic and More作者:Charles Alan Butler又名CAB
 
这是我对LISP逻辑函数及其用法的看法。
 
与我一起探索if and or cond while&progn函数。
 
if语句的工作方式如下
(if (this is true)
(then do this)
)
 
(if (this is true)
(then do this)
(else do this when false)
)
 
 
 
另一方面,(cond)stmt执行以下所有代码
然后退出条件stmt。它返回最后一个的值
子列表中的表达式。如果子列表中只有一个表达式(即,
如果缺少结果),则返回测试表达式的值。
 
(cond
((= 1 0)
   none of this will get executed
   because the conditions is false
) ; end cond 1

((= 1 1)
    do all of this because it is true
    and this
    and this
) ; end cond 2

((= 2 2)
    none of this will get
    executed even if it is true
    because the prior stmt was true
) ; end cond 3

(T
    This is often placed at the last position
    in a condition statement and will be executed
    if all the prior conditions are false
    if any one of the above conditions are true
   this will not be executed
) ; end cond 4
) ; end cond stmt
关于条件陈述的更多信息,请稍候。
 
 
OR将处理每一行,只要它们为false,当返回true时它将退出
(or (a. is true) ; stop here
    (b. does not get this far)
)
 
(or (a. is false) ; keep going
    (b. do this & if false keep going)
    (c. do this if b was false)
)
 
和将处理每一行,只要它们为true,当返回false时它将退出
(and (a. is true) ; keep going
   (b. do this & if true keep going)
   (c. do this if b was true)
)
 
请注意,AND和/或其自身仅返回true或nil,
而IF和COND将返回表达式的值。
(setq rtn
      (or (+ 3 7) ; returns 10 which is not nil so it passes the test for true
         (+ 2 4 6) ; return 12
      )
)
而rtn中的值为t
(setq rtn
      (if (+ 3 7) ; returns 10 which is not nil so it passes the test for true
         (+ 2 4 6) ; return 12
      )
)
rtn中的值为12
(setq rtn
      (if (> 3 7) ; 3 is not > 7 so this returns nil
         (+ 2 4 6) ; return 12
      )
)
rtn中的值为零,因为没有其他行需要考虑
(setq rtn
      (if (> 3 7) ; 3 is not > 7 so this returns nil
         (+ 2 4 6)
         (- 10 2)
      )
)
此处无支持,rtn值为8
 
cond语句与if类似
这是一个我喜欢的例子
(initget 0 "Yes No")
(setq ans
         (cond
                 ((getkword "\nGive your answer. <Yes>: "))
               ("Yes")
         )
)
如果用户点击回车键,则返回nil,cond返回“Yes”
如果用户输入文本,则返回文本
 
 
 
 
(progn)的一些示例
注意,progn返回最后计算的表达式的值。
(if (this is true)
(progn
       do all of this
       and this
       and this
   )
(don't do this)
); endif

(if (this is false)
(don't do this)
(progn
       do all of this
       and this
       and this
   )
)
 
您可以看到,progn是一种将代码分组在一起的方法。
当为true且
当为false时,将执行第二组代码,
如果有第二组代码。如果你忘记了(progn)只有第一个
如果为true,则将执行代码行,其余代码将被跳过。
还有其他方法可以将代码分组在一起,您将及时了解它们。
 
 
 
 
另一方面,(cond)stmt执行以下所有代码
然后退出条件stmt。记住,真理不是零。
 
(cond
((= 1 0)
   none of this will get executed
   because the conditions is false
) ; end cond 1

((= 1 1)
    do all of this because it is true
    and this
    and this
) ; end cond 2

((= 2 2)
    none of this will get
    executed even if it is true
    because the prior stmt was true
) ; end cond 3

(T
    This is often placed at the last position
    in a condition statement and will be executed
    if all the prior conditions are false
    if any one of the above conditions are true
   this will not be executed
) ; end cond 4
) ; end cond stmt
 
 
 
当您想要有条件地执行cond时,这里有一个cond语句的技巧。
我们经常看到这样的情况:
(if (something is true) ; reminder, 'true' here is really anything (not nil)
(cond
   ((= 1 1) ...)
   ((= 2 2) ...)
) ; end cond stmt
) ; endif
 
它可以这样写,如果某件事不是真的,那么第一个条件就是真的&
什么也没做,但cond语句满意地发现了真实条件。
处理跳过其余条件。
(cond
((not (something is true))) ; if something is not true stop here
((= 1 1) ...)
((= 2 2) ...)
) ; end cond stmt
 
 
 
WHILE用作条件循环,并将循环继续到下一个循环
表达式返回nil。在这里,我们测试cnt中的值,希望它变为0
这样我们就可以退出while循环。循环中的代码执行5次,
而cnt值为0到4。
(setq cnt 0)
(while (= cnt 5)
;;do some stuff
(setq cnt (1+ cnt))
)
 
也可以这样写,cnt值为0到4。
(setq cnt -1)
(while (= (setq cnt (1+ cnt)) 5)
;;do some stuff
)
 
有时,要测试的条件是在中的代码末尾设置的
循环。代码可能如下所示。
(setq continue_loop t)
(while continue_loop
;;do some stuff
(if (I want to leave the loop is true)
   (setq continue_loop nil) ; flag to exit the loop
)
)
 
也可以这样写:
(setq continue_loop t)
(while
(progn
;;do some stuff
(not (I want to leave the loop is true)) ; flag to exit the loop
) ; progn
)
 
你看,当(我想让循环为true)返回true时,not将返回true
返回nil,因为它是progn中的最后一个表达式,所以是
虽然看到了。然后退出循环。
 
 
这是一个真实的例子。
这是我输入数字如关键字的解决方案
模拟的关键词是“90 180 270-90”
29
 
 
现在就这些。
再见。
页: [1] 2
查看完整版本: “如果”。。。。“和”。。。。。“或”。。。。