발로하는 파이썬세미나 1
강성훈 2
http://j.mp/2010sparcspython 3
시작하기전에 : 4
왜? 5
C C++ 자바 6
C C++ 자바 파이썬? 7
스크립팅언어 8
빠르게짜고 빠르게확인하고 빠르게고친다 9
print "Hello, world!" 10
http://python.org/ 11
12
계산기 13
>>> 3 + 4 * (5-6) -1 14
>>> 8/5 1 15
>>> 8/5 1 >>> 8%5 3 16
>>> 8.0 / 5.0 1.6000000000000001 17
>>> 8.0 / 5 1.6000000000000001 >>> 8 / 5.0 1.6000000000000001 18
5 5.0 (O) 5 5.0 (X) 19
자료형 20
>>> "foo" + 'bar' 'foobar' 21
>>> "foo" * 4 'foofoofoofoo' 22
>>> 1 + 1 == 2 True >>> 1 + 1 == 3 False 23
참과거짓 : True, False 정수 : 1, 2, -3, -4, 실수 : 1.0, -2.34, 문자열 : 'x', "Hello", 기타등등 24
>>> 1600000 + (3.0-2.05) * 6300000 7585000.0000000009 25
내가니학점을 어찌아니? 26
>>> grade = 2.05 >>> 1600000 + (3.0 - grade) * 6300000 7585000.0000000009 27
>>> grade = 2.05 >>> 1600000 + (3.0 - grade) * 6300000 7585000.0000000009 >>> grade = 2.89 >>> 1600000 + (3.0 - grade) * 6300000 2292999.9999999991 28
변수 29
>>> grade = 3.5 >>> 1600000 + (3.0 - grade) * 6300000-1550000.0 30
>>> grade = 3.5 >>> if grade < 3.0:... 1600000 + (3.0 - grade) * 6300000... else:... 1600000... 1600000 31
>>> grade = 1.86 >>> if grade < 3.0:... 1600000 + (3.0 - grade) * 6300000... else:... 1600000... 8782000.0 32
>>> grade = 1.86 >>> if grade < 2.0:... 1600000 + (3.0-2.0) * 6300000... elif grade < 3.0:... 1600000 + (3.0 - grade) * 6300000... else:... 1600000... 7900000.0 33
>>> grade = 1.86 >>> if grade < 3.0:... if grade < 2.0:... 1600000 + (3.0-2.0) * 6300000... else:... 1600000 + (3.0-grade) * 6300000... else:... 1600000... 7900000.0 34
>>> for i in range(13):... print i+1,' 인의아해가거리를질주하오.'... 1 인의아해가거리를질주하오. 2 인의아해가거리를질주하오. ( 생략 ) 13 인의아해가거리를질주하오. 35
for i in range(1,101): one = (i%10==3 or i%10==6 or i%10==9) ten = (i/10==3 or i/10==6 or i/10==9) if one and ten: print ' 짝짝 ' elif one or ten: print ' 짝 ' else: print i 36
너무복잡하네 37
Refactoring? 38
# x 가 3, 6, 9 이면 True 아니면 False def is369(x): return x==3 or x==6 or x==9 39
def is369(x): return x==3 or x==6 or x==9 for i in range(1,101): one = is369(i%10) ten = is369(i/10) if one and ten: print ' 짝짝 ' elif one or ten: print ' 짝 ' else: print i 40
def is369(x): return x==2 or x==3 or x==5 or x==7 for i in range(1,101): one = is369(i%10) ten = is369(i/10) if one and ten: print ' 짝짝 ' elif one or ten: print ' 짝 ' else: print i 41
def needsclap(x): return x==2 or x==3 or x==5 or x==7 for i in range(1,101): one = needsclap(i%10) ten = needsclap(i/10) if one and ten: print ' 짝짝 ' elif one or ten: print ' 짝 ' else: print i 42
함수 단순히코드를묶는것이아닌 43
range 도함수인가요? 44
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 45
>>> [1, 2, 3] [1, 2, 3] >>> [4, 5] + ['hello?'] [4, 5, 'hello?'] >>> [41, 42] * 3 [41, 42, 41, 42, 41, 42] >>> [] [] 46
>>> (1, 2, 3) (1, 2, 3) >>> (4, 5) + ('hello?',) (4, 5, 'hello?') >>> (41, 42) * 3 (41, 42, 41, 42, 41, 42) >>> () () 47
>>> a = [1,2,3] >>> a[0] + a[1] + a[2] 6 >>> a[1] = 5 >>> a [1, 5, 3] 48
a a[0] a[-9] a[1] a[-8] a[2] a[-7] a[3] a[-6] a[4] a[-5] a[5] a[-4] a[6] a[-3] a[7] a[-2] a[8] a[-1] 49
>>> b = (1,2,3) >>> b[0] + b[1] + b[2] 6 >>> b[1] = 5 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment 50
>>> b = (1,2,3) >>> b = b[:1] + (5,) + b[2:] >>> b (1, 5, 3) 51
a[3:8] a[0] a[-9] a[1] a[-8] a[2] a[-7] a[3] a[-6] a[4] a[-5] a[5] a[-4] a[6] a[-3] a[7] a[-2] a[8] a[-1] 52
a[-3:0:-2] a[0] a[-9] a[1] a[-8] a[2] a[-7] a[3] a[-6] a[4] a[-5] a[5] a[-4] a[6] a[-3] a[7] a[-2] a[8] a[-1] 53
사실이런거 몰라도돼요 54
a[::-1] a[0] a[-9] a[1] a[-8] a[2] a[-7] a[3] a[-6] a[4] a[-5] a[5] a[-4] a[6] a[-3] a[7] a[-2] a[8] a[-1] 55
56
리스트와튜플을 함께쓸이유 57
birthdays = [ (' 강성훈 ', 1987, 9, 13), (' 정재성 ', 1987, 2, 23), (' 김준기 ', 1987, 5, 12), ] 58
for entry in birthdays: name, year, month, day = entry print name, month, ' 월 ', day, ' 일생 ' 59
for name, year, month, day in birthdays: print name, month, ' 월 ', day, ' 일생 ' 60
for name, _, month, day in birthdays: print name, month, ' 월 ', day, ' 일생 ' 61
for name, _, month, day in birthdays: print '%s - %d 월 %d 일생 ' % \ (name, month, day) 62
for name, _, month, day in birthdays: print '{0} - {1} 월 {2} 일생 '.format( name, month, day) 63
메소드 64
자료형이나값과 연관된함수 65
formatfun = '{0} - {1} 월 {2} 일생 '.format for name, _, month, day in birthdays: print formatfunc(name, month, day) 66
자료형 = 값 67
>>> type(4) <type 'int'> >>> type('hello?') <type 'str'> >>> type([1,2,3]) <type 'list'> 68
>>> type(4) == int True >>> type('hello?') == str True >>> type([1,2,3]) == list True 69
>>> str.format <method 'format' of 'str' objects> 70
fmt = '{0} - {1} 월 {2} 일생 ' for name, _, month, day in birthdays: # 엄밀하게는 print str.format(fmt, name, month, day) 71
>>> 'hello'.upper() 'HELLO' >>> _.lower() 'hello' >>> ' '.join(['we','are','the','world']) 'we are the world' >>> _.split(' ') ['we', 'are', 'the', 'world'] 72
>>> len('hello') 5 >>> str(42) '42' >>> '%d' % 42 '42' 73
>>> print str(1/5.0) 0.2 >>> 1/5.0 0.20000000000000001 >>> print repr(1/5.0) 0.20000000000000001 74
def names(birthdays): result = [] for name, _, _, _ in birthdays: result.append(name) result.sort() return result 75
>>> names(birthdays) ['\xb0\xad\xbc\xba\xc8\xc6', '\xb1\xe8\xc1\xd8\xb1\xe2', '\xc1\xa4\xc0\xe7\xbc\xba'] 76
>>> for name in names(birthdays):... print name... 강성훈김준기정재성 77
원래세상 다이런거지 78
def printbirthdays(birthdays): for name, _, month, day in birthdays: print '%s - %d월 %d일생' % \ (name, month, day) 79
def filterbyyear(birthdays, targetyear): result = [] for entry in birthdays: _, year, _, _ = entry if year == targetyear: result.append(entry) return result 80
def filterbyyear(birthdays, targetyear): def func(entry): _, year, _, _ = entry return year == targetyear return filter(func, birthdays) 81
def filterbyyear(birthdays, targetyear): def func((name, year, month, day)): return year == targetyear return filter(func, birthdays) 82
def filterbyyear(birthdays, targetyear): return filter( lambda (n,y,m,d): y==targetyear, birthdays) 83
def filterbyyear(birthdays, targetyear): return [(name, year, month, day) for name, year, month, day in birthdays if year == targetyear] 84
85
스크립팅언어? 86
스크립팅언어 87
스크립팅핛때쓰면 스크립팅언어 88
목표 89
생년월일검색하는 프로그램 90
보통은이름과생년월일을모두보여준다 이름만보여줄수도있다 이름으로검색핛수있다 생년별목록도볼수있다 91
birthdays = [ (' 강성훈 ', 1987, 9, 13), (' 정재성 ', 1987, 2, 23), (' 김준기 ', 1987, 5, 12), (' 안병욱 ', 1989, 10, 14), (' 강철 ', 1990, 3, 11), (' 유수형 ', 1991, 3, 13), (' 조유정 ', 1990, 4, 18), (' 김도국 ', 1990, 3, 11), ] 92
데이터는 data.py 프로그램은 birthday.py 93
출력핛때는 꼭 print 명령을 써야핚다 94
95
# coding=cp949 utf-8이어야할수도있음 birthdays = [ (' 강성훈 ', 1987, 9, 13), (' 정재성 ', 1987, 2, 23), (' 김준기 ', 1987, 5, 12), (' 안병욱 ', 1989, 10, 14), (' 강철 ', 1990, 3, 11), (' 유수형 ', 1991, 3, 13), (' 조유정 ', 1990, 4, 18), (' 김도국 ', 1990, 3, 11), ] 96
원래세상 다이런거지 (2) 97
>>> import data >>> print '%d 명 ' % len(data.birthdays) 8 명 98
# coding=cp949 import data print '%d 명 ' % len(data.birthdays) 99
# coding=cp949 from data import birthdays print '%d 명 ' % len(birthdays) 100
모듈 101
birthday.py main import data data.py data 102
persons.py main import birthday birthday.py birthday import data data.py data 103
# coding=cp949 from data import birthdays def main(): print '%d 명 ' % len(birthdays) if name == ' main ': main() 104
birthday.py main import data data.pyc data 105
def main(): choice = showmenu() if choice == 1: printnames(birthdays) elif choice == 2: printbirthdays(birthdays) elif choice == 3: printbyname(birthdays) elif choice == 4: printbyyear(birthdays) 106
def printnames(birthdays): pass # 이름만출력할것 def printbirthdays(birthdays): pass # 이름과생년월일을출력할것 def printbyname(birthdays): pass # 이름을입력받아서 # 해당하는생년월일을출력 def printbyyear(birthdays): pass # 생년을입력받아서 # 해당하는목록을출력 107
def printnames(birthdays): print 'TODO: 이름목록을출력 ' def printbirthdays(birthdays): print 'TODO: 이름과생년월일출력 ' def printbyname(birthdays): print ('TODO: 이름을입력받아 ' ' 해당하는생년월일을출력 ') def printbyyear(birthdays): print ('TODO: 생년을입력받아 ' ' 해당하는목록을출력 ') 108
def showmenu(): print '---- 메뉴 ----' print '1. 이름보기 ' print '2. 이름과생년월일보기 ' print '3. 이름으로찾기 ' print '4. 생년으로찾기 ' return input('>>> ') 109
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> 2 TODO: 이름과생년월일출력 110
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> 5 111
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> 3*4-11 TODO: 이름목록을출력 112
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> end Traceback (most recent call last): ( 생략 ) File "<string>", line 1, in <module> NameError: name 'end' is not defined 113
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> [ 엔터 ] Traceback (most recent call last): ( 생략 ) File "<string>", line 0 ^ SyntaxError: unexpected EOF while parsing 114
input 으로는 안된다 115
>>> dir() [' builtins ', ' doc ', ' name ', ' package '] >>> dir( builtins ) ['ArithmeticError', 'AssertionError', ( 생략 ), 'xrange', 'zip'] 116
>>> [x for x in dir( builtins )... if 'input' in x] ['input', 'raw_input'] 117
>>> help(raw_input) Help on built-in function raw_input in module builtin : raw_input(...) raw_input([prompt]) -> string Read a string from standard input. The trailing newline is stripped. If the user hits EOF (Unix: Ctl-D, Windows: Ctl-Z+Return), raise EOFError. On Unix, GNU readline is used if enabled. The prompt string, if given, is printed without a trailing newline before reading. 118
모르는게있으면 우선 help 를! 119
def inputnum(prompt): return input(prompt) def showmenu(): print '---- 메뉴 ----' print '1. 이름보기 ' print '2. 이름과생년월일보기 ' print '3. 이름으로찾기 ' print '4. 생년으로찾기 ' return inputnum('>>> ') 120
def inputnum(prompt): return int(raw_input(prompt)) 121
def inputnum(prompt): while True: # 무한반복 ( 사용에주의!) line = raw_input(prompt) try: return int(line) except: print ' 숫자를입력하시죠.' 122
예외 (exception) 일반적이지않다 123
>>> 3/0 Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: integer division or modulo by zero 124
>>> asdf Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'asdf' is not defined 125
>>> int('notanumber') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: invalid literal for int() with base 10: 'notanumber' 126
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 >>> exit 숫자를입력하시죠. >>> quit 숫자를입력하시죠. >>> 나좀나가게해줘ㅆㅂ숫자를입력하시죠. 127
나가는메뉴가없다 Ctrl-C 같은강제종료키도 try~except 가먹어버린다 128
def showmenu(): print '---- 메뉴 ----' print '1. 이름보기 ' print '2. 이름과생년월일보기 ' print '3. 이름으로찾기 ' print '4. 생년으로찾기 ' print '0. 끝내기 ' return inputnum('>>> ') 129
def inputnum(prompt): while True: line = raw_input(prompt) try: return int(line) except ValueError: print ' 숫자를입력하시죠.' 130
방어적프로그래밍 131
def names(birthdays): result = [] for name, _, _, _ in birthdays: result.append(name) result.sort() return result def printnames(birthdays): print ', '.join(names(birthdays)) 132
def printbirthdays(birthdays): for name, _, month, day in birthdays: print '%s - %d월 %d일생' % \ (name, month, day) 133
def printbyname(birthdays): name = raw_input(' 이름을입력하세요 : ') for n, y, m, d in birthdays: if n == name: print '%s - %d월 %d일생' % \ (n, m, d) 134
def printbyname(birthdays): name = raw_input(' 이름을입력하세요 : ') count = 0 for n, y, m, d in birthdays: if n == name: print '%s - %d월 %d일생' % \ (n, m, d) count += 1 if count == 0: print ' 그런사람이없습니다.' 135
똑같은기능에 똑같은성능이면 갂결핚게낫다 136
def filterbyname(birthdays, targetname): return [(name, year, month, day) for name, year, month, day in birthdays if name == targetname] def printbyname(birthdays): name = raw_input(' 이름을입력하세요 : ') filtered = filterbyname(birthdays, name) printbirthdays(filtered) 137
def filterbyyear(birthdays, targetyear): return [(name, year, month, day) for name, year, month, day in birthdays if year == targetyear] def printbyyear(birthdays): year = inputnum(' 생년을입력하세요 : ') filtered = filterbyyear(birthdays, year) printbirthdays(filtered) 138
---- 메뉴 ---- 1. 이름보기 2. 이름과생년월일보기 3. 이름으로찾기 4. 생년으로찾기 0. 끝내기 >>> 4 생년을입력하세요 : 1990 강철 - 3월 11일생조유정 - 4월 18일생김도국 - 3월 11일생 139
새기능을만들려면? 140
def main(): choice = showmenu() if choice == 1: printnames(birthdays) elif choice == 2: printbirthdays(birthdays) def showmenu(): elif choice == 3: print '---- 메뉴 ----' printbyname(birthdays) print '1. 이름보기 ' elif choice == 4: print '2. 이름과생년월일보기 ' printbyyear(birthdays) print '3. 이름으로찾기 ' 여기다새메뉴를추가 print '4. 생년으로찾기 ' print '0. 끝내기 ' 여기다새조건을추가 return inputnum('>>> ') 141
하나의함수에 하나의기능을 142
def showmenu(): print '---- 메뉴 ----' print '1. 이름보기 ' print '2. 이름과생년월일보기 ' print '3. 이름으로찾기 ' print '4. 생년으로찾기 ' print '0. 끝내기 ' choice = inputnum('>>> ') if choice == 1: return printnames elif choice == 2: return printbirthdays elif choice == 3: return printbyname elif choice == 4: return printbyyear 143
CHOICES = {1: printnames, 2: printbirthdays, 3: printbyname, 4: printbyyear} def showmenu(): print '---- 메뉴 ----' print '1. 이름보기 ' print '2. 이름과생년월일보기 ' print '3. 이름으로찾기 ' print '4. 생년으로찾기 ' print '0. 끝내기 ' choice = inputnum('>>> ') if choice in CHOICES: return CHOICES[choice] 144
def main(): routine = showmenu() if routine: routine(birthdays) 145
def main(): while True: routine = showmenu() if not routine: return routine(birthdays) print 146
main: 시작함수 showmenu: 메뉴를보여줌 inputnum: 숫자를입력받음 names: 목록에서이름만반홖 filterby : 목록을조건에따라걸러냄 printbirthdays: 목록을출력 print : 각메뉴를구현함 147
여전히중복이 있지않나요? 148
for name,_,_,_ in birthdays: for name,_,month,day in birthdays: [(name,year,month,day) for name,year,month,day in birthdays if ] 149
순서를하나라도 삐끗핚다면? 150
새자료형을만들기 151
class person(object): def init (self, name, year, month, day): self.name = name self.year = year self.month = month self.day = day 152
자료형과연관된 함수? 153
즉그냥함수 ( 첫인자만빼고 ) 154
class person(object): def init (you, name, year, month, day): you.name = name you.year = year you.month = month you.day = day 155
>>> p = person(' 강성훈 ', 1987, 9, 13) >>> p < main.person object at 0x00B12110> >>> print p.name 강성훈 >>> p.year, p.month, p.day (1987, 9, 13) 156
class person(object): def init (self, name, year, month, day): self.name = name self.year = year self.month = month self.day = day def str (self): return '%s - %d월 %d일생' % \ (self.name, self.month, self.day) 157
>>> print str(p) < main.person object at 0x00B12110> 158
파이썬메모리의 구조 159
정수 1987 미지의세계 정수 9 미지의세계 정수 13 자료형 person 미지의세계 값 person ( 클래스 ) 미지의세계 문자열 ' 강성훈 ' 미지의세계 환경 name year month day person p 160
자료형 person 미지의세계자료형 person 미지의세계 값 person ( 클래스 ) name month year day 환경 person p 161
모든것은 요레퍼런스로 162
>>> a = [[]] * 3 >>> a [[], [], []] >>> a[0].append(4) >>> a [[4], [4], [4]] 163
>>> a = [[] for i in range(3)] >>> a [[], [], []] >>> a[0].append(4) >>> a[1].append(5) >>> a[2].append(6) >>> a [[4], [5], [6]] 164
제자리에서변경이 가능핚가? 165
그런것 : 리스트, 사전 안그런것 : 문자열, 튜플 166
하여튼 167
망한값들 자료형 person 미지의세계 값 person ( 클래스 ) * * * * 자료형 person 미지의세계 환경 값 person ( 클래스 ) * * * * person p 168
자료형 person 미지의세계 환경 값 person ( 클래스 ) * * * * person p 169
가비지컬렉션 = 망핚값처리하기 170
>>> p = person(' 강성훈 ', 1987, 9, 13) >>> print p. str () 강성훈 - 9월 13일생 >>> print str(p) 강성훈 - 9월 13일생 >>> print p 강성훈 - 9월 13일생 171
마무리 172
# coding=cp949 class person(object): def init (self, ): def str (self, ): birthdays = [ person(' 강성훈 ', 1987, 9, 13), person(' 정재성 ', 1987, 2, 23), person(' 김준기 ', 1987, 5, 12), ] 173
def printnames(birthdays): names = [p.name for p in birthdays] names.sort() print ', '.join(names) def printbirthdays(birthdays): for p in birthdays: print p 174
def printbyname(birthdays): name = raw_input(' 이름을입력하세요 : ') filtered = [p for p in birthdays if p.name == name] printbirthdays(filtered) def printbyyear(birthdays): year = inputnum(' 생년을입력하세요 : ') filtered = [p for p in birthdays if p.year == year] printbirthdays(filtered) 175
더고칠거리를 생각해보세요! 176
끝? 177
세상모든일이 이렇게잘풀리짂 않겠지만 178
리팩토링 테스팅 디버깅 문서화 이건안했지만 179
모듈을꼭우리만 만들란법이있나 180
바퀴를재발명하기 181
182
>>> import sys >>> sys.version '2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)]' 183
>>> import math >>> math.sqrt(2) 1.4142135623730951 >>> 2 ** 0.5 1.4142135623730951 >>> math.factorial(16) 20922789888000L 184
>>> import datetime >>> datetime.date.today() datetime.date(2010, 3, 12) >>> _.weekday() 4 >>> print [' 월 ',' 화 ',' 수 ',' 목 ',' 금 ',... ' 토 ',' 일 '][_] 금 185
>>> import random >>> menus = [' 짜장 ', ' 짬뽕 ', ' 짜짬면 '] >>> print menus[random.randint(0,... len(menus)-1)] 짜장 >>> print random.choice(menus) 짬뽕 186
>>> import urllib >>> for line in urllib.urlopen(... 'http://www.census.gov/ipc/'... 'www/popclockworld.html'):... if 'worldnumber' in line:... print line[45:-14]... 6,807,870,286 187
188
레퍼런스는정독해도 부족함이없습니다 189
그밖에 Numpy라거나 Django라거나 Pyglet이라거나 190
안다룬것들 191
클래스에대핚자세핚내용 set, unicode 같은자료형들 외부라이브러리쓰기 패키지다루기 그밖에파이썬을쓰면서필요하게될수많은조언들 192
두시갂안에하긴 좀벅찬지라 193
질문과답변? 194
감사합니다. 너무길어서정말로죄송 195
덤 196
슬라이드목차 #1 시작 #4 왜파이썬을배우는가? #13 계산기로쓰기, 자료형 #25 변수, 조건문, 반복문 #36 리팩토링, 함수 #44 리스트, 튜플 #58 메소드, 값으로서의자료형 #72 내장함수및메소드 #86 아젠다설정 #92 모듈 #106 생년월일프로그램의뼈대 #116 내장도움말 #120 리팩토링 (2), 방어적프로그래밍, 예외 #132 생년월일프로그램의뼈대 (2) #140 리팩토링 (3) #148 클래스 #159 파이썬메모리의구조 #172 생년월일프로그램의마무리 #180 파이썬내장라이브러리 #191 안다룬것들 197
표기컨벤션 코드및대화식홖경은노란배경으로, 프로그램출력은파란배경으로, 직접입력하지않은내용은옅은색으로, 이벆슬라이드에처음등장하는문법 심볼은붉은색으로, ( 단, 공백등은별도표시안함 ) 파이썬프롬포트및예약어는굵게표기했음. 198