3. 간단한 그림을 그리면서 변수와 함수이해하기
3.1 학습내용
3.1.1 목표
- 함수를 만들고 사용할 수 있다.
- argument(함수를 만들 때)와 parameter (함수를 호출할 때)
- 지역변수를 돌려주는 경우 return을 사용한다.
- 함수와 변수의 범위 (지역, 전역변수)
3.1.2 문제
- 시작-3 기역자 바람개비 그리기
- 시작-4: 간단한 도형 삼각형, 다각형, 별모양 그리기
- 시작-5: 자신의 이름을 쓰고, 자신의 아이콘으로 장식하기.
3.1 개요
- 변수는 '박스'에 비유해서 설명할 수 있다.
- 값을 변경할 수 있다. 이름으로 값을 읽어올 수 있다.
- 실제 값을 사용하기 보다는 변수를 사용하는 것이 재사용을 많이 할 수 있게 한다 (일반화 또는 추상화).
- 조그만 사각형, 큰 사각형을 하나의 함수로 처리하려면 변수를 사용해야 한다.
- 함수
- 함수는 명령어를 만드는 것이다.
- 함수는 중복된 문장을 제거해서 다시 사용하게 해준다.
- 재사용과 일반화
- 변수와 함수의 경우와 같이 프로그래밍에 있어 '재사용'은 매우 중요하다.
- '재사용'할 경우, 재사용되는 경우가 많아지도록 한다. 이를 일반화(추상화)라고 한다.
3.2 한글 자음 그려보기
3.2.1 간단한 한글 자음 그려보기
- home() 위치는 전체 화면의 중앙이다.
- clear()는 화면에 어떤 내용이 있다면, 깨끗하게 지운다.
# 홈에서 시작
t1.home()
t1.clear()
- 철자 '기역'을 그린다.
- fd(100)은 앞으로 100만큼 선을 그린다. 100은 화면의 화소 수를 말한다.
- right(90)은 우측으로 90도 이동한다. 거북이의 방향이 처음 0의 위치에 있었다. 변화를 살펴본다.
# ㄱ
t1.fd(100)
t1.right(90)
t1.fd(100)
- 철자 '니은'을 그린다.
- 철자 '기역'과는 모양은 같지만, 놓여진 방향이 다르다.
- 방향이 왼쪽으로 그린다.
- 철자 '니은'은 철자 '기역'에 이어서 그렸다.
- 위치를 지정해서 그리는 것은 다음에 기능을 배운다.
# ㄴ
t1.fd(100)
t1.left(90)
t1.fd(100)
- 철자 '디귿'은 이어서 그리려면 역방향으로 선을 그려야 한다.
- 그리고 방향을 전환하고, 직진, 좌향, 직진으로 완성한다.
# ㄷ
t1.back(100)
t1.right(90)
t1.fd(100)
t1.left(90)
t1.fd(100)
- 철자 '리을'을 그린다.
# ㄹ
t1.home()
t1.fd(100)
t1.right(90)
t1.fd(50)
t1.right(90)
t1.fd(100)
t1.left(90)
t1.fd(50)
t1.left(90)
t1.fd(100)
- 변수
- 박스로 비유. 박스의 이름이 변수, 그 안에 값이 있다.
- 이와 같이 하는 이유는 값을 저장해 놓고 다시 사용하려는 의도 (재사용)
- 값을 사용하기 보다는 변수를 사용하는 것이 재사용을 많이 할 수 있게 한다 (일반화 또는 추상화).
- 조그만 사각형, 큰 사각형을 하나의 함수로 처리하려면 변수를 사용해야 한다.
- 함수
- argument(함수를 만들 때)와 parameter (함수를 호출할 때)
- 지역변수를 돌려주는 경우 return을 사용한다.
- 함수와 변수
- 지역변수는 함수부에서만 (들여쓰기 한 부분에서만) 의미가 있다. 함수부를 벗어나면 파괴된다.
- 전역변수는 어느 곳에서나 사용할 수 있다.
3.2.2 변수를 이용해서 크기를 변경하기
- 변수에 기본 위치를 저장하고
- 반으로 줄여보기
배로 늘려보기
변수
- 값을 저장하는 것에 대한 이름.
- 값은 숫자, 문자를 갖음
- 숫자는 정수, 소수
- 문자는 문자 하나, 문자열
- 그 외 여러 변수형이 있지만 다음에 배우기로 하자.
# 홈으로 가서 지우고
t1.home()
t1.clear()
# ㄱ에 관해.
# 크기를 줄여보기
t1.fd(50)
t1.right(90)
t1.fd(50)
# 크기를 2배
t1.home()
t1.clear()
t1.fd(200)
t1.right(90)
t1.fd(200)
# 변수를 이용해서 크기
t1.home()
t1.clear()
size=100
t1.fd(size)
t1.right(90)
t1.fd(size)
- 변수의 데이터형을 이해해보기
- 왜 같은 수로 나누고 곱해도 다른 값?
- size=50일 경우 size/3*3은 왜 48일까?
- 정수형의 연산은 정수형으로 결과
- 소수와 정수가 같이 있는 경우는 큰 데이터형으로 결과
- 50/3 = 16
- 50/3. = 16.666
size=50
print size/2
print (size/2)*2
print (size/3)*3
print 50/3*3
25
50
48
48
3.2.3 함수로 만들어 보기
함수의 구성
- 함수명
- 함수 인자
- 함수 결과 값
함수를 이해하기
- f(x) = x + 1에서 x=1이면 2, x=10이면 11
- x
- x는 변수라고 한다.
- 프로그래밍에서는 argument라고 한다.
- x=1이면 argument는 x, parameter는 1이다.
- x argument의 데이터 형은 정수 또는 소수를 가진다.
왜 변수를 사용할까?
- 일반화 generalization
- x가 1이나 2나 어느 경우에나 적용될 수 있게 함
매개변수 및 실인자
- argument는 변수와 데이터 형을 모두 포함.
- 변수명은 의미를 알 수 있게 지어줌. 변수(지역변수)는 함수 내에서만 의미가 있다.
- 데이터 형은 숫자, 문자, 자료구조, 객체로 구분할 수 있다.
- parameter는 argument가 가지는 실제 값
- 아래에서 사용되는 size의 경우, 데이터형은 정수? 소수? 문자?
- 실제 값은 50,100... 으로 변할 수 있다.
함수를 만들 때는 argument, 호출할 때는 parameter
함수 만들 때 argument를 이용
def giyuk(size): ...
함수 호출할 때 parameter를 이용
giyuk(100)
- argument는 변수와 데이터 형을 모두 포함.
기계적으로 함수 만들어보기
- 중복을 찾는다
- 중복을 묶고 함수명을 준다
- 변경되는 것을 찾는다
- 인자로 빼준다
함수를 프로그램할 때
함수 헤더 (function header)
- def
- 함수명 f
- argument x
def f(x):
함수 부 (function body)
- python에서는 '들여쓰기'로 함수부를 구분한다 (function body)
- 들여쓰기는 1칸, 2칸 또는 그 이상도 사용할 수 있다. 줄 맞춤만 해주면 된다.
- 함수 결과 값의 반환
return
def f(x):
x+1
print "f(2)=",f(2)
f(2)= None
def f(x):
result=x+1
return result
y=f(2)
print "f(2)=",y
위에서 매우 중요한 2가지를 배워야 한다.
결과 값의 반환
return result
지역변수와 전역변수
- 지역변수는 x, result와 같이 함수부에서 사용된 변수이다. 함수를 벗어나면 값이 파괴된다는 점에서 지역변수라고 한다.
- 전역변수는 프로그램 어디에서나 값을 사용할 수 있다는 점에서 그 이름이 붙여졌다. y는 함수부에서 만들어지지 않았으므로 전역변수이다.
- 따라서 result는 반환하지 않으면, 함수를 호출하고도 그 결과 값을 사용할 수 없게 된다.
y=f(2)
함수는 IPO Input-Processing-Output. 즉 입력을 출력으로 변환하는 처리부를 말한다.
- 따라서 프로그래밍을 할 때, 어떤 입력을 어떤 출력으로 변환하는 과정을 함수에 넣도록 한다.
- 위 예제에서는 숫자(x)를 받아서, 단순하게 1을 더해서 x+1, 출력으로 돌려주는 처리부를 함수로 만들었다.
def giyuk(size):
t1.fd(size)
t1.right(90)
t1.fd(size)
t1.home()
giyuk(100)
def nieun(size):
t1.right(90)
t1.fd(size)
t1.left(90)
t1.fd(size)
- nieum()함수는 동쪽방향에서 시작할 경우, 오른쪽 90도 회전을 해서 남쪽에서 시작한다.
- 이러한 상대적 회전보다는, 남쪽을 향하고 시작하는 것이 좋다. 시작이 어느 방향이든지 올바르게 니은을 그릴 수 있다.
def nieun(size):
t1.setheading(270)
t1.fd(size)
t1.left(90)
t1.fd(size)
t1.home()
nieun(100)
- digeut()은 앞서 만든 nieum()을 사용해서 완성한다.
def digeut(size):
t1.setheading(0)
t1.bk(size)
nieun(size)
- rieul()은 giyuk()과 diguet()를 재사용하면 완성할 수 있다.
def rieul(size):
giyuk(size)
digeut(size)
# ㅁ = ㄱ + ㄴ
# ㄹ = ㄱ + - + ㄴ
# 크기를 변수argument로 실제 값parameter 100
def mieum(size):
giyuk(size)
nieun(size)
t1.home()
t1.clear()
mieum(100)
- ㄱ + ㄴ 으로 ㅁ 을 그리려면 다음을 주의
- 위치를 저장하지 않으면 한 철자 끝에서부터 그려진다.
- 방향을 저장하지 않으면 전 철자가 끝난 방향에서 그려진다.
- 위치를 이동할 때도 원하지 않는 궤적이 남는다.
- 변수를 이용한 저장
- 위치의 저장
- 방향의 저장
- oldpos=t1.pos()에 대하여
- t1.pos() 함수의 결과 값을 반환받는다.
- 그 결과 값을 oldpos에 저장한다.
def giyukAt(size, x):
t1.penup()
t1.goto(x,0)
t1.pendown()
t1.fd(size)
t1.right(90)
t1.fd(size)
def nieunAt(size,x):
t1.penup()
t1.goto(x,0)
t1.pendown()
t1.setheading(270)
t1.fd(size)
t1.left(90)
t1.fd(size)
def mieum(size,x):
giyukAt(size,x)
nieunAt(size,x)
def mieumPos(size):
# 위치와 방향의 저장
oldpos=t1.pos()
oldhead=t1.heading()
giyuk(size)
# 이동 궤적 지우기
t1.penup()
# 저장한 위치와 방향을 사용하기
t1.setpos(oldpos)
t1.setheading(oldhead)
t1.pendown()
nieun(size)
t1.home()
t1.clear()
mieumPos(100)
시작-3 기역자 바람개비 그리기
- ㄱ자를 회전하고 난 후, ㅁ자도 한다.
- 학습내용
- 변수를 사용할 수 있게 된다.
- 함수를 만들 수 있게 된다.
- 함수의 argument를 알게 된다.
- 중복을 식별할 수 있게 된다.
- 결과에서 중복이 얼마나 되는지 세어본다.
- 함수를 이용해 중복을 줄이는 것은 이번에 배우지만 반복문은 다음 장에서 배운다.
어떻게 하나
- 함수 giyuk(size)를 수정해서 giyukBackHome(size)
- 끝나는 위치가 시작점이 아니다.
- 바람개비를 그리려면 시작점으로 복귀
변수를 이용해 회전하는 모양
- 45도씩 증가시킴
turnBy=45
- 45도씩 증가시킴
8회 반복을 한다.
- 8개 (45 x 8 = 360도 회전)
- 반복을 하면, 프로그램에 중복이 존재하게 된다.
- ㅁ자를 회전시키려면, 함수 miumpos(size)를 수정해서 miumBackHome(size)
- ㄱ자와 같이 시작점으로 복귀
- 함수 giyuk(size)를 수정해서 giyukBackHome(size)
절차
- 시작에서의 위치oldPos를 저장
- 시작에서의 방향oldHead을 저장
- ㄱ자를 그림
- pen들고
- oldPos로 이동
- oldHead로 방향전환
- pendown
- 회전각도turnBy 틀고
- ㄱ자 그림
- 위를 반복
- 끝나면
- 더블클릭해서 완료하게 한다.
- 수업시간에 완료해서 확인
# ㄱ 회전 바람개비 - 위치를 원위치하지 않으면 바람개비 효과가 나지 않는다.
t1.home()
t1.clear()
giyuk(size)
giyuk(size)
# ㄱ 회전 바람개비 - 위치와 회전각을 변경하면 바람개비 효과가 난다.
t1.home()
t1.clear()
turnBy=45
size=100
oldpos=t1.pos()
oldhead=t1.heading()
giyuk(size)
t1.penup()
t1.setpos(oldpos)
t1.setheading(oldhead+turnBy)
t1.pendown()
giyuk(size)
3.2.4 위치
- 위치를 사용하면서 '복잡한 변수'를 이해한다.
- 위치의 데이터타잎은 1개로 구성되어 있지 않다.
- 앞서 말했던 변수 가운데 소수이지만, 단순형이 아니고 복합형.
변수를 이용해 상대위치를 사용할 수 있다.
위치 알아내기
oldpos=t1.pos() print oldpos
중복되는 식을 계산해서 변수에 저장해 놓기
상대 위치
- 3등분해서 ㄱ자 그리기
# 현재위치 구하기
t1.home()
print t1.pos()
# 윈도우 높이 너비 구하기
width=t1.window_width()
height=t1.window_height()
print width, height
(0.00,0.00)
840 787
- 형변환
- 정수에서 소수로 형변환하는 경우 casting이라고 한다.
- 소수와 정수가 만나면 소수로 형을 변환해준다.
50/3. 50/float(3)
# 변수를 이용한 상대 위치 저장하기
# 왜 '점(.)'을 넣어줄까?
x1=0.-(width-40.)/3
x2=0.
x3=0.+(width-40.)/3
print x1,x2,x3
-266.666666667 0.0 266.666666667
# 중복되는 식을 변수화
w3=(width-40.)/3
x1=0.-w3
x2=0.
x3=0.+w3
print x1,x2,x3
-266.666666667 0.0 266.666666667
- goto()와 setpos()와 같은 기능
- 사용할 수 있는 데이터타잎
- x,y - 정수/소수의 두 좌표 값
- (x,y) - Vec2D라고 하는 복잡한 타잎
# 첫째 위치로 가서 위치 써보기
t1.penup()
t1.goto(x1,0)
t1.pendown()
t1.pos()
t1.write(t1.pos())
# 첫째 위치에서 ㄱ자 그리기
giyuk(100)
- 회전각도를 조정하지 않으면 ㄱ자가 되지 않는다.
t1.setheading(0)
t1.clear()
# 1번째
t1.penup()
t1.goto(x1,0)
t1.setheading(0)
t1.pendown()
t1.pos()
t1.write(t1.pos())
giyuk(100)
# 2번째
t1.penup()
t1.goto(x2,0)
t1.setheading(0)
t1.pendown()
t1.pos()
t1.write(t1.pos())
giyuk(100)
# 3번째
t1.penup()
t1.goto(x3,0)
t1.setheading(0)
t1.pendown()
t1.pos()
t1.write(t1.pos())
giyuk(100)
- 앞서 배웠던 '기계적으로 함수 만들어보기'를 실제로 해보기
- 중복을 찾는다.
- 중복을 묶고 함수명을 준다.
- 의미있게 giyukAt
- 변경되는 것을 찾는다.
- 숫자를 찾는다 -> x1, 100
- 회전각도는 숫자이지만 변하지 않으므로 그냥 둔다.
- 인자로 빼준다
- 인자는 2개
- 인자의 형에 대해서도 생각해 본다.
- size: 정수형으로 크기를 의미한다. 화면크기보다 크게 되면 오류
- at: 정수,소수 모두 가능하며 위치를 의미한다. 화면크기를 벗어나면 오류
- 앞으로 배워나가기
- 함수로 만들어서, 함수 자체가 중복되는 것은 중복문for-loop로 처리한다 (다음 장에서 학습)
- 오류의 처리
def giyukAt(size,at):
t1.penup()
t1.goto(at,0)
t1.setheading(0)
t1.pendown()
t1.pos()
t1.write(t1.pos())
giyuk(size)
t1.clear()
giyukAt(100,x1)
giyukAt(100,x2)
giyukAt(100,x3)
3.3 간단한 도형 그려보기
- 4각형
- 3각형
- 앞서 배운 것을 활용해서 함수로 만들어 보기
t1.home()
t1.clear()
# rectangle
t1.forward(100)
t1.write(t1.pos())
t1.left(90)
t1.forward(100)
t1.write(t1.pos())
t1.left(90)
t1.forward(100)
t1.write(t1.pos())
t1.left(90)
t1.forward(100)
t1.write(t1.pos())
t1.home()
t1.clear()
# triangle
t1.forward(100)
t1.write(t1.pos())
t1.left(120)
t1.forward(100)
t1.write(t1.pos())
t1.left(120)
t1.forward(100)
t1.write(t1.pos())
t1.left(120)
시작-4: 간단한 도형 삼각형, 다각형, 별모양 그리기
- 학습내용
- 위치를 3등분해서 삼각형, 다각형, 별모양을 그린다.
- 위치 변수를 사용할 수 있게 된다.
- 함수를 사용할 수 있게 된다.
- 함수의 argument를 알게 된다.
- 중복을 식별할 수 있게 된다.
함수의 정의 - argument를 size(도형의 크기), pos(도형그리는 위치)
def drawTriangleAt(size, pos): ... def drawPolygonAt(size, pos): ... def drawStarAt(size, pos): ....
앞의 시작-3을 참조해서 작업한다.
시작-5: 자신의 이름을 쓰고, 자신의 아이콘으로 장식하기.
- 박스를 3개 다른 색으로 그려서, 그 안에 자신의 이름 한 글자씩 넣는다.
학습 내용
- 변수를 이해 (위치 변수 포함) - 사용하는 숫자가 반복되지 않게 한다.
- 중복을 이해 - 모든 철자는 함수로 만든다.
- Thumbnail
기본명령어, thumbnail을 배우면 30분 이내에 마칠 수 있슴.
- 주의
- 너무 예쁘게 쓰려고 하지 않는다.
- 글자 크기를 같게 한다.
- 철자를 함수로 만들 때는 철자+위치의 의미를 갖도록 예: giyukAt(size, pos)
- 문제를 풀고, 그 화면을 확인 (수업 중).
- 어떻게하나
- 1) 사진을 찍고, thumbnail로 변환 jpg -> gif
- 2) t1.stamp() 명령어를 사용한다.
- 3) 화면을 3등분하고 자신의 이름을 쓴다
- 4) 함수를 적절히 사용한다.