국민대, 파이썬, 데이터

W04 Exercise, Indexing&Slicing, Function


Table of Contents

  1. Practice Makes Perfect
    1. Chinese Zodiac
    2. Hashtags
    3. Morse
    4. Card Deck
    5. 문장 안의 단어 개수
    6. 단어의 순서를 바꿔 출력
    7. 단어의 순서와 그 단어의 글자 순서 바꿔 출력
  2. Indexing and Slicing
  3. Function
  4. Object-Oriented Programming

In [6]:
from IPython.display import Image

References

  1. 파이썬 완벽 가이드(원제: Python Essential Reference), 한빛미디어, David Beazley
  2. Learning Python 5th Edition, Oreilly, Mark Lutz

1. Practice Makes Perfect

이번 시간에는 함께 아래 문제를 풀어보도록 하겠습니다. 이 URL(https://floobits.com/initialkommit/kookmin)로 접근하셔서 같이 보도록 하겠습니다.

1.1 Chinese Zodiac

아래에 표에 나와있는 값을 이용해서 사용자가 입력한 년도에 해당되는 띠를 알려주세요. 사용자가 어떤 값을 입력해도 말이지요.

Year(ex) Animal Remain
2000 8
2001 9
2002 10
2003 11
2004 원숭이 0
2005 1
2006 2
2007 돼지 3
2008 4
2009 5
2010 호랑이 6
2011 토끼 7

1.2 Hashtags


In [ ]:
# 게시글 제목
title = "On top of the world! Life is so fantastic if you just let it. \
I have never been happier. #nyc #newyork #vacation #traveling"

# Write your code below.

1.3 Morse


In [8]:
# 모스부호
morse = {
    '.-':'A','-...':'B','-.-.':'C','-..':'D','.':'E','..-.':'F',
    '--.':'G','....':'H','..':'I','.---':'J','-.-':'K','.-..':'L',
    '--':'M','-.':'N','---':'O','.--.':'P','--.-':'Q','.-.':'R',
    '...':'S','-':'T','..-':'U','...-':'V','.--':'W','-..-':'X',
    '-.--':'Y','--..':'Z'
}
 
# 풀어야할 암호
code = '.... .  ... .-.. . . .--. ...  . .- .-. .-.. -.--'

# Write your code below.

1.4 Card Deck


In [1]:
front = ['s', 'c', 'd', 'h', ]  # Spade, Club, Diamond, Heart
back = [
	'2',
	'3',
	'4',
	'5',
	'6',
	'7',
	'8',
	'9',
	'T',  # Ten
	'J',  # Jack
	'Q',  # Queen
	'K',  # King
	'A',  # Ace
]

# Write your code below.

1.5 문장 안의 단어 개수


In [ ]:
# 주어진 문장을 모두 소문자로 만들고 ',', '.'을 제거하라.
# 그리고 각 단어가 몇 개 사용했는지 Counting하라.

s = 'We propose to start by making it possible to teach programming in Python, \
an existing scripting language, and to focus on creating \
a new development environment and teaching materials for it.'

# Write your code below.

1.6 단어의 순서를 바꿔 출력


In [4]:
# 단어의 순서를 바꿔서 출력하라.

s = "Sometimes I feel like a data scientist"

# Write your code below.

1.7 단어의 순서와 그 단어의 글자 순서 바꿔 출력


In [5]:
# 단어의 순서를 바꾸고
# 단어의 글자 순서도 바꿔 출력하라.
# tsitneics atada a ekil leef I semitemoS"

s = "Sometimes I feel like a data scientist"

# Write your code below.

2. Indexing and Slicing

항목 설명
s[i] 순서열의 원소 i를 반환
s[i:j] 조각을 반환
s[i:k:stride] 확장 분할에 의한 조각을 반환
  • List
  • Tuple
  • Str

등 모든 순서열 객체에 Index와 Slice를 적용할 수 있습니다. 그러나 순서가 없는 객체인 사전(Dictionary)에는 순서가 없기 때문에 Slice는 적 적용되지 않고 오직 Index만 적용이 됩니다.

2.1 Index

순서열(List, Tuple, Str)


In [11]:
s = 'bicycle'

In [16]:
s[0]


Out[16]:
'b'

사전(Dictionary)


In [17]:
morse


Out[17]:
{'-': 'T',
 '--': 'M',
 '---': 'O',
 '--.': 'G',
 '--.-': 'Q',
 '--..': 'Z',
 '-.': 'N',
 '-.-': 'K',
 '-.--': 'Y',
 '-.-.': 'C',
 '-..': 'D',
 '-..-': 'X',
 '-...': 'B',
 '.': 'E',
 '.-': 'A',
 '.--': 'W',
 '.---': 'J',
 '.--.': 'P',
 '.-.': 'R',
 '.-..': 'L',
 '..': 'I',
 '..-': 'U',
 '..-.': 'F',
 '...': 'S',
 '...-': 'V',
 '....': 'H'}

In [18]:
morse['....']


Out[18]:
'H'

In [21]:
morse.get('....')


Out[21]:
'H'

2.2 Slice


In [51]:
Image(filename='images/slicing.png')


Out[51]:

In [23]:
s = 'bicycle'

In [31]:
s[1:7]


Out[31]:
'icycle'

In [53]:
s[1:7:2]  # Skipping


Out[53]:
'iyl'

In [33]:
s[1::2]


Out[33]:
'iyl'

In [35]:
s[:7:2]


Out[35]:
'bcce'

In [45]:
l = list(range(10))
l


Out[45]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [46]:
l[2:5] = [20, 30]
l


Out[46]:
[0, 1, 20, 30, 5, 6, 7, 8, 9]

In [48]:
l[2:5] = 100
l


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-d29be80f6a36> in <module>()
----> 1 l[2:5] = 100
      2 l

TypeError: can only assign an iterable

In [49]:
l[2:5] = [100]
l


Out[49]:
[0, 1, 100, 8, 9]

In [47]:
del l[5:7]
l


Out[47]:
[0, 1, 20, 30, 5, 8, 9]

위 연습 문제 중 Hashtags로 이동해서 '#'만 빼봅시다.

2.3 Stride


In [13]:
s[::3]


Out[13]:
'bye'

In [14]:
s[::-1]


Out[14]:
'elcycib'

In [15]:
s[::-2]


Out[15]:
'eccb'

3. Function

  • 함수, 객체 지향 프로그래밍에서는 메소드(Method)라고 부르기도 합니다.
  • 쉽게 생각해보면 함수는 '특정 행동'을 말합니다. 즉 함수를 호출하면 함수안의 내용이 실행이 되는 것입니다.
  • 함수는 호출해야 실행되는 객체이므로 Callable Object 라고도 합니다.

3.1 Input and Output


In [73]:
Image(filename='images/function2.png')


Out[73]:
  • Input: Argument, Parameter, 매개변수, 인자
  • Output: Return, 반환값

위의 그림을 봐서 알 수 있듯이 함수에는 Input/Output이라는 개념이 있습니다. 만약 Input이 있다면 Input을 인자(Argument, Parameter)라고 부릅니다. 또한, 만약 Output이 있다면 Output을 Return Value 혹은 반환값이라고 말합니다. 그러나 위에서 '만약 ...가 있다면'이라는 표현을 썼듯이 항상 있는 것은 아닙니다.

어떻게 생겼을까!?

1) 인자값이 없을 경우: function ( )

2) 인자값이 있을 경우: function ( 1, "1", name="python )

3.2 Why Use Function?

Maximizing Code Reuse and Minimizing Redundancy


In [71]:
Image(filename='images/function.png')


Out[71]:

위 그림 안의 있는 코드가 뭘 뜻하는지는 몰라도 뭔가 계속해서 중복된다는 것은 보일 것입니다. 이렇듯 함수를 통해 코드가 반복될 때 중복을 피하고 코드 재사용을 최대화할 수 있습니다.

3.3 How to Use

함수를 선언할 때는 def라는 예약어를 사용합니다.

1) 함수를 선언하는 방법

- Argument가 없을 경우 선언


In [1]:
def addition0():
    print("더하기 함수입니다.")
    # Argument의 개수와 상관없이 Return Value가 있을 수도 있고 없을 수도 있습니다.

addition0()


더하기 함수입니다.

- Return Value가 없을 경우 선언


In [1]:
def addition1(x, y):
    print(x + y)

addition1(1, 2)


3

- Return Value가 있을 경우 선언


In [2]:
def addition2(x, y):
    return x + y

In [3]:
print("%d%d의 합은 %s입니다." % (10, 30, addition2(10, 30)))


10과 30의 합은 40입니다.

2) 함수를 실행하는 방법


In [82]:
addition0()


더하기 함수입니다.

In [79]:
addition1(10, 10)


20

In [87]:
a = addition1(100, 200)
print(a)


300
None

In [4]:
print(addition2(10, 20))


30

In [88]:
a = addition2(10, 20)
print(a)


30

3.4 Arguments

  • Argument
    • 인자
    • Parameter
    • 함수 안으로 전달되는 값
  • *args
    • 인자 이름 앞에 별표(*)를 삽입하면 함수는 여러 개의 인자를 받을 수 있습니다.
    • 인자 이름은 임의로 만들 수 있으나 관행 상 args라고 많이 사용합니다.

In [8]:
def printa(x, y, *args):
    print(type(args))  # *args는 Tuple 형식
    for item in args:  # *args는 x, y를 뺀 나머지
        print(item)

printa("a", "b", "c", "d", "c", "1")


<class 'tuple'>
c
d
c
1

3.5 Keyword Arguments

  • 키워드 인자(keyword argument)
    • 인자값을 전달할 때 각 인자의 이름과 값을 직접 지정할 수 있는데 이를 Keyword Argument라고 합니다.
    • 위의 *args와 마찬가지로 인자 이름 앞에 별표(*) 2개를 붙이면 여러 개의 인자를 받을 수 있습니다.
    • **kwagrs 인자는 사전 객체이며 관행 상 kwagrs라는 이름을 사용합니다.
    • 기본값 설정
      • keyword 이름과 함께 값을 처음부터 할당할 수 있는데 이 때 그 값은 기본값이 됩니다.

In [10]:
def foo(x=10, greeting="hello", **kwargs):
    print(kwargs)
    print(type(kwargs))
    print(kwargs.get('you'))
    print(kwargs['you'])
    print(greeting, x, kwargs.get('you'))

foo(you="mbc")


{'you': 'mbc'}
<class 'dict'>
mbc
mbc
hello 10 mbc

3.6 Doc String

복잡한 함수를 만들었다고 가정해보겠습니다. 이 함수의 이름만으론 이 함수의 목적을 알기가 어려울 것입니다. 이럴 때 함수의 선언부 바로 아래에 Multiple Comments(""" ... """)로 함수에 대한 설명을 적어 놓으면 후에 문서화하거나 다른 사람들이 소스를 볼 때 매우 유익할 것입니다.


In [11]:
def foo():
    '''This is a foo.'''
    return "foo"

foo()


Out[11]:
'foo'

Doc String을 보는 방법


In [115]:
foo.__doc__


Out[115]:
'This is a foo.'

In [12]:
help(foo)


Help on function foo in module __main__:

foo()
    This is a foo.

3.7 Annotations

위에 Doc String과 마찬가지로 함수에 주석을 달 수 있습니다. 다른 개발자가 복잡하고 알기 어려운 함수를 볼 때 매우 유용하게 사용할 수 있겠죠!?


In [128]:
def add(x:int, y:int) -> int:
    """더하기 함수입니다."""
    return x + y

Annotations를 보는 방법


In [129]:
help(add)


Help on function add in module __main__:

add(x:int, y:int) -> int
    더하기 함수입니다.


In [130]:
add.__annotations__


Out[130]:
{'return': int, 'x': int, 'y': int}

특히 위의 Doc String과 Annotation은 오픈 소스가 많아지면서 유용하게 쓰일 수 있습니다. 이런 것을 Informational Metadata 혹은 Metadata라고 합니다. 이런 부분을 잘 기입하면 나중에 문서화할 때도 많은 도움이 됩니다. Python을 문서화해주는 오픈 소스는 대표적으로 Sphinx가 있습니다.


4. Practice Makes Perfect

4.1 함수를 이용해 평균을 구해보세요.


In [21]:
# 사용자가 몇 개의 인수든 상관없이 모든 인수의 평균을 구하는 함수를 만들어봅시다.

# Write your code below.
def avg(*args):
    return sum(args) / len(args)

print(avg(1, 2))


1.5

4.2 미국에 있는 주(State)의 수도는 무엇인지 알아낼 수 있는 함수를 만들어보세요.


In [30]:
# 미국의 주의 수도를 찾는 함수를 만드세요.

STATES_CAPITALS = {
    'Alabama': 'Montgomery',
    'Alaska': 'Juneau',
    'Arizona': 'Phoenix',
    'Wyoming': 'Cheyenne',
}

# Write your code below.
def find_capital(name=''):
    return STATES_CAPITALS.get(name, 'a')

print(find_capital(name='Al'))


a

4.3 Algorithm - Bubble Sort

이번엔 지금까지 배운 것을 총동원해서 Bubble Sort 알고리즘을 풀어보도록 하겠습니다.


In [1]:
from IPython.display import YouTubeVideo

Bubble Sort


In [2]:
YouTubeVideo('Cq7SMsQBEUw')


Out[2]:

Sorting Algorithms


In [21]:
YouTubeVideo('ZZuD6iUe3Pc')


Out[21]:

사실 지금까지 많은 것을 배웠습니다. 그리고 지금까지 배운 것만으로도 많은 문제를 해결할 수 있습니다. 문제를 해결하기 위해 지식보다는 문제를 어떻게 해결해 나가야할지 사고력이 중요해지고 있습니다. 프로그래밍에서는 이를 알고리즘이라는 것으로 부릅니다. 이번에는 알고리즘 중에 정렬(Sorting)이라는 것을 보며 프로그래밍 실력을 키워보도록 하겠습니다.

Sorting 알고리즘은 일반적으로 나와있는 방법이 여러가지가 있습니다. 어디까지나 사고하는 방법이기 때문에 방법은 더 많을 수 있으나 대표적인 방법들이 9가지 정도가 있습니다. 그 중에서도 가장 쉽게(?) 생각해볼 수 있는 Bubble Sort를 보도록 하겠습니다.


In [32]:
target_list = [54, 26, 93, 17, 77, 31, 44, 55, 20]

In [33]:
len(target_list)


Out[33]:
9

In [36]:
for item in range(len(target_list)):
    print(item)


0
1
2
3
4
5
6
7
8

위와 같이 무작위로 정렬되어 있는 숫자 9개가 있습니다. 이를 Bubble Sort 알고리즘을 이용해서 오름차순으로 정렬해보도록 하겠습니다. 잘 기억해두셔야 할 것은 이 것은 사고하는 방법이므로 정답은 없다는 것입니다. 그리고 머릿속에서 어떻게 풀어나가면 좋을지 먼저 생각해보시기 바랍니다.


hint

[54, 26, 93, 17, 77, 31, 44, 55, 20]  # 1
[26, 54, 93, 17, 77, 31, 44, 55, 20]  # 2
[26, 54, 93, 17, 77, 31, 44, 55, 20]  # 3
[26, 54, 17, 93, 77, 31, 44, 55, 20]  # 4
[26, 54, 17, 77, 93, 31, 44, 55, 20]  # 5
[26, 54, 17, 77, 31, 93, 44, 55, 20]  # 6
[26, 54, 17, 77, 31, 44, 93, 55, 20]  # 7
[26, 54, 17, 77, 31, 44, 55, 93, 20]  # 8
[26, 54, 17, 77, 31, 44, 55, 20, 93]  # 9