티스토리 뷰

프로그래밍/LISP

LISP 3.

.가끔은 2021. 10. 13. 23:03
반응형

사용자에게 입력값 받기

숫자, 문자등을 명령창에서 변수로 가져와 코드를 작성할때 사용하게 됩니다.

가장 많이 사용하는 3가지 함수입니다.

(getint)  -> 정수
(getreal)  -> 실수
(getstring)  -> 문자

1. getint - 숫자중 정수만을 입력받고 싶을때 사용됩니다.

(정수를 간단히 설명하면 0이 포함된 소숫점이 없는 숫자라 생각하시면 됩니다)
(예 : 0, 1, 44, -24123, ,,, )

예로 알아 봅시다 

(setq test1 (getint)) 

이렇게 하면 test1 이라는 변수에 사용자가 입력한 값을 넣어 줍니다. 


(setq test1 (getint "값을 입력하시오 : ")) 

이렇게 하면 화면에 "값을 입력하시오 : " 라는 메세지가 화면에 표시 됩니다. 
화면에 메세지를 출력해 주면 사용자가 어떤값을 입력해야 하는지를 쉽게 알 수 있습니다. 

만약 1.241234 이런 소수를 넣으면 오류로 실행되지 않습니다.
정수형 변수에 다른형식에 데이터를 넣을수 없습니다.


2. getreal - 실수 형태의 데이터를 입력받을때 사용됩니다.

(getint)가 정수만을 입력 받지만 (getreal)은 모든 숫자를 입력 받습니다. 

아래 예제입니다. 

(setq test2 (getreal "숫자를 입력하시오 : ")) 

3. getstring - 문자의 입력 

문자를 입력 받습니다. 

(setq test3 (getstring "당신의 이름은? ")) 

캐드에서는 스페이스가 엔터기능입니다. 
여기서 스페이스를 엔터기능으로 사용하지 않고 공백으로 사용하려면 
(getstring <메세지> t) 하면 됩니다. 뒤에 t 만 달아주면 되죠.. 

  • 전체적인 예제입니다. 
    (defun c:test() 
    (setq t1 (getint "첫번째 정수는 : ")); 사용자로 하여금 정수입력받음 (t1) 
    (setq t2 (getreal "두번째 숫자는 : ")) ; 사용자로 하여금 실수입력받음 (t2) 
    (setq t3 (+ t1 t2)); 두 수의 합을 구함 (t3) 
    (prompt "\n계산된 결과값은 = "); 화면에 "계산된 결과값은 = "을 표시, \n은 줄바꿈 
    (princ t3) ; 화면에 덧셈결과값인 t3 출력 
    (princ); 기본적으로 꼭 써주는 연습. (응답값을 표시 하지 말라는 입력문) 
    ) ; end of defun​
     

캐드화면에서 위치값 받기

캐드화면에서 점(point)의 값을 받아오는 리습을 만들어 보겠습니다. 

(getpoint) 
(getcorner) 

1. (getpoint [기준점] [화면표시글]) 

한점의 좌표를 구해옵니다. [기준점]과 [화면표시글]은 생략가능. 

(setq test1 (getpoint "한점을 클릭하시오 : "))

이렇게 하면 test1 값은 (x y z)의 좌표를 가진 리스트(배열)입니다. 
리스트란 ( ) 안에 묶여서 한 그룹처럼 형성된 형태입니다. 

<예제1> 
 (defun c:test1() 
 (setq p1 (getpoint "첫번째 점을 찍으세요")) 
 (setq p2 (getpoint "두번째 점을 찍으세요")) 
 (princ)) 

<예제2> 
 (defun c:test2() 
 (setq p1 (getpoint "첫번째 점을 찍으세요")) 
 (setq p2 (getpoint p1 "두번째 점을 찍으세요")) 
 (princ)) 

<예제1>과 <예제2>의 다른점을 (getpoint p1...) 입니다. 
두가지 다 해보시면 알겠지만 <예제2>는 p1의 기준점을 가지고 있습니다.

2. (getcorner 기준점 [화면표시글]) 

(getpoint) 와 비슷하지만 사각형의 테두리선을 보여줍니다. 
기준점은 꼭 있어야 하고 화면표시글은 생략가능합니다. 
예제를 통해서 알아보겠습니다. 

(defun c:test3() 
(setq p1 (getpoint "첫번째 구석은?")) 
(setq p2 (getcorner p1 "두번째 구석은?")) 
(princ)) 
 

  • 응용

    다음은 점을 찍으면 그 자리에 반자름이 10인 원을 그립니다. 

    (defun c:test4() 
     (setq r 10); 반지름을 10 으로 r 이라는 변수로 정의 
     (setq p1 (getpoint "원의 중심위치는 :")) ;중심값 사용자 요구 (p1) 
     (command "circle" p1 r) ; p1위치에 r의 값인 원 작성 
    (princ))​

    다음은 두 점을 선택하면 그 점에 라인을 그리는 리습입니다. 
    사실 선을 그리는 것은 이 리습이 없어도 되지만 
    응용하기 위한 연습입니다. 필요없다 생각말고 따라해 봅시다. 

    (defun c:test5() 
     (setq p1 (getpoint "선의 시작위치는 :")) 
     (setq p2 (getpoint "선의 끝위치는 :")) 
     (command "line" p1 p2 "") 
    (princ))​

LIST

LIST란 ()안에 묶여서 하나의 그룹을 형성합니다. 
주로 좌표를 작성하는데 사용하며, 때때로 데이터를 묶어서 사용하고자 할때 사용하기도 합니다. 

1. LIST 만드는 방법 

(list a b c) 

list의 구분은 한칸의 공백으로 표현합니다. 
a,b,c 는 각각 한칸의 공백간격이 필요하죠 
a, b, c 세개를 그룹화하여 리스트를 만듭니다. 
좌표로 사용할 경우 a,b,c 각각이 x,y,z 좌표입니다. 
z좌표는 생략될 수 있습니다. 

좌표는 리스트형태로 써주어도 되고 따움표("")안에 넣어서 
사용할 수 있습니다. 
예를 보겠습니다. 

<방법1> (command "line" (list 100 100) (list 200 200) "") 
<방법2> (command "line" "100,100" "200,200" "") 

위의 두가지 방법은 모두 100,100 에서 200,200 으로 선을 그립니다. 
그러나 x 또는 y 좌표를 계속적으로 변경할 필요가 있을경우는 
List의 방법이 훨씬 쉽습니다. 
그 예입니다. x와 y좌표를 바꾸어 가면서 반지름 1인 원을 10개 작성합니다. 

(Defun c:test1() 
 (setq x 1) ; x의 초기값을 1로 설정 (x좌표로 사용목적) 
 (setq y 1) ; y의 초기값을 1로 설정 (y좌표로 사용목적) 

 (repeat 10; 10번을 반복합니다. 
 (command "circle" (list x y) "1") ; x,y좌표에 반지름 1인원을 작성 
(setq x (1+ x)) ; x값을 1증가 
(setq y (1+ y)) ; y값을 1증가 

(princ)) 

만약 z 좌표를 사용하고 싶으면 
(list 100 100 50) 처럼 세번째에 z좌표(여기선 50)을 써주면 됩니다. 

2. 리스트의 형태 

리스트는 좌표를 만들땐 숫자를 사용하지만, 다른 용도로 사용하고 싶으면 
문자도 가능하고 리스트안에 리스트를 포함시킬 수도 있습니다. 
리스트의 포함된 요소의 갯수는 정해진것이 없습니다. 
아래 예를 보고 리스트에 대해 익혀봅시다. 

☞ 좌표처럼 숫자만 사용 
(list 1 2 3) -> (1 2 3) 
☞ 문자를 사용하여 리스트 생성 
(list "a" "bb" "ccc") -> ("a" "bb" "ccc") 
☞ 숫자와 문자를 혼용 
(list "a" 123 "ccc" 44) -> ("a" 123 "ccc" 44) 
☞ 리스트 안에 리스트 생성 
(list "a" (1 2) 3 (1 2 3)) -> ("a" (1 2) 3 (1 2 3)) 
☞ 갯수제한이 없습니다. 
 (list 1) -> (1) 
 (list 1 2)-> (1 2) 
 (list 1 2 3)-> (1 2 3) 
 (list 1 2 3 4)-> (1 2 3 4) 
 (list 1 2 3 4 5)-> (1 2 3 4 5) 

 

LIST 활용

리스트 ()안의 요소들을 따로 분리해 봅시다. 
즉, (x y z)의 좌표값중에서 x, y, z값을 축출하여 리습에 적용하는거죠 

(car ) 리스트의 첫 번째 요소를 구한다. 
(cdr ) 리스트의 첫 번째 요소를 제외한 모든 요소를 구한다. 
(cadr ) 리스트의 두 번째 요소를 구한다. 

1. (car ) 함수: X좌표만을 구할때 주로사용 

(car)은 리스트의 첫번째 값을 취할 수 있습니다. 
예로 (1 2 3)이라는 리스트가 있다면 
(car '(1 2 3)) 의 결과값은 1 입니다. 
작은따움표(')는 괄호()앞에 쓰이며 
괄호()는 명령어를 의미하지만 작은따움표를 써주면 리스트로 인식합니다. 
예를 하나 더 들어보죠 

(defun c:test1() 
(setq a (list "aa" "bb" "cc")) 
(setq b (car a)) 


위의 예제는 a = ("aa" "bb" "cc") 를 의미하고 
b = "aa" 를 가지고 있습니다.  

2. (cdr ) 함수 

(cdr)은 리스트의 첫번째 요소를 제외한 전체 리스트값을 축출합니다. 
예로 (1 2 3 4 5)라는 리스트가 있다면 
(cdr '(1 2 3 4 5))의 결과값은 (2 3 4 5) 입니다. 
첫번째 리스트인 1이 빠지고 두번째 이후의 값을 가져옵니다. 

3. (cadr ) 함수: Y좌표만을 구할때 주로 사용 

(cadr)은 두번째 요소를 취합니다. 
사실 (cdr) + (car) 함수의 합성입니다. 
예를 들어보겠습니다. 

<예제1> 
 (defun c:test2() 
 (setq a (list 1 2 3)) 
 (setq c (cadr a)) ;(cadr) 두번째 요소 선택 


<예제2> 
(defun c:test3() 
(setq a (list 1 2 3)) 
(setq b (cdr a)) ;(cdr a)의 결과는 (2 3) 입니다. 
(setq c (car b)) ;(car '(2 3))의 결과는 2입니다. 


<예제3> 
(defun c:test4() 
(setq a (list 1 2 3)) 
(setq c (car (cdr a))) ;(cdr)을 먼저수행하고 (car)수행 


위의 예제는 모두 c 값이 2인 같은 결과를 나타냅니다. 
예제의 의도는 cadr이 cdr 과 car의 합성을 뜻한다는겁니다. 

4. (car)과 (cdr)의 합성 

① (caddr ) : Z 값을 구할때 주로 사용 

(caddr '(1 2 3)); 결과값은 3 

위의 예제는 (cdr)+(cdr)+(car)의 복합니다. 
(caddr)에서 d의 갯수가 1개이면 2번째 요소값 
d의 갯수가 2개이면 3번째 요소값 
그럼 (cadddr)처럼 d의 갯수가 3개이면 4번째 요소값이 되겠죠? 

② (cadddr ): 4번째의 요소선택 

(cadddr '(1 2 3 4 5)) ;결과값은 당연히 4 

이제 여러분이 조합을 잘 해보세요..생각도 잘 해보시구요. 

5. 복합예제 

<예제1> x←1, y←2, z←(x+y)값을 넣어서 좌표(xyz)에 반지름 1인 원을 그리는 리습 
(defun c:test5() 
 (setq x 1) 
 (setq y 2) 
 (setq z (+ x y)) 
 (setq xyz (list x y z)) ;좌표값으로 형성 
(command "circle" xyz "1");반지름 1인 원을 작성 


<예제2> 한점을 캐드에서 입력받아서 x,y,z 의 값을 취하는 리습 
(defun c:test6() 
 (setq pt (getpoint "점을 하나 선택하시죠? ")) 
 (setq x (car pt)) 
 (setq y (cadr pt)) 
 (setq z (caddr pt)) 
 ) 

 

 

반응형

'프로그래밍 > LISP' 카테고리의 다른 글

LISP 6.  (0) 2021.10.27
LISP 5.  (0) 2021.10.20
LIPS 4.  (1) 2021.10.16
LISP 2.  (0) 2021.10.09
LISP 1.  (0) 2021.10.06
댓글