python

hanahana·2022년 7월 30일
0

파이썬

목록 보기
1/1
post-thumbnail

프로그램 작성 예제

함수

여러개의 프로그램 명령어를 모아 놓은것

새로운 함수의 이름과 함수가 호출될 때 실행되 명령들로 만들어짐

def print_message () : 
  print ("Cs101")

print_message() 라는 함수를 정의하겠다는 뜻

:는 함수의 정의 def는 키워드를 뜻한다

print - ()안의 내용을 출력함

print_message안에 함수를 넣을때 다음줄에서 반드시 공백 2칸이 필요함

공백 2칸이 있을때 그 안에 있는것으로 이해함

def repeat_message () :
  print_message ()
  print_message ()

repeat_message는 print_message를 2번 불러오는 함수라고 정의한다.

실행순서

함수는 왼쪽에서 오른쪽 위에서 밑의 순서로 실행한다.

파이썬에서는 공백을 맞추는것도 매우 중요!!!

예제실행

def print_message() :
  print("cs101 is fantastic!")
  print("programing is so much fun!")

#print_message라는 함수를 정의하였다

print_message()
#print_message를 실행한다

def repeat_message( ):
    print_message()
    print_message()
#repeat_message는 print_message를 두번 실행하는 함수이다

repeat_message()
#repeat_message를 실행한다

실행결과

cs101 is fantastic!
programing is so much fun!
cs101 is fantastic!
programing is so much fun!
cs101 is fantastic!
programing is so much fun!
  • 실행결과는 코드에 따라 print_message를 한번 출력한뒤 repeat_message를 한번 출력하는 것이다
  • repeat_message는 print_message를 두번 실행하는 것이기에 print_message안의 값인 cs101 is fantastic! programing is so much fun! 이 총 3번 출력되는 결과를 볼수 있다.

로봇움직이기

파이썬은 모듈을 불러와 사용할수있다.

이 명령어는 IDLE 에디터에서만 실행가능하다

from cs1robots import *
create_world()

cs1robotds라는 모듈을 불러와 create_world를 실행시켜주면 10칸짜리 로봇이 움직일수있는 윈도우가 생성된다

hubo = Robot(beepers = 1)

이 명령어로 로봇이 생성된다.

로봇은 다음 명령어로 움직일 수 있다.

hubo.move() #한칸 전진한다
hubo.turn_left() #왼쪽으로 회전한다.

오른쪽으로 회전하고 싶을때는 새로운 명령어를 정의한다

def turn_right() :
hubo.turn_left()
hubo.turn_left()
hubo.turn_left()

이런 반복 명령어를 줄일수 있는 법이 for문이다

For문

def turn_right() :
  for i in range(3) :   #정의해주기에 앞에 2칸을 띈다
    hubo.turn_left()  #i를 다시 정의하는 것이기에 앞에 4칸을 띈다

실행하면 돌아선 로봇을 볼수있다.

로봇예제

휴보에게 계단을 올라서서 다시 돌아나오는 프로그래밍을 해본다.

  1. 휴보는 앞으로 한칸
  2. 휴보는 위로 한칸
  3. 휴보는 앞으로 2칸
  4. 휴보는 위로 한칸
  5. 휴보는 앞으로 앞으로 2칸
  6. 휴보는 위로 한칸
  7. 휴보는 앞으로 2칸
  8. 휴보는 위로 한칸
  9. 휴보는 앞으로 2칸
  10. 한바퀴를 돌아서
  11. 앞으로 2칸
  12. 아래로 한칸
  13. 앞으로 2칸
  14. 아래로 한칸
  15. 앞으로 2칸
  16. 아래로 한칸
  17. 앞으로 2칸
  18. 아래로 한칸
  19. 앞으로 한칸

을 실행한다

반복 할 명령어

휴보는 계단을 오르는것을 반복한다 계단을 오를때에는

  1. 위로 한칸 올라간다
    1. 위로 올라가는것은 화면 반대방향을 보고 전진하면 위로 올라갈수 있다.
  2. 휴보는 앞으로 두칸 전진한다

를 반복한다.

이것을 코드로 구성하면

def step_1() :
  hubo.turn_left() #기본 상태에서 왼쪽으로 돌면 화면을 등진다.
  hubo. move()
  turn_right() #화면 우측을 본다.
  hubo. move()
  hubo. move()

휴보는 계단을 4번 올라가기에 이것을 4번 반복한다 이 명령을 for문으로 반복하면

def step_4() :
  for i in range(4) :   #정의해주기에 앞에 2칸을 띈다
    step_1()  #i를 다시 정의하는 것이기에 앞에 4칸을 띈다

라고 할수있다.

  • 휴보는 한바퀴 회전한다.
def turn_around() :
  turn_right() #휴보는 기본적으로 왼쪽을 보고있다 오른쪽으로 돌면 화면 정면을 본다
  turn_right() #정면에서 오른쪽을 한번 더 돌면 기본값과 정 반대를 볼수있다.
  • 휴보는 계단을 내려오기를 4번 반복한다.
def down_step() :
  hubo.move()
  hubo.move()
  hubo.turn_left() #휴보가 화면 정면을 보고 이동하면 내려갈수 있다
  hubo.move()
  turn_right()
#계단을 1번 내려오는 명령어

def down_4_step() :
  for i in range(4) : 
    down_step()

#명령어를 4번 반복하여 계단을 4번 내려올수 있게된다.

따라서 계단오르내리기 명령어는 다음과 같다

hubo.move()
step_4()
turn_around()
down_4_step()
turn_right()
hubo.move()

막상 해보니 시행착오가 굉장히 많았지만 실수해가면서 만들어가니 이해가 쉬운것 같다

python if 조건문과 while 반복문

조건문

if 조건 :  #만약 조건이 참이라면
  실행문()  # 2칸을 띄고 실행문을 실행한다
else  :  #조건이 거짓이라면
  실행문() # 2칸띄고 실행문을 실행한다

예제

if True:  # True는 반드시 첫자가 대문자이다  만약 참이라면 
    print("CS101 is my favorite course")  #()안의 값을 출력한다

if False:  #False는 반드시 첫자가 대문자이다 만약 참이라면
    print("Every CS101 student will receive an A+")
#()안의 값을 출력한다

if 3 < 5:  #만일 이 값이 참이라면 
    print("3 is less than 5") #()값을 출력한다
else:  #참이 아니라면(=거짓이라면)
    print("3 is larger than 5")  #()안의 값을 출력한다
  • True와 False를 선언할때 앞자는 반드시 대문자여야 한다

not으로 조건을 반대로 바꾼다

if not 3 < 5:  #3<5가 아니(not)라면
    print("3 is less than 5") #()값을 출력한다
else:  # 3<5가 맞다면 (not의 false)
    print("3 is larger than 5")  #()안의 값을 출력한다
  • 이 경우 3<5값은 참이기때문에 if첫번째 조건문은 실행되지 않으며 else값이 실행된다
  • not은 true를 false로 false를 true조건으로 만든다

else

 def move_or_turn():
		if hubo.front_is_clear() : #휴보의 앞에 아무것도 없을때
			hubo.move() #휴보는 한칸 이동한다
	else : #휴보의 앞에 한칸없는것이 거짓일때
		hubo.turn_left() #휴보는 왼쪽으로 돈다

		
 for i in range(20) :
		move_or_turn() #위의 if문을 20번 반복한다
  • 휴보가 벽 끝까지 가서 몸을 돌려 다시 벽 끝으로 돌아 한바퀴를 돌수 있는 반복 문이다.
  • 이 반복문에서는 20번 반복했는데 몇번을 반복하든 휴보는 앞에 벽이 없으면 직진하고 벽을 만나면 왼쪽으로 돌게되어 반복을 입력한 만큼의 값을 움직인다

그림은 11번을 반복하여 왼쪽으로 회전한 휴보이다

들여쓰기의 중요성

 def move_or_turn():
		if hubo.front_is_clear() : #휴보의 앞에 아무것도 없을때
			hubo.move() #휴보는 한칸 이동한다
	else : #휴보의 앞에 한칸없는것이 거짓일때
		hubo.turn_left() #휴보는 왼쪽으로 돈다
		hubo.move() #휴보는 한칸 이동한다
  • 이때의 명령어는 휴보의 앞에 아무것도 없을때 휴보는 한칸이동하고 휴보의 앞에 벽이 있으면 휴보는 왼쪽으로 돌아 한칸 이동하는 것이다
 def move_or_turn():
		if hubo.front_is_clear() : #휴보의 앞에 아무것도 없을때
			hubo.move() #휴보는 한칸 이동한다
	else : #휴보의 앞에 한칸없는것이 거짓일때
		hubo.turn_left() #휴보는 왼쪽으로 돈다
hubo.move() #들여쓰기가 달라졌다  이 명령어는 조건문과는 상관없이 반드시 실행된다
  • if와 else의 조건과는 상관없이 맨 마지막 명령어를 무조건 수행한다
    • ture 일때 : 휴보는 앞에 아무것도 없으때 한칸이동하고 다시 한칸이동한다
    • false 일때 : 휴보는 앞에 벽이 있을때 왼쪽으로 돌고 한칸 이동한다.
  • 들여쓰기를 하지 않으면 if esle의 반복문이 아니라 별개의 명령으로 인식한다.

elif

  • 길어지는 if문을 줄일수 있다
if hubo.on_beeper():  #휴보위에 beeper가 있으면
    hubo.pick_beeper() #beeper를 줍는다
else: #그렇지 않으면
    if hubo.front_is_clear():  #앞에 아무것도 없으면
        hubo.move() #한칸 전진
    else: #그렇지 않으면
        if hubo.left_is_clear(): #왼쪽에 아무것도 없다면
            hubo.turn_left() #왼쪽으로 회전
        else: #그렇지 않으면
            if hubo.right_is_clear():  #휴보의 오른쪽에 아무것도 없다면
                turn_right() #오른쪽으로 회전
            else: #그렇지 않으면
                turn_around() #반대쪽로 돈다

if와 else문이 너무 많아 들여쓰기가 잦아 입력하기도 보기에도 힘들어진다

if hubo.on_beeper():   #휴보 위에 beeper가 있으면
    hubo.pick_beeper() #beeper를 줍는다
elif hubo.front_is_clear():  #elif =그렇지 않고 + 앞에 아무것도 없으면
    hubo.move() #한칸전진
elif hubo.left_is_clear(): #그렇지 않고 왼쪽에 아무것도 없으면
    hubo.turn_left() #왼쪽으로 돌기
elif hubo.right_is_clear():  #그렇지 않고 오른쪽엥 아무것도 없으면
    turn_right() #오른쪽으로 돌기
else: #위에 모든것이 그렇지 않으면
    turn_around() #반대쪽으로 돈다

이런식으로 elif를 사용하면 손쉽게 코드를 짤수 있다

While반복문

  • 조건이 참이면 밑에 명령을 계속 수행한다
while not hubo.on_beeper():
  hubo.move()
  • 이 경우 while의 hubo.on_beeper가 아닐때가 false가 될때까지 계속 움직이게 된다.
    • 다시 말해 beeper를 만나기 전까지 움직인다.

python if와 while을 활용한 미로탈출

hubo에게 다음가 같은 행동을 하게 한다

해결 과정 :

① 시작점에 비퍼를 놓는다

② 벽을 만날 때까지 전진한다

③ 좌회전한다

④ 2, 3번 과정을 비퍼를 발견할 때까지 반복한다

⑤ 비퍼를 발견하면 종료한다

휴보는 이 미로를 한바퀴 돌아서 원래 자리로 돌아올것이다.

hubo.drop_beeper()
hubo.move()
	while not hubo.on_beeper():
		if hubo.front_is_clear():
			hubo.move()
		else:
			hubo.turn_left()

첫줄에 beeper를 놓아주고 휴고를 움직이면 휴고가 while문의 false값에 반응하여 움직이지 않는다

beeper를 놓아준뒤 앞으로 한칸가야 한다

하지만 이 경우 휴보는 벽을 따라가지 않고 3번째 줄에서 beeper위치까지 돌아와버린다

while not hubo.on_beeper():
	if hubo.right_is_clear():
		turn_right()
		time.sleep(sleeptiome) #이건 천천히 움직이게 하는 명령어
	elif hubo.front_is_clear():
		hubo.move()
		time.sleep(sleeptiome)
	else :
		hubo.turn_left()
		time.sleep(sleeptiome))

휴보가 오른쪽을 보면 돌아갈수 있는 명령어를 넣었다.

중간에 벽을 만나자 그곳에서 회전만 하게 된다 오른쪽이 비어있고 왼쪽도 비어있으니 뱅글뱅글 도는것을 반복하는 것이다.

while not hubo.on_beeper():
	if hubo.right_is_clear():
		turn_right()
		hubo.move() #오른쪽에서 휴보가 전진하는 명령어를 넣어준다
		time.sleep(sleeptiome) #이건 천천히 움직이게 하는 명령어
	elif hubo.front_is_clear():
		hubo.move()
		time.sleep(sleeptiome)
	else :
		hubo.turn_left()
		time.sleep(sleeptiome)

이 경우 위 지도에서는 회전이 가능하지만 다른 지도에서는 움직이지 못하게 된다.

# This program lets the robot go around her world
# counter clockwise, stopping when he returns
# to the starting point.

from cs1robots import * 
load_world()
hubo = Robot(beepers=1)

def turn_right():
    for i in range(3):
        hubo.turn_left()

def mark_starting_point_and_move():
    hubo.drop_beeper()
    while not hubo.front_is_clear():
        hubo.turn_left()
    hubo.move()

def follow_right_wall():
    if hubo.right_is_clear():
        # Keep to the right  
        turn_right()  
        hubo.move()
    elif hubo.front_is_clear():
        # move following the right wall
        hubo.move()
    else:
        # follow the wall
        hubo.turn_left()

# end of definitions, begin solution  

mark_starting_point_and_move()
 
while not hubo.on_beeper():
    follow_right_wall()

프로그램 작성시 추천 방법:

  • 간단하게 시작하자

* 한 번에 하나의 작은 작업만 수행하자

* 각각의 작업들이 이전에 했던 작업에 영향을 주지 않도록 하자

* 알기 쉬운 유용한 주석을 달자     (프로그램 명령들을 있는 그대로 글로 쓰지는 말자)

* 의미를 잘 전달하는 이름을 고르자

python 객체와 형태

객체

각각의 데이터를 뜻함

객체의 종류

  • 숫자
    • 13
    • 3.14159265
    • -5
    • 3 + 6j
  • 문자열: “”를 사용
    • "CS101 is wonderful"
    • 'The instructor said: "Well done!" and smiled'
  • 복잡한 객체 : 객체를 만드는 함수를 부르는 망식으로 사용
    • from cs1robots import *
    • Robot()
    • from cs1media import *
    • load_picture("photos/geowi.jpg")
  • 튜플(Tuple) : 다른 객체를 묶어주는 객체
    • (3, 2.5, 7)
    • ("red", "yellow", "green")
    • (20100001, "Hong Gildong")

형태

  • 객체가 할수 있는 결정

  • 객체를 이용해 할수 있는 결정

  • type(3) : class int 정수

  • type(3.1415) : class float 실수

  • type(”class is fanstatic”) : class str 무자욜

  • type(3+7) : class complex 복소수

  • type(true) : class bool 논리값

  • type(Robot()) : class cs1robts.Robot

  • type((3,-1.5,7)) : class tuple

  • type(load_picture(”geowi.jpg”) : class ‘cs1media.pictur’

이처럼 하수와 class의 이름이 복잡한 객체의 타입으로 표시됨

객체의 이름

message = "CS101 is fantastic"

이 겨우 "CS101 is fantastic"message로 지정해주었다

이것을 대입문이라고 한다.

n=17 #n의 값은 17이 된다
hubo=Robot() #hubo에게 명령하면 Robot()에게 명령한 것이 된다

hubo.move #따라서 이 명령으로 로봇은 움직인다
  • 영어문자, 숫자, 밑줄 문자 _ 로만 가능하다
  • 이름의 첫 글자는 숫자로 쓸수 없다
  • python에 등록된 키워드는 사용할수 없다
  • 이름은 대,소문자를 구분한다
  • 객체에 붙여준 이름은 변수라고 한다
  • 실행중 변수가 가리키는 객체가 바뀔수 있다
    • n=17
    • n=”seventeen”
    • 이렇게 2개의 값이 입력이 되었을때는 나중에 입력한값으로 n의 정의가 변경된다

None

  • 파이선 안에 있는 객체
  • 특별한 용도로만 사용
  • none : type(n) class NoneType
  • 값이 없다 비어있다는 뜻

멤버 변수

  • 객체가 할수있는 일은 객체의 형태에 결정된다
  • 멤버 함수(Method)에 의해 수행된다
  • 점(.)연사자를 통해 실행가능하다
    hubo=Robot()
    hubo.move()
    hubo.turn_left()
    img=load_picture("geowi.jpg")
    print(img.size())
    (58.50) #이것은 위의 명령의 출력값이다
    img.show()#이미지를 출력한다.

여러이름을 가진 객체

hubo=Robot("yellow") #hubo는 노란색 로봇이다
hubo.move() #노란색 로봇이 움직인다

ami=hubo #ami는 hubo이다
ami.turn_left() #노란색 로봇이 왼쪽으로 회전한다
hubo.move() # 노란색 로봇이 움직인다

hubo=Robot("blue") #hubo는 파란색로봇이다
amie.turn_left() #노란색 로봇이 왼쪽으로 회전한다
ami.move #노란색 로봇이 움직인다.
  • 처음에는 ami는 hubo와 같은 노란색 로봇이었다.
  • 그래서 hubo와 ami에게 명령을 하면 노란색 로봇이 움직였다
  • 셋째 단에서 hubo는 파란 로봇으로 재 정의된다
  • ami에게 명령을 하면 노란색 로봇이 움직인다
  • hubo에게 명령하면 파란 로봇이 움직인다

여러개의 이름을 가지는 것을 alias라고 하고 객체는 바뀔수있다.

여러가지 연산자

// 정수 나눗셈

>>> 13//4
3
>>> 13.0//4.0
3.0
>>> 9/7
1.2857142857142858
>>> 9//7
1

//로 나누면 나누기의 나머지 값이 보이지 않고 정수로 값이 나온다

/는 나머지 값이 보인다.

>>> 2*2*2*2*2
32
>>> 2**5
32
>>> 2*2*2
8
>>> 2**3
8
>>> 7%3
1
>>> 7%-3
-2
>>> -7%3
2
>>>
  • **는 거듭재곱연산 앞의 숫자의 몇승인지를 계산한다 2**5는 2의 5승을 뜻한다
  • %는 나머지 연산자이다 7%3 은 7/3의 나머지 값이라는 뜻이다
  • 음수 나눗셈의 경우 뒤에 숫자로 -/+가 정해진다

우선순위

  1. 거듭제곱 **
  2. 곱셈, 나눗셈
  3. 덧셈 뺄셈

연산자는 문자열에도 사용가능하다

>>> "Hello"+"CS101"
'HelloCS101'
>>> "CS101"*8
'CS101CS101CS101CS101CS101CS101CS101CS101'

논리식 연산

>>> 3<5
True
>>> 27<14
False
>>> 3.14!=3.14
False
>>> 3.14>=3.14
  • 문자열에서 사용
>>> "Cheong"<"Choe"
True
  • Cheong / Choe의 비교
    • Che → Cho 두 문자중 e가 o보다 사전순서가 빠르기 떄문에 cheong은 choe보다 작은 값이 된다

      "a"<"b"
      True
  • “”를 사용한 숫자와 그냥 숫자는 다름
    "3" == 3
    False
    “”를 사용시 텍스트로 인식한다.
  • not : true와 false의 값을 바꾼다
    >>> (not True)==False
    True
    >>> (not False)==True
    True
  • and : 왼쪽과 오른쪽 둘다 참이어야 true
    >>> (False and False)==False
    True
    >>> (False and True)==False
    True
    >>> (True and True)==True
    True
    >>> (True and False)==False
    True
  • or : 왼쪽과 오른쪽 값중 하나만 참이여도 true
    >>> (False or False)==False
    True
    >>> (False or True)==True
    True
    >>> (True or False)==True
    True
    >>> (True or True)==True
    True

논리 연산자의 계산방식

or의 경우 왼쪽의 값만 맞으면 출력되기에 파이썬은 오른쪽 값을 아예 계산하지 않는다

and의 경우에도 왼쪽이 false일때 무조건 false의 결과가 계산되기에 오른쪽의 계산 결과가 나오지 않는다

>>> a = 10 #1
>>> def f() : #2
	global a
	a=0
	return True

>>> True or f() #3
True
>>> print(a) #4
10
  1. a를 10이라고 정의했따
  2. f를 a값을 불러와 a=0이라고 정의한뒤 True를 출력하도록 정의했다
  3. True or f() True혹은 f()가 True인지 물었다, 왼쪽값이 True이니 True를 출력했다
  4. 함수 f()를 실행하지 않고 True만 읽어서 결과값을 출력하였으니 f()에서 정의한 값을 계산하지 않고 맨 처음에 입력한 a의 값이 출력된다.
>>> False and f()
False
>>> print(a)
10

>>> True and f()
True
>>> print(a)
0
  • and값으로 계산하면 false일 경우 f()를 계산하지 않아 a는 10이 된다
  • Ture의 경우 f()를 계산하기에 a의 값이 f()에서 정의한 값으로 출력된다.

Tuple

  • 가장 간단한 자료 구조 중에 하나
  • 다른 객체들을 포함하는 객체
>>> position = (3.14,-5,7.5)
>>> profs=("in-Yong Ko","Sunghee choi","Lee YoungHee","Duksan Ryu","Key-Sun Choi")

>>> print(position, type(position)) #position이 정의된 값과 position의 타입을 출력한다
(3.14, -5, 7.5) <class 'tuple'>

튜플의 값은 풀고 다시 묶을수 있다.

>>> x,y,z=position #position = (3.14,-5,7.5)이다
>>> print(x)
3.14
>>> print(y)
-5
>>> print(z)
7.5

정의된 값의 숫자만큼 좌변에 값을 넣어주면 그 값대로 정의된다

>>> a,b=("aa","bb") #a=aa b=bb
>>> a,b=b,a # a는 b의 값으로 b는 a의 값으로 재 정의된다 a=bb, b=aa
>>> print(b)
aa

튜플을 사용한 디지털 사진 변환 예제

  • 파이선은 빨간색, 초록색, 파란색으로 색상을 파악한다
red = (255, 0, 0)

blue = (0, 0, 255)

white = (255, 255, 255)

black = (0, 0, 0)

yellow = (255, 255, 0)

purple = (128, 0, 128)

색을 명사로 정의해준다

from cs1media import * # 이 외부 프로그램을 불러온다
img = create_picture(100, 100, purple) #img는 100 100의 픽셀을 가진 보라색 그림이다
img.show() #100 100의 보라색 이미지가 출력된다
img.set_pixels(yellow) #이미지의 색상을 노란색으로 다시 세팅한다
img.show() #이미지가 노란색이 되었다,

for반복문

>>> for i in range(7) :
	print("*" * i)

	

*
**
***
****
*****
******
  • *을 7번 반복시킨다
  • *은 i(반복 횟수만큼 반복된다)
  • 첫 i값은 0이기에 첫줄에는 *이 출력되지 않는다.
    >>> for i in range(4) :
    	print(i)
    
    	
    0
    1
    2
    3
    • 이 값에서 확인할수 있듯 i는 0부터 시작해서 range값 -1까지임을 알수있다.

이미지 반전

from cs1media import *

img = load_picture("../photos/geowi.jpg")
w, h = img.size() #1
for y in range(h): #2
    for x in range(w): #3
        r, g, b = img.get(x, y) #4
        r, g, b = 255 - r, 255 - g, 255 - b #5
        img.set(x, y, (r, g, b)) #6
img.show()
  1. geowi.jpg의 이미지 크기의 가로 값이 w 세로값이 h가 된다.
  2. for문으로 반복된다, 세로값 만큼
  3. for문으로 반복된다 가로값만큼
  4. 각각의 픽셀의 rgb값을 가지고 온다.
  5. rgb의 값을 최댓값 255에서 그 만큼을 뺀다 (그러면 반대 색상으로 반전된다)
  6. 이미지를 셋팅한다 x=가로값 y=세로값의 바뀐rgb값으로 xy가 픽셀의 1.1부터 픽셀의 위치를 나타나기에 픽셀 하나 하나 변경된다

이미지의 반전

  • 이것은 그림이 고유값 X,Y r,g,b값을 픽셀마다 가지고 있기 때문이다.
  • 위의 코드는 XY rgb (픽셀좌,픽셀우) (그림고유색상)을 변경하는 코드인것이다.

매개 변수와 반환값을 가진 함수

  • def : defin의 줄임말 정의한다는 뜻
import math

sin = math.sin
pi = math.pi
radians = degrees / 360.0 * 2 * pi

print(sin(radians))

math.sin같은 함수를 sin으로 정의하여 간단하게 사용할 수도 있다.

Math모듈

수학함수를 사용할때는 import math로 모듈을 불러와 사용할수있다.

함수인자

def computue_interset(amount,rate,years) :
	value=amount*(1+rate/100)**years
	return value
  • amount,rate,years : 매개변수
    • 함수 내부에서 매개 변수는 다른 변수와 동일하게 사용

여러 반환문을 가진 함수

def absolute(x):
    if x < 0:
        return -x
    else:
        return x

x가 음수이면 -x 양수이면 x값을 리턴하는 여러반환문을 가질수있다

value값은 하나다

def absolute(x):
    if x < 0:
        return –x
    return x

더 간단하게 x가 음수일때 -x를 return하고 if의 값이 틀릴때는 바로 x를 return하는 더 간단한 함수를 쓸수도 있다.

하지만 중간에 새로운 if식을 넣은 return을 쓰면 안된다

조건함수

논리값 turu나 false를 반환하는 함수

# is integer a divisible by b?
def is_divisible(a, b):
    if a % b == 0:
        return True
    else:
        return False
  • a/b의 나머지값이 없을때는 true 나머지값이 있으면 false를 retrun한다
def is_divisible(a, b):
    return a % b == 0
  • 간단하게 이렇게 정의할수도 있다
  • return한 a/b의 값이 0일때만 return이 true라고 인식하기때문에 위와 아래는 같은 함수이다
>>> def is_divisible(a, b):
    if a % b == 0:
        return True
    else:
        return False

>>> is_divisible(10, 2)
True
>>> def is_divisible1(a, b):
    return a % b == 0

>>> is_divisible1(10,2)
True
>>>

같은값이 출력됨을 확인할수있다

결과값이 없는 함수

def turn_right():
     for i in range(3):  
         hubo.turn_left()
  • return value를 선언하지 않았기때문에 결과값이 없다
  • 이럴떄는 none이라는 함수를 자동반환한다

여러값 반환하기

def student():
    name = "Hong, Gildong"  
    id = 20101234
    return name, id

이 경우 student안에는 name과 id의 값이 동시에 정의되게 한다

이때 student안에 있는 두 값을 분리 시켜주기 위해서는

name,id =student()

라고 다시 나누어줄 필요가 있다. student안에 들어있는 2개의 값을 튜플로 나누어저 각각 하나의 정보씩 담기게 된다.

예제

>>> def f() :
	x=10
	y=20
	return (x,y)

>>> print (f())
(10, 20)

>>> print (x)
Traceback (most recent call last):
  File "<pyshell#59>", line 1, in <module>
    print (x)
NameError: name 'x' is not defined
>>> print (y)
Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    print (y)
NameError: name 'y' is not defined

이때 f ()는 x,y 두 값을 소유하게 되지만 x,y는 f()안에만 속한값이 된다

xy의 값을 꺼내고 싶다면

>>> (x,y)=f()
>>> print(x)
10
>>> print(y)
20

튜플을 이용해 f()안의 값으로 정의하면 내가 원하는 하나의 요소씩 나눌수있다

input

메세지를 출력하고 키보드를 통해서 사용자의 문자열의 입력을 받는 함수

>>> name = input("What is your name? ")
What is your name? 가나다 # 이 값이 가나다는 내가 직접 입력한 값이다
>>> print("Welcome to CS101, " + name)
Welcome to CS101, 가나다

문자열만 반환한다 숫자 입력이 필요한 경우 변환이 필요하다

raw_n = input("Enter a positive integer> ") #1
n = int(raw_n) #2
for i in range(n):  #3
    print("*" * i) #4
  1. 문자열은 출력만 될뿐 중요하지 않다 raw_n이란 값은 내가 지금 입력한 값으로 정의된다.
  2. int(값)으로 내가 입력한 숫자를 문자열이 아니라 숫자로 인식하게 하는 함수이다.
  3. 숫자로 재 인식한 값만큼 반복하는 함수이다
  4. *을 내가 입력한 숫자만큼 1부터 n까지 반복한다

출력값 (15를 입력했을때)

*
**
***
****
*****
******
*******
********
*********
**********
***********
************
*************
**************

예제

>>> name=input("이름을 적어주세요")
이름을 적어주세요가나다
>>> print(name)
가나다

내가 input한 값이 정의한 name이 되는것을 알수있다.

>>> raw_n=input("숫자를 입력하세요>")
숫자를 입력하세요>25
>>> print(raw_n)
25
>>> type(raw_n)
<class 'str'>
>>> n=int(raw_n)
>>> type(n)
<class 'int'>

내가 입력한 숫자가 raw_n으로 정의되고 그 타입이 str텍스트 인것을 알수있다

int()를 이용하면 변환한 함수가 int숫자로 바뀌는것을 볼수있다.

함수를 사용한 로봇 조종 및 디지털 사진 변환 프로그램

  • 로봇이 beeper를 전부 먹는 프로그램을 설정한다.
  1. 로봇은 앞으로 5칸 진행한다.

    for i in range(5):
    	hubo.move()
  2. 로봇은 왼쪽으로 돈다

    hubo.turn_left()
  3. 로봇은 앞으로 한칸 진행한다

    hubo.move()
  4. 비퍼를 줍는다. 로봇은 오른쪽으로 돌아 한칸 왼쪽으로 돌아 한칸 진행한다

    def mov4():
    	hubo.pick_beeper()
    	turn_right()
     hubo.move()
    	hubo.turn_left()
    	hubo.move()
  5. 4를 5번 반복한다.

    for i in range5):
    	mov4()
  6. 비퍼를 줍는다. 로봇은 앞으로 한칸 왼쪽으로 돌아 한칸 진행하고 다시 오른쪽으로 돈다.

    def mov6():
    	hubo.pick_beeper()
    	hubo.move()
    	hubo.turn_left()
    	hubo.move()
    	turn_right()
  7. 로봇은 6을 5번 반복한다.

    for i in range(5):
    	mov6()
  8. 로봇은 왼쪽으로 돈다

    hubo.turn_left()
  9. 로봇은 6을 5번 반복한다.

    for i in range(5):
    	mov6()
  10. 로봇은 왼쪽으로 돈다.

    hubo.turn_left()
  11. 로봇은 6을 5번 반복한다.

    for i in range(5):
    	mov6()

11번까지 완료하면 이런상황이 된다.

  1. 로봇은 반바퀴를 돈다.

    def turn():
    	turn_right()
    	turn_right()
    
    turn()
  2. 로봇은 앞으로 두칸 이동한다. 오른쪽으로 돈다

    >>> hubo.move()
    >>> hubo.move()
    >>> turn_right()
  3. 6을 3번반복한다.

    for i in range(3):
    	mov6()
  4. 왼쪽으로 돈다.

    hubo.turn_left()
  5. 6을 3번반복한다.

    for i in range(3):
    	mov6()
  6. 왼쪽으로 돈다.

    hubo.turn_left()
  7. 6을 3번 반복한다.

    for i in range(3):
    	mov6()
  8. 왼쪽으로 돈다.

    hubo.turn_left()
  9. 6을 3번 반복한다.

    hubo.turn_left()

20번까지 입력한 경우 이런결과가 된다.

  1. 반바퀴 회전한다

    turn()
  2. 앞으로 2칸 전진한다.

    >>> hubo.move()
    >>> hubo.move()
  3. 오른쪽으로 돈다

    turn_right()
  4. 6을 1번 반복한다. 왼쪽으로 돈다.

    def mov24():
    	mov6()
    	hubo.turn_left()
  5. 24를 3번 반복한다.

    for i in range(3):
    	move24()
  6. 비퍼를 줍는다

    hubo.pick_beeper()

    예시로 나온 코드

    def stairs(robot, n):
      for i in range(n):
        robot.pick_beeper()
        robot.move()
        turn_right(robot)
        robot.move()
        robot.turn_left()
    • 계단을 하나 오르는 코드이다 n 만큼 반복한다
      • 5만큼 반복하면 가장 외부의 비퍼를 한줄 가지게 된다.

      • 모서리에서 robot.turn_left()를 선언하면 다음줄의 비퍼를 한줄 가질수 있다.

      • 이것을 4번 반복하면 외부의 다이아몬드모양 비퍼를 전부 가질수있다.

        def diamond(robot, n):
          for i in range(4):
            stairs(robot, n)
            robot.turn_left()
      • 이것을 하나로 정의하면 이렇게 된다.

      • 이 코드를 3번 반복하면 다이아몬드 모양의 비퍼 3개를 전부 가질수 있다.

        def harvest_all(robot):
          for i in range(3):
            n = 5 - 2 * i
            diamond(robot, n)
            hubo.move()
            hubo.move()
      • n은 i가 처음반복할때는 0이 되어 5번을 반복한다 stairs가 5번 반복되기 때문에 가장 외부의 큰 피버 5개 한줄을 가지게 된다.

      • diamond안에 stairs는 4번 반복하기때문에 가장 큰 외부 다이아몬드 1번의 비퍼를 전부 가지게 된다.

      • move()가 2번선언되었기때문에 다음 다이아몬드로 이동하게 된다

      • n은 i가 두번째 반복할때 1이되어 3번을 반복한다, 다음줄의 비퍼 4개 한줄을 가지게 되고 dimond안에서 4번 반복되어 다이아몬드 하나를 전부 가지게된다

      • move()두번으로 안쪽 다이아몬드로 진입하고 마지막으로 작은 다이아몬드 한면 3개씩 4번을 반복하여 전부 가지게 된다.

        사진변환

        def luma(p):
            r, g, b = p
            return int(0.213 * r + 0.715 * g + 0.072 * b)
        
        white = (255, 255, 255)
        black = (0, 0, 0)
        
        def blackwhite(img, threshold):
            w, h = img.size()
            for y in range(h):
                for x in range(w):
                    v = luma(img.get(x, y))
                    if v > threshold:  
                        img.set(x, y, white)
                    else:
                        img.set(x, y, black)
        
        pict = load_picture("../photos/yuna1.jpg")  
        blackwhite(pict, 100)
        pict.show()

        p값에 rgb 세 값을 입력하고 공식에 따라 흑백으로 출력한다

함수 인자와 매개 변수

def swap(a, b):
    a, b = b, a     #1
>>> x, y = 123, 456 #2
>>> swap(x, y)#3
>>> print (x, y)#4
123 456
  1. ab와 ba값을 바꾸는 함수를 선언하였다.
  2. xy의 값을 정의하였따
  3. xy를 swap으로 선언하여다
  4. print를 했을때 xy의 값은 서로 바뀌지 않는다 왜냐하면 함수 안에서의 일은 함수 안에서만 끝나기때문에 외부에서는 끝날수 없다
def f1(x, y=0):    # 옳은 함수 정의
   return x+y

Def f2(x=0, y):    # 틀린 함수 정의
   return x+y

기본값을 가진 변수는 반드시 뒤에 와야 한다

x에 기본값 0을 부여하려면 절대 먼저 정의 되어서는 안된다

def avg(data, start = 0, end = None):
    if not end: # (not None)==True, (not 4)==False
        end = len(data)
    return sum(data[start:end]) / float(end-start)

평균을 구하는 함수이다.

if not end : end의 값이 선언되었을때는 참 선언되지 않았을때는 거짓으로 인식한다

  • 0을 제외한 모든 숫자가 true이다

  • end=none end값에 아무것도 입력하지 않았을때 혹은 0일때

  • end=data의 갯수이다 (1,13,47,9 일때는 4)

    sum(data[start:end]) / float(end-start) :

  • 데이터의 처음부터 마지막 모든 수를 더한값 =sum

d=(3,4,5,6,7)
d[0:5]
(3, 4, 5, 6, 7)
  • 데이터의 갯수에서 stat로 정한 처음으로 지정한 숫자를 뺀 값을 나누면 평균이 된다,
>>> d=(3,4,5,6,7)
>>> avg(d,1,4)
5.0
>>> avg(d,2)
6.0
>>> avg(d)
5.0

d=34567 5개의 값이다

avg(d,1,4) : 4,5,6값만을 불러와 평균으로 낸다 (end가 지정된 숫자는 제외한다 첫 숫자는 0을 선언해야 한다)(마지막 숫자는 end+1d을 해줘야 선택됨)

avg(d,2) : 5,6,7의 평균을 구한다, end값이 선언되지 않았을때는 마지막 숫자를 선택한다

avg(d) : start의 기본값은 0이기때문에 처음부터 마지막까지의 평균을 구한다

함수가 사용하는 지역 변수와 전역 변수

def quadratic(a, b, c, x):
    quad_term = a * x ** 2
    lin_term = b * x
    return quad_term + lin_term + c

quad_term , lin_term : 함수 안에서만 사용할수 있는 변수 지역변수라고 한다

  • 전역변수
    • 함수 안밖 어디서나 사용할수 있는 변수

    • 함수안에서 값이 읽어지기만 하는 변수

      def f1():
          return 3 * a + 5

      f1안에서는 a의 값을 읽지만 a의 값을 변경하지 않는다

      a는 읽기만 하기때문에 읽어지기만 하기에 전역 변수이다.

      def f2(x):
          a = 3 * x + 17
          return a * 3 + 5 * a
  • x는 읽기만 하지만 파라메터 이기때문에 지역변수이다
  • a는 안에서 값이 다시 쓰여지기때문에 지역변수이다
a = 17
def test():  
    print(a)  
    a = 13
    print(a)
test()

a가 함수 안 밖에서 두번에 읽어지기때문에 에러가 나타난다

전역변수 업데이트 하기

hubo = Robot()
hubo_direction = 0 #전역변수

def turn_left():  
    hubo.turn_left()  
    global hubo_direction
    hubo_direction += 90

def turn_right():
    for i in range(3):  
        hubo.turn_left()
    global hubo_direction
    hubo_direction -= 90
  • global : 이 명령어를 이용하면 함수안에서 전역변수를 업데이트 할수 있다
a = "Letter a" #전역변수 a

def f(a):  # 함수 f에서만 쓰이는 매개변수 a
    print("A = ", a)

def g(): 
    a = 7  #함수 g에서만 쓰이는 지역변수 a
    f(a + 1)
    print("A = ", a) 

print("A = ", a) #: A=Letter a, 전역변수 a의 값만 출력됨
f(3.14) # A=3.14 f안의 a만 출력
print("A = ", a)#: A=Letter a, 전역변수 a의 값만 출력됨
g() #A=8 A=7 g()함수 안에서 정의된 a만 출력 안에 f()도 있었기에 그 값도 출력된다
print("A = ", a) #: A=Letter a, 전역변수 a의 값만 출력됨

모듈과 그래픽 객체들

  • math 모듈 :sin cos pi tan 등 수학함수
  • random 모듈 : 난수 무작위 섞기 등의 함수들을 제공
  • sys, os : 운영체제와 관련된 함수
  • urllib : 인터넷 관련
  • cl1robots : 휴보에 관련된 함수
  • cs1graphics : 그래픽과 관련된 함수
  • cs1media : 사진을 처리하는 함수

이 함수들 앞에 help를 붙어 help(”cs1graiphics”)같이 입력하면 정보를 볼수있다.

앞에 import urllib같이 불러와 사용한다 import대신 from math improt *을 쓸수도 있다

  • from을 사용했을때는 import로 불러왔을때 와는 달리 불러온 함수 math.pi 같이 앞에 표기하면 오히려 파이선 안에서 인식할수 없다 from을 사용했을때는 pi처럼 앞에 함수를 빼고 사용해야 한다.
>>> from math import *
>>> print(pi) #pi는 정상적으로 인식한다.
3.141592653589793
>>> print(math.pi) #math.pi는 인식하지 못한다
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    print(math.pi)
NameError: name 'math' is not defined
  • 하나의 함수만 가지고 올수도있다
    • from 함수 import 필요한소속함수 : 이렇게 입력한다면 소속함수 하나만 불러오는 것이다.

      >>> from math import sin #math함수 안에 sin만 사용한다
      >>> print (sin(3.14)) #sin을 인식해 값을 출력한다
      0.0015926529164868282
      >>> pirnt (pi) #pi는 인식하지 못한다
      Traceback (most recent call last):
        File "<pyshell#12>", line 1, in <module>
          pirnt (pi)
      NameError: name 'pirnt' is not defined
      >>> print(math.pi) #math를 붙여도 sin만 불러왔기때문에 인식하지 못한다.
      Traceback (most recent call last):
        File "<pyshell#13>", line 1, in <module>
          print(math.pi)
      NameError: name 'math' is not defined

from으로 모든 함수를 불러오는것은 매우 편하지만, 2가지 이상의 함수를 불러올경우 프로그램안에서 어떤함수를 사용하려는건지 충돌할수 있으니 from으로 모든 함수를 불러오는것은 지양해야 한다.

캔버스 만들기

from cs1graphics import * #모듈 불러오기

canvas = Canvas(400, 300) #캔버스 생성,크기지정
canvas.setBackgroundColor("light blue") #바탕색 지정
canvas.setTitle("CS101 Drawing exercise") #타이틀 지정

그래픽 객체

그래픽 객체를 캔버스에 추가하는 방식으로 캔버스에 그림을 그릴 수 있습니다.

  • 원: Circle(radius)

* 정사각형: Square(side)

* 직사각형: Rectangle(width, height)

* 다각형: Polygon

* 선: Path

* 글자: Text(message, font_size)

* 이미지: (image_filename)

obj.setBorderColor(color): 이미지 선 컬러 지정하기

obj.getBorderColor(): 이미지 선 컬러 확인하기

obj.setFillColor(color) : 이미지 바탕 컬러 지정하기

obj.getFillColor() :이미지 컬러 확인하기

>>> sq=Square(100) #박스 크기를 지정하고 sq라는 이름으로 정의한다(정사각형)
>>> canvas.add(sq) # 캔버스에 박스을 추가한다
>>> sq.setFillColor("blue") #바탕색은 파랑이다
>>> sq.setBorderColor("red") #선색은 빨강이다
>>> sq.setBorderWidth(5) #선의 넓이는 5이다
>>> sq.moveTo(200,200) #위치는 200,200이다

>>> import time #time함수를 불러온다
>>> 
>>> for i in range(100): #100번 반복한다
	sq.move(1,0) #상자가 x축으로 1 이동한다
	time.sleep(0.1) #속도를 0.1로 지정한다 
>>> r=Rectangle(150,75) #직사각형의 크기를 지정하고 r이라 정의한다
>>> canvas.add(r) #캔버스에 추가한다
>>> r.setFillColor("yellow") #바탕색은 노랑이다
>>> r.moveTo(280,150) #좌표로 움직인다

깊이

>>> sq.setDepth(10) #sq의 깊이는 10이다
>>> r.setDepth(20) #r의 깊이는 20이다

깊이가 더 깊은 쪽이 뒤로간다

회전

sq.rotate(45) #45도 만큼 회전한다

크기

>>> sq.scale(1.5) #크기가 1.5배가 된다
>>> r.scale(0.5) #크기가 0.5배가 된다

for i in range(80):
	sq.scale(0.95)
	time.sleep(0.1)

	
canvas.remove(sq)

이런식으로 명령하면 sq를 점점 작게하여 사라지는 애니메이션을 작성할수있다.

레이어

car = Layer() #car라는 레이어를 만든다
tire1 = Circle(10, Point(-20,-10)) #tire1은 10크기의 원 위치는 -20 -10
tire1.setFillColor('black') #색은 검정
car.add(tire1) #car레이어에 tire1을 추가한다
tire2 = Circle(10, Point(20,-10)) #원크기는 10 위치는 20 -10
tire2.setFillColor('black') #색은 검정
car.add(tire2) #car레이어에 추가한다
body = Rectangle(70, 30, Point(0, -25)) #body는 70,30크기에 직사각형 위치는 0,-25
body.setFillColor('blue') #색은 파랑
body.setDepth(60) #깊이는 60
car.add(body) #car레이어에 추가한다

애니메이션

for i in range(50):
  car.move(2, 0)
for i in range(22):
  car.rotate(-1)
for i in range(50):
  car.move(2,-1)
for i in range(22):
  car.rotate(1)
for i in range(50):
  car.move(2,0)
for i in range(10):
  car.scale(1.05)
  • car라는 레이어에 속한 도형들이 한꺼번에 움직인다
  • 반복문으로 움직임을 반복하여 애니메이션 효과를 준다.

list

countries = [ "Australia", "Austria", "Belarus", "Canada",
              "China", "Croatia", "Czech Republic", "Estonia",
              "Finland", "France", "Germany", "Great Britain",
              "Italy", "Japan", "Kazakhstan", "Korea", "Latvia",
              "Netherlands", "Norway", "Poland", "Russian Federation",
              "Slovakia", "Slovenia", "Sweden", "Switzerland",
              "United States" ]

contries라는 목록에 데이터 값을 담을수 있다.

>>> countries[0]
'Australia'
>>> countries[20]
'Russian Federation'

최초번호는 0으로 시작되며 순서에 따라 숫자를 입력하면 출력된다.

>>> Korea=['korea','kr',3,3,2]
>>> len(Korea)
5
>>> max(gold)
14
>>> sum(gold)
86
>>> min(gold)
0
  • len : 리스트에 길이, 리스트 속에 몇개의 값이 있는지
  • sum:리스트 속 원소의 합
  • max:리스트에서 가장 큰원소
  • min:리스트에서 가장 작은 원소
countries[-2]
'Switzerland'
countries[26-2] #26은 len(countires로 나온 요소의 갯수이다)
'Switzerland'

여기서 -2는 끝에서 두번째 요소를 뜻한다 요소의 갯수-값과 동일하다

>>> aba=["a","b","c",(1,2,3)]
>>> aba[3]
(1, 2, 3)
  • 요소를 튜플로 넣었을시 3번째 요소는(0부터 시작하기에 4번째를 뜻한다) 튜플로 구성된 요소 전체가 된다.

리스트를 넣고 빼기

>>> aba[1]="d"
>>> print(aba)
['a', 'd', 'c', (1, 2, 3)]
  • 리스트이름[순서]=바꾸고자 하는 값을 넣으면 그 순서의 값이 변경된다
>>> aba.append('apple')
>>> aba
['a', 'd', 'c', (1, 2, 3), 'apple']
  • 리스트이름.append(추가하고자하는요소)를 넣으면 마지막에 추가된다
>>> add=aba
>>> add.append('apple1')
>>> aba
['a', 'd', 'c', (1, 2, 3), 'apple', 'apple1']
  • 두가지의 목록의 이름을 넣을수 있다. 중요한건 이미 생성된 이름이 오른쪽으로 가야 한다는것이다
    • 내가 만들고자 하는 이름 = 이미 생성된 리스트의 이름
  • 살펴보면 add에 추가한 요소가 aba에도 추가됨을 확인할수 있다

리스트 탐색하기

for country in countries:
	print(country)

	
Australia
Austria
Belarus
Canada
China
Croatia
Czech Republic
Estonia
Finland
France
Germany
Great Britain
Italy
Japan
Kazakhstan
Korea
Latvia
Netherlands
Norway
Poland
Russian Federation
Slovakia
Slovenia
Sweden
Switzerland
United States
  • for를 이용해 리스트를 출력할수있다.

range타입으로 리스트 작성하기

>>> totals=[] #1
>>> for i in range(len(countries)): #2
	medals=gold[i]+silver[i]+bronze[i] #3
	totals.append((medals,countries[i])) #4

	
>>> totals #5
[(3, 'Australia'), (16, 'Austria'), (3, 'Belarus'), (26, 'Canada'), (11, 'China'), (3, 'Croatia'), (6, 'Czech Republic'), (1, 'Estonia'), (5, 'Finland'), (11, 'France'), (30, 'Germany'), (1, 'Great Britain'), (5, 'Italy'), (5, 'Japan'), (1, 'Kazakhstan'), (14, 'Korea'), (2, 'Latvia'), (8, 'Netherlands'), (23, 'Norway'), (6, 'Poland'), (15, 'Russian Federation'), (3, 'Slovakia'), (3, 'Slovenia'), (11, 'Sweden'), (9, 'Switzerland'), (37, 'United States')]
  1. total이라는 빈 리스트를 만든다
  2. 반복한다 countries의 요소의 수만큼
  3. medals의 값은 gold+silver+boronze의 각각 반복한 i의 값이다 i는 0 부터 반복한다 (각 나라마다 매달의 합이다)
  4. totals에 medals의 값을 counties와 묶어 튜플로 리스트화 시킨다
  5. totals의 값을 출력한다.
>>> for c in countries[-5:]: #1
	print (c)

	
Slovakia
Slovenia
Sweden
Switzerland
United States
>>> list(range(5)) #2
[0, 1, 2, 3, 4]
>>> list(range(3,8))#3
[3, 4, 5, 6, 7]
  1. countries의 뒤에서 5번째부터 마지막까지 출력한다 (-5: )
  2. range(5)=0부터 5를 뜻하며 그 값을 list한다
  3. range(a,b) a순서부터 b순서 -1까지 리스트화한다 (0부터 시작하기에 a+1순서부터 b까지이다)
for i in range(21,26):
	print(gold[i])

	
1
0
5
6
9
  • range(21,26)는 21번째부터 25번째까지를 뜻하기때문에 i의 값은 21~25가 된다
  • gold[21]~gold[25]의 리스트 값을 출력한다.

sort

사전순서대로 내용값을 정리해준다.

>>> countries.sort()
>>> countries
['Australia', 'Austria', 'Belarus', 'Canada', 'China', 'Croatia', 'Czech Republic', 'Estonia', 'Finland', 'France', 'Germany', 'Great Britain', 'Italy', 'Japan', 'Kazakhstan', 'Korea', 'Latvia', 'Netherlands', 'Norway', 'Poland', 'Russian Federation', 'Slovakia', 'Slovenia', 'Sweden', 'Switzerland', 'United States']
>>> totals.sort()
>>> totals
[(1, 'Estonia'), (1, 'Great Britain'), (1, 'Kazakhstan'), (2, 'Latvia'), (3, 'Australia'), (3, 'Belarus'), (3, 'Croatia'), (3, 'Slovakia'), (3, 'Slovenia'), (5, 'Finland'), (5, 'Italy'), (5, 'Japan'), (6, 'Czech Republic'), (6, 'Poland'), (8, 'Netherlands'), (9, 'Switzerland'), (11, 'China'), (11, 'France'), (11, 'Sweden'), (14, 'Korea'), (15, 'Russian Federation'), (16, 'Austria'), (23, 'Norway'), (26, 'Canada'), (30, 'Germany'), (37, 'United States')]

숫자 값이 먼저 정의되어있기에 숫자 순으로 정렬하고 숫자가 같으면 사전순으로 정렬한다

슬라이싱

  • sublist=mylist[i:j] : sublist는 mylist의 i부터 j-1번까지의 요소를 갖는다
    • i를 생략하면 첫번째부터 j-1까지
    • j를 생략하면 i부터 마짐ㄱ까지
    • 모두 생략하면 전체 리스트
    • 목록은 무조건 0부터 시작한다!! 기억할것!
>>> totals.reverse()
>>> totals
[(37, 'United States'), (30, 'Germany'), (26, 'Canada'), (23, 'Norway'), (16, 'Austria'), (15, 'Russian Federation'), (14, 'Korea'), (11, 'Sweden'), (11, 'France'), (11, 'China'), (9, 'Switzerland'), (8, 'Netherlands'), (6, 'Poland'), (6, 'Czech Republic'), (5, 'Japan'), (5, 'Italy'), (5, 'Finland'), (3, 'Slovenia'), (3, 'Slovakia'), (3, 'Croatia'), (3, 'Belarus'), (3, 'Australia'), (2, 'Latvia'), (1, 'Kazakhstan'), (1, 'Great Britain'), (1, 'Estonia')]

리스트.revers()를 쓰면 내림차순으로 정렬된다

>>> country=countries
>>> top_ten=totals[:10]#1
>>> for p in top_ten: #2
	medals,country=p #3
	print(medals,country)

	
37 United States
30 Germany
26 Canada
23 Norway
16 Austria
15 Russian Federation
14 Korea
11 Sweden
11 France
11 China
  1. top_ten리스트는 totals에 0~9까지의 값이다
  2. p의 숫자만큼 top_ten[p]를반복한다
  3. medals,contry=top_ten[p]이다, 그 값을 출력한다
for medals, country in top_ten: #1
	print(medals,country)

	
37 United States
30 Germany
26 Canada
23 Norway
16 Austria
15 Russian Federation
14 Korea
11 Sweden
11 France
11 China

같은 코드를 이렇게 표현할수도 있다.

  1. medals,country=top_ten이며 top_ten이 끝날때까지 반복한다.
table=[] #1
for i in range(len(countries)): #2
	table.append((gold[i],silver[i],bronze[i],countries[i])) #3
table.sort() #4 
top_ten=table[-10:]#5 
top_ten.reverse() #6 
for g,s,b,country in top_ten:#7
	print(country,g,s,b) 
	
Canada 14 7 5
Germany 10 13 7
United States 9 15 13
Norway 9 8 6
Korea 6 6 2
Switzerland 6 0 3
Sweden 5 2 4
China 5 2 4
Austria 4 6 6
Netherlands 4 1 3
  1. table이라는 빈 리스트를 작성한다
  2. 반복한다 countries의 요소 수만큼
  3. talbe리스트에 추가한다 (gold,silver,bronze,countries를 각각 0부터 countries의 요소수-1 까지)
  4. table을 오름차순으로 정렬한다
  5. table의 마지막 10개부터 끝까지 top_ten리스트에 작성한다
  6. top_ten리스트를 내림차순으로 정렬한다.
  7. g,s,b,country = top_ten의 리스트 값과 같다.
    1. top_ten[0] = 14,7,5,Canada이다 g=14, s=7,b=5,country=canada이다
    2. 이 값을 country,g,s,b 순서대로 정렬하여 프린트한다
def no_medals(countries, al, bl): #1
    result = [] #2
    for i in range(len(countries)): #3
        if al[i] == 0 and bl[i] == 0: #4
            result.append(countries[i]) #5
    return result #6

only_gold = no_medals(countries, silver, bronze) #7
only_silver = no_medals(countries, gold, bronze) #8
only_bronze = no_medals(countries, gold, silver) #9
only_one = only_gold + only_silver + only_bronze #10
  1. no_medals의 값은 (countries,al,bl)의 값으로 이루어진다.

  2. result라는 빈 리스트를 만든다

  3. countries의 요소 수 만큼 반복한다.

  4. al의 값이 0이 되고 bl의 값이 0이 될때

  5. result안에 countries의 리스트에 반복된 숫자의 나라를 등록한다. (al과 bl의 값이 0인 나라가 리스트에 들어간다)

  6. result값으로 리턴한다.

  7. only_gold는 no_medals에서 나라이름,silver값 bronze값이다.

    1. no_medals(countries, al, bl)였기떄문에 silver=al, bronze=bl이다
    2. countries[0]=Australia, silver[0]= 1, bronze[0]=0이다
    3. al과 bl이 값이 둘다 0이 아니기때문에 result안에 들어가지 않는다.
  8. 마찬가지로 이번엔 gold, bronze의 값이 0인 곳만 result안에 입력한다

  9. 마찬가지로 이번엔 gold, silver이 값이 0인곳만 result안에 입력한다.

  10. 위 세 값(result리스트에 입력된 나라)를 합치면 딱 한개의 메달을 받은 result 리스트만 남게된다.

    print(only_one)
    ['Great Britain', 'Estonia', 'Kazakhstan', 'Latvia']
    • result는 def안에서만 입력된 리스트이기때문이 지역변수이다 함수밖에서는 사용할수 없다
  • L.append(v) v 객체를 리스트 끝에 추가
  • L.insert(i, v) 객체를 리스트의 i번째 위치에 추가
  • L.pop() 리스트의 마지막 원소를 삭제하고, 그 값을 반환
  • L.pop(i) i번째 원소를 삭제하고, 그 값을 반환
  • L.remove(v) v와 일치하는 첫 번째 원소를 삭제
    • 내용이 중복일때 v값과 같은 첫번째 원소를 삭제
  • L.index(v) v와 일치하는 첫 번째 원소의 위치를 반환
  • L.count(v) v와 일치하는 원소들의 개수를 반환
  • L.extend(K) K의 모든 원소를 리스트 L 끝에 추가
    • 두개의 리스트를 합친다 L과 K가 합쳐지며 K는 L의 요소 두에 추가된다
  • L.reverse() 리스트의 모든 원소를 역순으로 재배열
  • L.sort() 리스트 정렬

시퀀스

>>> a="CS101"
>>> a[-1] #a의 마지막
'1'
>>> a[2:] #a의 3번째부터 끝까지
'101'
>>> for i in a: #a를 0부터 순서대로 출력
	print(i)

	
C
S
1
0
1
>>> t=("CS101","A+",13)
>>> t[0] #t의 첫번째
'CS101'
>>> t[-1] #t의 마지막
13
>>> t[1:] #t의 두번쨰부터 끝까지
('A+', 13)
>>> for i in t: #t를 0부터 끝까지 출력
	print (i)

	
CS101
A+
13

리스트 튜플 문자열은 시퀀스의 한종류로 매우 비슷하게 이용할수 있다

튜플안에 원소는 바꿀수 없다.

튜플,리스트,문자열은 list tuple함수를 이용해 형탤르 바꿀수있따

히스토그램 만들기

def histogram():  
    t = [0] * 13 #1 
    for item in medals: #2
        total = sum(item[1:]) #3
        t[total // 3] += 1 #4
    for i in range(13): #5
        print (str(3*i) + "~" + str(3*i+2)+":\t"+("*"* t[i])) #6
  • medals는 각 나라이름,금메달,은메달,동메달로 이미 정의되어있다.
  1. t의 값은 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 이다,t의 요소수는 13개 라는 뜻이다. 여기서 [0]은 t의 리스트에 입력된값이다 숫자로 인식하지 않는다.

  2. item은 medals의 값의 반복과 같다.

  3. total은 item 두번쨰값부터 끝까지 더한 값이다(나라이름이 빠진다)

  4. t의 목록 숫자는 [total//3](3으로 나누고 나머지를 지운몫)

    1. += : append
    2. t[숫자].append=1이라는 뜻으로 값에 t의 해당 리스트값에 1이 더해진다.
    >>> c=[1,2,3,4]
    >>> c[3]+=1
    >>> c
    [1, 2, 3, 5] #c[3]에 해당하는 4에 1이 더해졌다
  1. 13만큼 반복한다
  • t[0]=( 'Australia', 2, 1, 0 )
  • total=3
  • t[1]=값에+1
    • t=[0,1,0,0…]

.

.

  • t[8]=( 'Estonia', 0, 1, 0 )
  • total=1
  • t[0]=값에+1
    • t=[1,3…]
  1. 문자(3곱하기 i) + 문자~ + 문자 (3곱하기i더하기2)+문자열:+(*을 t의 i값만큼 출력한다)
>>> histogram()
0~2:	****
3~5:	********
6~8:	***
9~11:	****
12~14:	*
15~17:	**
18~20:	
21~23:	*
24~26:	*
27~29:	
30~32:	*
33~35:	
36~38:	*

배열을 크기 순으로 정렬해주는 함수

def bubbleSort(a):
    sorted = False #1
    while(not sorted): #2
        sorted = True #3
        for i in range(1,len(a)): #4
            if(a[i-1] > a[i]): #5
                a[i-1],a[i]=a[i],a[i-1] #6
                sorted = False #7
  1. sorted의 기본값은 false이다
  2. sorted가 false일때 반복한다
  3. sorted를 Ture로 바꾼다
  4. len(a)=a의요소수가 1보다 클때만 반복한다.
  5. 만약 a의 i-1값이 a의 i값보다 크다면
    1. 가 0일때는 -1 배열의 가장 마지막 요소를 뜻한다
  6. a[i-1]의 요소가 a[i]의 요소 순서를 바꾼다
  7. 5가 참일때 sorted를 False로 바꾼다 2로 돌아가 반복한다
    1. 5가 참이 아닐때 sort는 True이기때문에 더이상 반복하지 않는다.

결과

>>> a=[1,9,8,7,5,1]
>>> def bubbleSort(a):
    sorted = False 
    while(not sorted): 
        sorted = True 
        for i in range(1,len(a)): 
            if(a[i-1] > a[i]): 
                a[i-1],a[i]=a[i],a[i-1] 
                sorted = False 

                
>>> bubbleSort(a)
>>> a
[1, 1, 5, 7, 8, 9]

소수 구하기

>>> def sieve(n):
	candidates=list(range(2,n)) #1
	i=0 #2
	while i<len(candidates): #3
		prime=candidates[i] #4
		j=i+1 #5
		while j<len(candidates): #6
			if candidates[j]%prime==0: #7
				candidates.pop(j) #8
			else: #9
				j=j+1
		i=i+1#10
	return candidates #11

>>> sieve(26)
[2, 3, 5, 7, 11, 13, 17, 19, 23]
  1. candidates의 리스트 요소는 2부터 n-1까지의 값이다. (n-1=9일때 [2,3,4,5,6,7,8,9])
  2. i의 기본값은 0 이다
  3. candidates의 요소의 수가 i보다 클때만 반복한다
  4. prime은 candidates의 i번째 요소의 값과 같다
  5. j는 i+1이다
  6. 3이 참일때만 반복한다 j가 candidates의 요수의 수보다 작을때만 반복한다
  7. 만약 candidates의 j번째 요소가 prime으로 나누었을때 나머지 값이 없다면
  8. candidates의 요소중 j번째 요소를 삭제한다 (pop 삭제 함수)
  9. 그렇지 않으면 j=j+1이다, 6으로 돌아간다
  10. 이 값은 1번이 시작되었으면 무조건 실행되야 하는 값이다 i=i+1
  11. candidates의 값으로 리턴한다.

문자열과 집합

포맷연산자

  • %d 10진법 정수
  • %g 실수 print("maximum is %g: % val)처럼 포맷코드를 하나만 사용하는 경우 괄호는 쓰지 않아도 됨
  • %.2f 소수점 자리수가 설정된 실수 (여기는 둘째자리)
  • %s 모든 자료형(문자열등)
>>> (x0,x1,x2)=(1,2,3)
>>> print("%3d~%3d:%10g" % (x0,x1,x2))
  1~  2:         3
  • %3d는 문자당 세칸을 사용하며 우측정렬된다 %10g는 문자당 10칸을 차지하며 우측정렬된다
    • ㅁㅁ1~ㅁㅁ2:ㅁㅁㅁㅁㅁㅁㅁㅁㅁ3 각각 지정된 숫자대로 공간을 차지했다.
print("%-3d~%-3d:%-10g" % (x0,x1,x2))
1  ~2  :3        
  • 포맷연산자 앞에 -를 붙이면 좌측정렬이 된다

  • palindrome 앞뒤 어느쪽으로 읽어도 같은 단어

def is_pailndrome(s):
	for i in range(len(s)): #s의 길이를 파악한다
		if s[i] != s[len(s)-i-1]: #i가 0이면 len(s)-1이 되며 이것은 s의 가장 마지막 숫자를 뜻한다
			return False #위에 if식에 !가 들어갔기때문에 부정형이다 답이 틀리니  false를 출력한다
	return True #위 반복문이 틀려서 반복할수 없을때는 앞뒤가 모두 같은거니 True를 출력한다.
>>> s="tomto"
>>> is_pailndrome(s)
False
>>> a="tommot"
>>> is_pailndrome(a)
True

문자열의 멤버 함수

문자열 객체에서는 다음과 같은 멤버 함수를 사용할 수 있습니다.

  • upper()소문자를 대문자로 바꾼다, lower()대문자로르 소문자로 바꾼다, capitalize()첫 글자를 대문자로 바꾼다

* isalpha()알파멧인지, isdigit()숫자인지

* startswith(prefix)문자열이 prefix로 시작하는가, endswith(suffix)문자열이 suffix로 끝나는가

* find(str1)문자열 안에 str1이 나타나는 첫 위치 반환, find(str1, start)start위치의 인데스 부터 검색, find(str1, start, end)start부터 end-1사이에서 str1을 찾는다

* replace(str1, str2)문자열 치환

* rstrip()오른쪽 공백제거, lstrip()왼쪽공백제거, strip()양옆공백제거

* split()문자열을 공백으로 분리시켜 단어들을 리스트로 생성한다, split(sep)sep를 기준으로 문자열을 나눈다

* join(list1) a.join(b)는 b에 있는 각각의 문자들 사이에 a를 넣는다

여기에서의 값은 직접 문자열을 바꾸는게 아니라 명령한대로 실행한 문자열을 출력한다 문자열의 값은 절대 바뀌지 않는다

문자열은 불가변개체이다 바뀌지 않는다

예제

>>> s="abcdef"
>>> s.upper()
'ABCDEF' #대문자로 바뀐다
>>> s.lower()
'abcdef' #소문자로 바뀐다
>>> s.capitalize()
'Abcdef' #첫 글자만 대문자가 된다
>>> s.isalpha()
True #알파벳이 맞기에 참
>>> s.isdigit()
False #숫자가 아니기에 거짓
>>> s2="1234"
>>> s.startswith("ef")
False #첫 글자에 ef가 들어가지 않아서 거짓
>>> s2.isdigit()
True #숫자가 맞기에 참
>>> s.endswith("ef")
True #마지막 글자에 ef가 들어가서 참
>>> s.replace("de","123")
'abc123f'#de의 값과 123을변경
>>> s="12ab34de"
>>> s.find("ab")
2 #ab는 index2에 있다
>>> s.find("z")
-1 #z는 없다
>>> s.find("ab",4)
-1 #ab는 index4 이후에 없다
>>> s.find("ab",1)
2 #ab는 index1이후에 있으며 그 순서는 2이다
>>> s.find("ab",1,6)
2 #ab는 1부터 6-1까지 사이에 있으며 그 순서는 2이다
>>> s="  abd dfe   "
>>> s.rstrip() #오른쪽공백 제거
'  abd dfe'
>>> s #s의 값은 변하지 않았다
'  abd dfe   '
>>> s.lstrip() # 왼쪽 공백제거
'abd dfe   '
>>> s.strip() #왼쪽오른쪽 공백제거 가운데공백은 제거하지 않음
'abd dfe'
>>> s1=s.strip()
>>> s1
'abd dfe'
>>> s1.split() #s1의 값을 공백을 기준으로 나눔
['abd', 'dfe']
>>> s2="ab cd ef gh"
>>> L2=s2.split() #s2를 공백으로 나눈것을 L2로 정의
>>> L2
['ab', 'cd', 'ef', 'gh']
>>> s3="2019/12/13"
>>> s3.split() 
['2019/12/13'] #공백이 없기에 나눠지지 않는다
>>> s3.split("/")
['2019', '12', '13'] #/를 기준으로 요소가 나눠진다
>>> s1="1234"
>>> s2="abc"
>>> s1.join(s2) #s2사이에 s1의 값이 삽입된다
'a1234b1234c'

집합

  • 집합 안의 원소들 사이 순서는 중요하지 않음
  • 하나의 똑같은 원소가 두번 들어갈 수 없음
  • {}나 set()를 통해 만들수 있음 ()만은 불가하며 {}는 무조건 집합이 됨

리스트를 집합으로 변환

>>> gold=[1,2,3,4,5,5,6,2,2]
>>> godset=set(gold)
>>> godset
{1, 2, 3, 4, 5, 6}
>>> type(godset)
<class 'set'>

중복값이 삭제된것을 확인할수있다

>>> set("Good morning")
{'i', 'G', 'g', 'n', 'r', 'm', 'd', 'o', ' '}

문자열을 집합으로 만들면 공백 또한 원소가 되며 순서도 상관없어진다

>>> 3 in godset
True
#3이 안에 있는지 확인할수 있다
>>> godset[1]
Traceback (most recent call last):
  File "<pyshell#71>", line 1, in <module>
 #집합안의 두번째 원소가 뭔지 찾을수는 없다 집합은 순서가 없다 
  • s.add(v): 원소 v를 집합 s에 추가한다.
  • s.remove(v): 원소 v를 집합 s에서 제거한다.
  • s.pop(): 무작위 원소를 집합 s에서 제거하고 그 원소를 반환한다.
  • s.intersection(k): 집합 s, k의 공통 원소를 반환한다. (s∩k)
  • s.union(k): 집합 s, k의 합집합을 반환한다. (s∪k)
  • s.difference(k): 집합 k에 있는 원소들을 s에서 제거한다. (s∩k^c)
    >>> randomset={2,3,4,5,6,7}
    >>> randomset.add(9) #원소에 9를 추가한다
    >>> randomset
    {2, 3, 4, 5, 6, 7, 9}
    >>> randomset.remove(7) #7을 제거한다
    >>> randomset
    {2, 3, 4, 5, 6, 9}
    >>> randomset.pop() #랜덤제거한다(실제로는 작은수부터 사라진다)
    2
    >>> randomset
    {3, 4, 5, 6, 9}
    >>> odds={1,3,5,7,9}
    >>> randomset.intersection(odds) #odds와 randomset의 공동원소만 출력한다
    {9, 3, 5}
    >>> evens={2,4,6,8,10}
    >>> randomset.union(evens) #evens와 randomset두 원소를 합쳐서 출력한다
    {2, 3, 4, 5, 6, 8, 9, 10}
    >>> randomset.difference(odds) #randomeset안에 있는 odds를 제거한다
    {4, 6}
    >>> odds.difference(randomset) #odds안에서 randomset에 있는 요소를 제거한다
    {1, 7}
    >>> randomset.difference(odds,evens) #randomset안에서 odds와 evens의 요소를 제거한다
    set() #전부 제거하면 아무것도 없기때문에 내용이 없다
profile
hello world

1개의 댓글

comment-user-thumbnail
2023년 3월 4일

저 질문할게 있는데요. 제가 파일을 다운받아서 load_world()를 통해 파일 경로를 쓰고 실행했는데
FileNotFoundError: [Errno 2] No such file or directory: 'worlds\hurdles1.wld'
이라고 에러가 뜨는데 어떻게 해야하나요?

답글 달기