본문 바로가기
Programming/LOGO

LOGO 중급 연습 - repCount - 001

by The Programmer 2024. 11. 20.

1. Introduction

 
LOGO 중급 - repCount - 001 연습 예제입니다. 변수, 파라미터 변수, repCount 등을 이해할 수 있어야 합니다. boxes 함수의 lt :A 부분이 핵심입니다. 우연 효과 혹은 LOGO Bug? (텍스트 표시 라벨 부분은 일단 무시하세요.)
 
 

2. Code

 
to box1 :side
    repeat 4 [ fd :side rt 90 ]
end

to boxes
    repeat 1800 [ 
        box1 :side pu rt 90 fd :side+5 lt 90 
        make "A repCount + 0.7
        lt :A pd
    ]
end

to displayText
    gotoCenter
    text1
    gotoNextLine
    text2
end

to draw
    boxes
    displayText
    HT
end

to gotoCenter
    pu lt 90 fd 270 rt 90 fd 150 pd
end

to gotoNextLine
    pu back 30 pd
end

to main
    
setup
    draw

end

to setup
    Window Home CS PPT PD ST 
    pu rt 90 fd 150 lt 90 back 120 pd
    make "side 10
    make "A 0
end

to text1
    rt 90
    label [ "YS is BABO! ^.^ ..." ]
    lt 90
end

to text2
    rt 90
    label [ "SH is BABO too! ^.^ ..." ]
    lt 90
end


 

3. Result

 

[ LOGO 중급 연습 - repCount - 001 ]

 
 

4. Notes

boxes 함수의 lt :A 부분이 핵심입니다. 
 
make "A repCount + 0.7
lt :A pd
 
위 코드가 어떻게 해서 회전체를 만들어내는지 생각해보세요. repCount 값에다가 0.7을 더해서 A에 저장합니다. 여기서 repCount 값은 1부터 반복횟수 1800까지 자동 증가합니다.
 
repCount는 LOGO의 내장 특수 변수라서 변수명 앞에 콜론(:)을 사용하지 않습니다. repCount는 현재의 반복 횟수를 카운트하는 용도로 사용됩니다. 이 변수는 반복할 내용이 반복될 때마다 1씩 증가합니다. 처음에는 1부터 시작합니다.
 
0.7 증가폭으로 LT 회전각을 0.7 증가폭으로 1800회 반복하면 중간에 어떤 일이 발생하게 될까요?
 
1800 * 0.7 = 1260.
원과 같이 완전한 1회전에는 LT 360도면 충분합니다. 그런데 1260이나 주어지는군요. 대략 360의 3.5배 정도입니다.
 
Q1.  이 0.7을 제거하고 반복 횟수를 1800에서 720정도로 줄여서 테스트해보세요. 0.7이 제거된 상태에서 719와 720을 번갈아 가면서 테스트해보세요. 이 숫자 720에서 무엇을 알 수 있나요?
 
  Q2. 그리고 0.7 이 값을 변경해서 다양한 테스트를 해보세요. 이 값의 역할은 무엇인가요?
 
 
  테스트 - 02
 
0.7 떼어내고 360회 반복 시 결과. 검은 블랙홀 속으로 들어갔다가 나오면서 LT가 RT로 바뀐 느낌? ^.^;
( 뭔가 음수값으로 전환된 느낌? FD -100 또는 LT -45 같은 ... )
 
to boxes
    repeat 360 [ 
        box1 :side pu rt 90 fd :side+5 lt 90 
        make "A repCount
        lt :A pd
        show [ repCount : ] Show repCount
        ; 테스트 용으로 사용
        show [ :A ] show :A
        ; show 명령은 제법 delay가 발생함.
    ]
end
 
 
■ Result ...

 

블랙홀 속으로 들어갔다가 나오면 방향이 바뀌는 듯 보입니다?? 왜??
 
 

■  테스트 - 03
 
0.7 떼어내고 720회 반복 시 결과. 검은 블랙홀 속으로 들어갔다가 나오면서 LT가 RT로 바뀐 느낌? ^.^;
 
to boxes
    repeat 720 [ 
        box1 :side pu rt 90 fd :side+5 lt 90 
        make "A repCount
        lt :A pd
        show [ repCount : ] Show repCount
        ; 테스트 용으로 사용
        show [ :A ] show :A
        ; show 명령은 제법 delay가 발생함.
    ]
end

 
■ Result ...
 

[ 들어갈 때는 LT 느낌, 나올 때는 RT 느낌. 왜?? ]

 
 
■ Q. CoPilot에게 FMSLogo 블랙홀 부분 그림을 보여주며 손가락으로 가리키며 이 부분 저부분 질문하기...
 

더보기

make "A repCount + 0.7
lt :A pd

 

CoPilot은 FMSLogo의 repcount 변수가 정수형이라고 합니다. 변수 A는 부동소수점을 더해서 부동소수점 타입이 되고. LT 명령어는 정수형 뿐만 아니라 부동소수점 값도 문제없이 처리할 수 있을 것이라고 합니다.

 

"...

Q. 양수값이 음수값으로 해석될 수 있는 경우가 있는가?

A. 일반적으로 양수 값이 음수로 해석되는 경우는 드물지만, 데이터 형 변환이나 오버플로우와 같은 특정한 상황에서는 발생할 수 있습니다. 여기 몇 가지 예를 들어볼게요:

 

1) 데이터 형 변환: 정수의 크기가 제한된 데이터 타입을 사용할 때, 예를 들어 16비트 정수에서는 최대값이 32767이고, 최소값이 -32768입니다. 만약 최대값을 넘는 값을 저장하려고 하면 오버플로우가 발생할 수 있습니다. 이 경우, 양수 값이 음수로 해석될 수 있습니다.

 
 
python 예시 코드

 

import numpy as np
x = np.int16(32767 + 1)
print(x)  # -32768이 출력됩니다.

 

2) 메모리 해석 문제: 비트 단위로 데이터를 해석할 때, 부호 비트를 잘못 해석하면 양수 값이 음수로 보일 수 있습니다. 예를 들어, 부호와 절대값 표현 (Sign-Magnitude Representation) 에서는 최상위 비트가 부호를 나타내므로, 이 비트를 잘못 읽으면 양수 값이 음수로 해석될 수 있습니다.

 

3) 2의 보수 표기법: 컴퓨터 시스템에서 음수를 표현하는 데 자주 사용되는 2의 보수 표기법에서도, 부호 비트를 포함한 전체 비트를 사용하여 음수 값을 표현합니다. 만약 이러한 비트를 잘못 해석하면 음수 값이 양수로, 혹은 양수 값이 음수로 해석될 수 있습니다.

 

python 예시 코드
 
def to_signed(n):
    return n if n < 0x8000 else n - 0x10000

# 16비트 정수 값 0xFFFF는 -1로 해석됩니다.
signed_value = to_signed(0xFFFF)
print(signed_value)  # -1 출력

 

(

□ 참고 : 

return n if n < 0x8000 else n - 0x10000   

# 위 표현에 쓰인 16진수 값들은 각각 십진수 32768, 십진수 65536. 타입 최대값들 비교 조건.

)

 

이러한 상황들은 주로 저수준 프로그래밍이나 시스템 프로그램에서 발생할 수 있습니다. 일반적인 고수준 프로그래밍 언어에서는 이러한 문제를 자동으로 처리해주기 때문에, 개발자가 직접적인 문제로 겪을 일은 많지 않습니다.

..."

 

 

"...

Logo 프로그래밍 환경에서 양수 값이 음수로 해석될 수 있는 경우는 매우 드뭅니다. 하지만 특정 상황에서는 데이터 형 변환이나 부호 비트의 잘못된 처리로 인해 이러한 문제가 발생할 수 있습니다. 다음은 Logo에서 발생할 수 있는 몇 가지 경우입니다:

  1. 큰 수의 사용: Logo는 일반적으로 큰 숫자를 처리할 수 있지만, 특정 환경이나 구현에서는 최대 처리 가능한 숫자가 제한될 수 있습니다. 이러한 경우 오버플로우가 발생할 수 있으며, 이로 인해 예상치 못한 결과가 나올 수 있습니다.
  2. 부동 소수점 연산: 부동 소수점 연산에서는 소수점 이하의 정밀도가 제한될 수 있습니다. 이로 인해 매우 큰 값이나 매우 작은 값을 처리할 때 부정확한 결과가 나타날 수 있으며, 이는 음수로 해석될 가능성도 있습니다.
  3. 저수준의 메모리 해석: Logo 자체는 고수준의 교육용 프로그래밍 언어로 설계되어 저수준의 메모리 관리 문제를 직접 다루지는 않지만, Logo 인터프리터나 컴파일러가 내부적으로 메모리를 어떻게 해석하느냐에 따라 이러한 문제가 발생할 수 있습니다.
  4. 변수 범위 및 타입: 특정 구현에서는 변수의 범위나 타입에 따라 값이 이상하게 변환될 수 있습니다. 예를 들어, 양수 값을 저장할 변수의 크기가 작다면 오버플로우가 발생할 수 있습니다.

전반적으로 Logo는 이러한 문제를 피할 수 있도록 설계된 고수준 언어이기 때문에, 일반적인 사용에서는 큰 문제가 발생하지 않습니다. 그러나 특정 상황에서는 예상치 못한 결과가 발생할 수 있음을 유념하시기 바랍니다.

..."

 

 

"...

A. 이해했습니다. 오버플로우는 특정한 상황에서 발생할 수 있는 문제입니다. 특히 반복 횟수가 매우 클 경우, 변수의 값이 최대치에 도달하면서 양수 값이 음수 값으로 변환될 수 있습니다. Logo에서는 이러한 문제를 방지하기 위해 변수의 범위를 잘 관리하는 것이 중요합니다.

 

repcount는 Logo의 repeat 문에서 자연스럽게 증가하는 값입니다. 이 값이 매우 큰 경우, 특히 내부적으로 사용하는 데이터 타입의 한계를 넘어서면 오버플로우가 발생할 수 있습니다. 그러나 일반적인 Logo 환경에서는 이러한 경우가 드물게 발생합니다.

 

하지만 무한히 큰 숫자나 매우 큰 반복 횟수를 사용할 때, 시스템의 한계나 구현 방식에 따라 문제가 발생할 수 있습니다. 예를 들어, 32비트 정수형 데이터 타입은 최대 약 21억 (2^31 - 1)까지의 값을 저장할 수 있습니다. 이 범위를 초과하면 오버플로우가 발생하여 부호가 반전될 수 있습니다.

 

따라서, Logo 프로그램에서 매우 큰 값을 사용할 때에는 이러한 한계를 염두에 두고, 필요한 경우 적절한 범위 내에서 값을 관리하는 것이 좋습니다. 현재 코드에서는 1800번의 반복이므로, 대부분의 환경에서 오버플로우 문제가 발생하지 않을 것입니다.

..."

 

... 는 불가능합니다만.
 
그럼 뭔가요...??
 
 

5. 응용 연습 1

LT에 사용된 회전각 값만 약간 조정합니다. 도형이 변형되어 텍스트 위치값도 적절하게 조정해줍니다.
 
to box1 :side
    repeat 4 [ fd :side rt 90 ]
end

to boxes
    repeat 1800 [ 
        box1 :side pu rt 90 fd :side+5 lt 90 
        make "A repCount + 0.75
        lt :A pd
        ; show [ repCount : ] Show repCount
        ; 테스트 용으로 사용
        ; show [ :A ] show :A
        ; show 명령은 제법 delay가 발생함.
    ]
end

to displayText
    rt 90
    gotoCenter
    text1
    gotoNextLine
    text2
end

to draw
    ; SLOWDRAW 0
    ; for Slow Drawing
    ; FullScreen
    ; FullScreen, fs <--> SPLITSCREEN, ss
    boxes
    displayText
    HT
end

to gotoCenter
    pu lt 90 fd 230 rt 90 back 150 pd
end

to gotoNextLine
    pu back 30 pd
end

to main
    setup

    draw
end

to setup
    Window Home CS PPT PD ST 
    pu rt 90 fd 200 lt 90 back 150 pd
    make "side 15
    make "A 0
end

to text1
    rt 90
    label [ "YS is BABO! ^.^ ..." ]
    lt 90
end

to text2
    rt 90
    label [ "SH is BABO too! ^.^ ..." ]
    lt 90
end

 
■ Result .. 
 

[ LOGO 중급 연습 - repCount - 003 ]

 

6. 응용연습  - 2

 
거의 달라지지 않았습니다만. 6각형스러운 도형을 그립니다.
 
to box1 :side
    repeat 4 [ fd :side rt 90 ]
end

to boxes
    repeat 2160 [ 
        box1 :side pu rt 90 fd :side+5 lt 90 
        make "A repCount + 0.6669
        lt :A pd
        ; show [ repCount : ] Show repCount
        ; 테스트 용으로 사용
        ; show [ :A ] show :A
        ; show 명령은 제법 delay가 발생함.
    ]
end

to displayText
    ; rt 90
    gotoCenter
    text1
    gotoNextLine
    text2
end

to draw
    ; SLOWDRAW 0
    ; for Slow Drawing
    ; FullScreen
    ; FullScreen, fs <--> SPLITSCREEN, ss
    setup
     boxes

    displayText
    HT
end

to gotoCenter
    pu lt 90 fd 250 rt 90 fd 160 pd
end

to gotoNextLine
    pu back 30 pd
end

to main
    draw
end

to setup
    Window Home CS PPT PD ST 
    pu rt 90 fd 200 lt 90 back 100 pd
    make "side 6
    make "A 0
end

to text1
    rt 90
    label [ "YS is BABO! ^.^ ..." ]
    lt 90
end

to text2
    rt 90
    label [ "SH is BABO too! ^.^ ..." ]
    lt 90
end

 

■ Result .. 
 

[ 6각형스러운.. ! ]

 
우하단, 끝 연결 마감 부분은 대략 어림짐작값으로 처리했습니다. ㅡ.ㅡ;
 
 

7. 응용 연습 - 3

LT 값이 180 이상이라면 RT 값으로 전환해서 생각할 수도 있습니다. 예를 들어 LT 181 --> RT 179.

 

repCount 값을 받아서 사용하고 있는 LT 값이 180(도) 이상이면 RT 값으로 전환해서 그립니다.

 

180 그 이하일 때는 아예 무시하고 LT 값 적용 부분을 아예 패스해서 LT 값이 적용되지 않으니 직선 형태로 그려집니다.

 

RT :A에서 변수 A의 값은 180에서 시작해서 1씩 감소하는 방향으로 진행됩니다.

 

180(도)를 기준으로 그 이하이면 박스를 그리고 그 이상이면 삼각형을 그립니다. 시각적 분리.

 

박스 크기 때문에 한참 왼쪽에서 시작해야 해서 시작 위치를 무려 3000이나 왼쪽으로 옮겨놓고 시작합니다.

 

■  Code

 

to box1 :side
    repeat 4 [ fd :side rt 90 ]
end

to boxes

    ; LT 값이 180 이상이라면 RT 값으로 전환해서 생각할 수도 있습니다.
    ; 예를 들어 LT 181 --> RT 179.
    repeat 360 [ 
        make "A repCount + 0.7
        ifelse repCount >= 180 [                                       ; ifelse의 if 블록
            tri1 :side move1  
            make "mod modulo repCount 180       ; 나머지 구하기. 
            make "downto :mod * -1                           ; 나머지를 음수값으로.
            make "A 180 + :downto                              ; 180부터 시작해서 감소함.
            type  [ repCount_: ] show repCount     ; check. show 명령은 제법 delay가 발생함.
            type  [ A : ] show :A                                       ; check . type은 비슷한 용도의 print와는 달리 줄을 바꾸지 않는다.
            rt :A
            ; wait 1                                                               ; wait num.에서 num.은 60분의 1초를 의미합니다. 아마도. ^.^;
        ][ 
            box1 :side move1                                          ; ifesle의 else 블록

            ; lt :A
        ]

    ]
end

to draw
    ; SLOWDRAW 0
    ; for Slow Drawing
    ; FullScreen
    ; FullScreen, fs <--> SPLITSCREEN, ss
    setup
    boxes
    printText
    HT
end

to gotoNextLine
    pu back 30 pd
end

to gotoTextPosition
    pu fd 450 rt 90 fd 220 pd   

    ; 도형 그리기의 끝 장면에서 거북이의 위치와 방향과 관계됨.

    ; pu home pd으로 새로 재조정할 수도 있음.
end

to main
    draw
end

to move1
    pu rt 90 fd :side+2 lt 90 pd
end

to printText
    gotoTextPosition
    text1
    gotoNextLine
    text2
end

to setup
    Window Home CS PPT PD ST 
    pu lt 90 fd 3000 rt 90 back 100 pd
    make "side 15
    make "A 0
end

to text1
    rt 90
    label [ "YS is BABO! ^.^ ..." ]
    lt 90
end

to text2
    rt 90
    label [ "SH is BABO too! ^.^ ..." ]
    lt 90
end

to tri1 :side
     pd repeat 3 [ fd :side rt 120 ] pd
end

 

■ Result :

 

[ LT 180 그 이상에서의 문제 ]

 

 

  Comments :

 

LT 180 이상에서 연속된 LT Curve가 RT Curve처럼 보임. 이 현상에 착안, 응용해서 아예 RT로 명시적으로 그림.

 

다음 코드는 한 두 줄로 묶어 좀 더 간결하게 표현할 수도 있겠으나 괄호를 사용했더니, ifelse 블록내 괄호가 너무 많다고 뭐라 뭐라 잔소리를 해대서 일단 분리 처리했습니다. ^.^;

 

            make "mod modulo repCount 180       ; 나머지 구하기. 
            make "downto :mod * -1                           ; 나머지를 음수값으로.
            make "A 180 + :downto                              ; 180부터 시작해서 1씩 감소함.

 

8. Files

 

Logo_Pro_IM_001_variables_001_.lgo
0.00MB
Logo_Pro_IM_001_variables_003_.lgo
0.00MB
Logo_Pro_IM_001_variables_004_.lgo
0.00MB
Logo_Pro_IM_001_variables_006_.lgo
0.00MB

 

9. Ref.

1) FMSLogo 내장 공식 도움말

2) JD8, Comments.
 
 
Happy Programming!
^.^;