프리렉 - FREELEC
http://freelec.co.kr/book/catalogue_view.asp?UID=134
이강성저
우선 ch10-01.txt 텍스트 파일을 만들어보자. 에디터로 파일을 만들어서 시작해도 좋다. 하지만 ipython의 %%file 명령을 이용하면 간단히 파일을 저장할 수 있다.
%%file ch10-01.txt
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
# comment1..
* a powerful N-dimensional array object
* sophisticated (broadcasting) functions
* tools for integrating C/C++ and Fortran code
* useful linear algebra, Fourier transform, and random number capabilities
# comment2..
Besides its obvious scientific uses, NumPy can also be used as an efficient multi-dimensional container of generic data. Arbitrary data-types can be defined. This allows NumPy to seamlessly and speedily integrate with a wide variety of databases.
Numpy is licensed under the BSD license, enabling reuse with few restrictions.
# 파일을 읽어서 처리한다.
lineno = 0
for line in open('ch10-01.txt'):
lineno += 1
if line.startswith('#'):
continue
n = len(line.split())
print ('{:3d} : {:3d}'.format(lineno, n))
# 방법 1
f = open('number.txt', 'w')
for k in range(10):
f.write('{}\n'.format(k))
f.close()
# 방법 2
f = open('number.txt', 'w')
s = '\n'.join([str(k) for k in range(10)])
f.write(s)
f.close()
# 방법 3
with open('number.txt', 'w') as f:
s = '\n'.join([str(k) for k in range(10)])
f.write(s)
# 방법 4
with open('number.txt', 'w') as f:
L = [str(k)+'\n' for k in range(10)]
f.writelines(L)
# 확인
print (open('number.txt').read())
%%file s.txt
pig ham
cat dog
ham bird
dog pig
L = sorted(open('s.txt').read().splitlines())
L
print ('\n'.join(L))
# 각 라인에 단어가 두 개 이상 있다는 가정하에 문제를 풉니다.
L = sorted(open('s.txt').read().splitlines(), key=lambda a:a.split()[1])
L
print ('\n'.join(L))
ws = open('s.txt').read().split()
ws
for k in range(0, len(ws), 3):
print (' '.join(ws[k:k+3]))
import glob
# 우선 함수 테스트를 해보자
def mygrep(find, fpattern):
flist = glob.glob(fpattern)
for fpath in flist: # 각 파일에 대해서
lineno = 0
for line in open(fpath): # 각 라인에 대해서
lineno += 1
if find in line:
print ('{}:{:}:{}'.format(fpath, lineno, line.rstrip()))
mygrep('bird', 'ch*.ipynb')
%%file mygrep.py
# simple solution
'''
사용 예
$ python3 mygrep.py worksheets *.ipynb
'''
import glob
import sys
def mygrep(find, flist):
for fpath in flist: # 각 파일에 대해서
lineno = 0
for line in open(fpath): # 각 라인에 대해서
lineno += 1
if find in line:
print ('{}:{:}:{}'.format(fpath, lineno, line.rstrip()))
if __name__ == '__main__':
mygrep(sys.argv[1], sys.argv[2:]) # 두 개의 인수
!python3 mygrep.py bird ch*.ipynb # 사용 예
%%file mygrep2.py
# using argparse
'''
사용 예
$ python3 mygrep.py worksheets *.ipynb
'''
import argparse
import sys
def mygrep(find, flist):
for fpath in flist: # 각 파일에 대해서
lineno = 0
for line in open(fpath): # 각 라인에 대해서
lineno += 1
if find in line:
print ('{}:{:}:{}'.format(fpath, lineno, line.rstrip()))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('find')
parser.add_argument('flist', nargs='+')
args = parser.parse_args(sys.argv[1:])
mygrep(args.find, args.flist)
!python3 mygrep2.py bird ch*.ipynb # 사용 예
'''
함수를 테스트 해보자.
re 모듈의 search 함수를 이용하면 정규식을 간단히 처리할 수 있다.
'''
import re
import glob
def mygrep2(find, fpattern):
flist = glob.glob(fpattern)
for fpath in flist: # 각 파일에 대해서
lineno = 0
for line in open(fpath): # 각 라인에 대해서
lineno += 1
if re.search(find, line):
print ('{}:{:}:{}'.format(fpath, lineno, line.rstrip()))
mygrep2('\Wtiger\W', 'ch*.ipynb') # \W는 숫자 또는 문자가 아닌 것과 매칭된다.
import time
def addLogLine(logfile, ip, access_page, access_time):
f = open(logfile, 'a')
f.write('{}:{}:{}\n'.format(ip, access_page, access_time))
addLogLine('weblog', '119.197.7.230', '/dokuwiki/lib/images/smileys/icon_sad.gif', time.time())
addLogLine('weblog', '119.197.7.230', '/dokuwiki/lib/images/email.png', time.time())
addLogLine('weblog', '119.197.7.230', '/dokuwiki/lib/images/email.png', time.time())
addLogLine('weblog', '119.197.7.230', '/dokuwiki/lib/tpl/dokuwiki/images/logo.png', time.time())
addLogLine('weblog', '119.63.193.130', '/', time.time())
addLogLine('weblog', '202.46.50.79', '/gugak/wp-includes/wlwmanifest.xml', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/doku.php?id=start', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/lib/tpl/dokuwiki/images/logo.png', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/lib/tpl/dokuwiki/images/button-donate.gif', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/lib/tpl/dokuwiki/images/button-php.gif', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/lib/tpl/dokuwiki/images/button-html5.png', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/doku.php?id=start', time.time())
addLogLine('weblog', '119.197.7.237', '/dokuwiki/lib/tpl/dokuwiki/images/button-dw.png', time.time())
!cat weblog # 저장 내용 확인 (리눅스 쉘 명령)
#!type weblog # 윈도우에서의 명령
group = {}
for line in open('weblog'):
ip, url, tm = line.split(':')
if ip not in group:
group[ip] = []
group[ip].append(url)
import collections
for ip in group:
print ('-'*60)
print (ip)
for url, cnt in collections.Counter(group[ip]).items():
print ('{} : {}'.format(url, cnt))
문제를 수정합니다. 암호화 방식은 파이썬2에서 사용된 sha 모듈 대신에 파이썬3의 hashlib를 사용합니다. hashlib은 다양한 보안 hash를 제공합니다. SHA1, SHA224, SHA256, SHA384, SHA512, MD5를 제공합니다.
import hashlib
password = 'my pass word'
encrypted1 = hashlib.sha1(password.encode()).hexdigest()
encrypted2 = hashlib.sha224(password.encode()).hexdigest()
encrypted3 = hashlib.md5(password.encode()).hexdigest()
print (encrypted1)
print (encrypted2)
print (encrypted3)
# save password to file 'access'
def savePassword(sid, passwd):
encrypted = hashlib.sha1(passwd.encode()).hexdigest()
f = open('access', 'a')
f.write('{}:{}\n'.format(sid, encrypted))
savePassword('gslee', '1234')
!cat access # 저장된 내용 확인 (리눅스 쉘 명령)
savePassword('ky', 'asbc')
!cat access # 저장된 내용 확인 (리눅스 쉘 명령)
#!type access # 윈도우
def checkIfUserValid(sid, passwd):
encrypted = hashlib.sha1(passwd.encode()).hexdigest()
with open('access') as f:
for line in f:
tid, tpass = line.split(':')
if tid == sid and encrypted == tpass.strip():
return True
return False
checkIfUserValid('gslee', '1234')
checkIfUserValid('gslee', '12345')
본격적인 작업을 시작하기 전에 코드들을 테스트 해보자.
# 웹에서 페이지 읽어오기 테스트
from urllib.request import urlopen
root = 'http://docs.python.org/2/howto/webservers.html'
f = urlopen(root)
html = f.read()
print (len(html)) # 바이트열 길이
print (html[:100]) # 일부만 출력해본다.
# 읽어온 페이지에서 링크 추출하기
# <a>..</a> 태그만 추출하기로 한다.
import re # 26장 정규식 참조
shtml = html.decode() # 바이트 열을 문자열로 전환. utf-8
hrefs = re.findall('<a href="(.*?\.html)".*?>.+?</a>', shtml) # href 안에 있는 내용만 추출한다. .html로 끝나는 링크만 찾아낸다.
hrefs
# 각 링크의 절대 경로를 얻어낸다.
from urllib.parse import urljoin
for ref in hrefs:
print ('{} ==> {}'.format(ref, urljoin(root, ref)))
# 중복되는 경로는 제거하기로 한다.
full_refs = list(set([urljoin(root, ref) for ref in hrefs]))
full_refs
# 경로 분리 테스트
from urllib.parse import urlsplit
res = urlsplit('http://docs.python.org/2/copyright.html')
print (res)
print (res.path)
자 이제 모든 준비가 되었다. 위의 코드들을 조합해보자.
import os
import re # 26장 정규식 참조
from urllib.request import urlopen
from urllib.parse import urljoin
def savePage(root):
fpath = urlsplit(root).path[1:]
html = urlopen(root).read()
shtml = html.decode()
folder, fname = os.path.split(fpath)
if not os.path.exists(folder): # 필요하다면 디렉토리를 생성한다.
print ('making directory : ', folder)
os.makedirs(folder)
print ('saving..', fpath)
open(fpath, 'w').write(shtml)
return shtml
root = 'http://docs.python.org/2/howto/webservers.html'
shtml = savePage(root)
hrefs = re.findall('<a href="(.*?\.html)".*?>.+?</a>', shtml) # href 안에 있는 내용만 추출한다. .html로 끝나는 링크만 찾아낸다.
full_refs = list(set([urljoin(root, ref) for ref in hrefs]))
for ref in full_refs:
shtml = savePage(ref)