Jupyter notebook

1. 조건문

  • 특정 조건에 따라서 코드를 실행하고자 할때 사용
  • if, else, elif
1
2
3
4
5
# 조건부분에 bool 데이터 타입 이외의 테이터 타입이 오면 bool으로 형변환 되어 판단
if False:
print("python")

print("done")
done
1
2
# int : 0을 제외한 나머지 값은 True
bool(0), bool(1), bool(-1), bool(100)
(False, True, True, True)
1
2
3
4
5
6
7
8
num = 0

if num :
print("python_1")

num = 1
if num :
print("python_2")
python_2
1
2
3
4
number = 7

if number % 2:
print("홀수")
홀수
1
2
3
# float : 0.0을 제외한 나머지 실수는 True
# str : ""를 제외한 나머지 문자열은 True
# list, tuple, dict : [], (), {}를 제외한 나머지는 True
1
2
3
4
5
6
7
8
9
# 지갑에 돈이 10000원 이상 있으면 택시를 타고 그렇지 않으면 걸어서 집에 갑니다.
# 2000원 이상이면 버스
money = 5000

if money >= 10000:
print("택시")

if money < 10000:
print("걸어서")
택시
1
2
3
4
if money >= 10000:
print("택시")
else:
print("걸어서")
택시
1
2
3
4
5
6
if money >= 10000:
print("택시")
elif money > 2000:
print("버스")
else:
print("걸어서")
택시
1
2
3
4
5
# 계좌에 10000원이 들어 있다.
# 인출 금액을 입력 받습니다.
# 인출 금액이 계좌에 있는 금액보다 크면 "잔액 부족" 출력
# 아니면 "인출" 출력
# 마지막에 현재 잔액 출력
1
2
data = int(input("draw money: "))
type(data), data
draw money: 5000





(int, 5000)
1
10000 - data
5000
1
2
3
4
5
6
7
8
9
10
account = 10000
draw_money = int(input("insert draw money: "))

if account >= draw_money:
account -= draw_money
print(str(draw_money) + "원 출금")
else:
print("잔액 부족, "+ str(draw_money - account) + "원 부족")

print("현재 잔액 : " + str(account) + "원")
insert draw money: 5000
5000원 출금
현재 잔액 : 5000원
1
2
3
# string 데이터 타입의 format 함수
print("현재 잔액은 {}원, 인출금액은 {}원 입니다.".format(account, draw_money))
print("현재 잔액은 {data1}원, 인출금액은 {data2}원 입니다.".format(data2 = draw_money, data1 = account))
현재 잔액은 5000원, 인출금액은 5000원 입니다.
현재 잔액은 5000원, 인출금액은 5000원 입니다.
1
f'현재 {account}'
'현재 5000'

삼항연산자

  • 간단한 if, else 구문을 한줄의 코드로 표현할 수 있는 방법
  • (True) if (condition) else (False)
1
2
3
4
5
6
# data  변수에 0이면 "zero" 출력, 아니면 "not zero" 출력
data = 0
if data:
print("not zero")
else:
print("zero")
zero
1
2
3
data = 1
result = "not zero" if data else "zero"
result
'not zero'

2. 반복문

  • 반복되는 코드를 실행할 때 사용
  • while, for, break, continue
  • list comprehention
1
2
3
4
5
6
# while
data = 3
while data:# 조건이 False가 될때까지 구문의 코드를 실행
# 반복되는 코드
print(data)
data -= 1
3
2
1
1
2
3
4
5
6
7
8
# 무한루프
# break : 반복문을 중단 시킬때 사용되는 예약어
result = 1
while result:
if result >= 10:
break
result += 1
print(result)
10

for

  • iterable한 값을 하나씩 꺼내서 value에 대입시킨 후 코드를 iterable 변수의 값 갯수 만큼 실행
    1
    2
    for <variable> in <iterables>:
    <code>
1
2
3
4
5
6
7
# for : continue : 조건부분으로 올라가서 코드가 실행
ls = [0, 1, 2, 3, 4]
for data in ls: # data가 홀수면 continue 실행
if data % 2:
continue
# data가 짝수면 print 실행
print(data, end=" ")
0 2 4 
1
2
3
4
5
6
7
# for문을 이용하여 코드를 100번 실행
# range 함수
list(range(100))
result = 0
for data in range(100):
result += data
result
4950
1
2
# offset index 개념과 비슷하게 사용
list(range(5)), list(range(5, 10)), list(range(0, 10, 2)), list(range(10, 0, -2))
([0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [0, 2, 4, 6, 8], [10, 8, 6, 4, 2])
1
2
3
4
5
# 0~10 까지 짝수 합
result = 0
for number in range(0, 11, 2):
result += number
result
30
1
dict = {"one": 1, "two":2, "three":3}
1
2
3
# 키값만 출력
for data in dict:
print(data)
one
two
three
1
list(dict.items())
[('one', 1), ('two', 2), ('three', 3)]
1
2
for subject, point in dict.items():
print(subject, point)
one 1
two 2
three 3
1
2
3
4
5
# 구구단
for num2 in range(1, 10):
for num1 in range(2, 10):
print("{}*{}={}".format(num1, num2, num1*num2), end='\t')
print()
2*1=2    3*1=3    4*1=4    5*1=5    6*1=6    7*1=7    8*1=8    9*1=9    
2*2=4    3*2=6    4*2=8    5*2=10    6*2=12    7*2=14    8*2=16    9*2=18    
2*3=6    3*3=9    4*3=12    5*3=15    6*3=18    7*3=21    8*3=24    9*3=27    
2*4=8    3*4=12    4*4=16    5*4=20    6*4=24    7*4=28    8*4=32    9*4=36    
2*5=10    3*5=15    4*5=20    5*5=25    6*5=30    7*5=35    8*5=40    9*5=45    
2*6=12    3*6=18    4*6=24    5*6=30    6*6=36    7*6=42    8*6=48    9*6=54    
2*7=14    3*7=21    4*7=28    5*7=35    6*7=42    7*7=49    8*7=56    9*7=63    
2*8=16    3*8=24    4*8=32    5*8=40    6*8=48    7*8=56    8*8=64    9*8=72    
2*9=18    3*9=27    4*9=36    5*9=45    6*9=54    7*9=63    8*9=72    9*9=81    

3. list comprehention

  • 리스트 데이터를 만들어 주는 방법
  • for문 보다 빠르게 동작
1
2
3
4
5
6
# 각각 값에 제곡한 결과 출력
ls = [0, 1, 2, 3]
result = []
for data in ls:
result.append(data**2)
result
[0, 1, 4, 9]
1
2
result = [data**2 for data in ls]
result
[0, 1, 4, 9]
1
2
3
4
5
6
7
8
9
# 리스트 컴프리헨션을 써서 홀수와 짝수를 리스트로 출력해주는 코드
# 삼항연산 사용
ls = [0, 1, 2, 3]
result = ["짝수", "홀수", "짝수", "홀수"]

result = [
"홀수" if data % 2 else "짝수" for data in ls
]
result
['짝수', '홀수', '짝수', '홀수']
1
2
3
# 리스트 컴프리헨션 조건문
ls = range(10)
[data for data in ls if data % 2]
[1, 3, 5, 7, 9]
1
2
ls = [1, 2, 3]
[func for func in dir(ls) if func[:2] != "__" and func[0] == 'c']
['clear', 'copy', 'count']
1
# for문과 list comprehention 성능 비교
1
2
3
4
5
%%timeit
ls = []
for num in range(1, 10001):
ls.append(num)
len(ls)
785 µs ± 23.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1
2
3
%%timeit
ls = [num for num in range(1, 10001) if num % 3 == 0]
len(ls)
735 µs ± 3.17 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1

Jupyter notebook

함수

  • 반복되는 코드를 묶음으로 효율적인 코드를 작성하도록 해주는 기능
  • 기본 함수
  • 파라미터와 아규먼트
  • 리턴
  • ‘*args’, ‘**kwargs’
  • docstring
  • scope
  • inner function
  • lambda function
  • Map, Filter, Reduce
  • Decorlator

1. 기본함수

  • 함수의 선언과 호출
1
2
3
4
5
6
7
8
point = 88

if point >= 90:
print("A")
elif point >= 80:
print("B")
elif point >= 70:
print("C")
B
1
%reset
Once deleted, variables cannot be recovered. Proceed (y/[n])? y
1
%whos
Interactive namespace is empty.
1
2
3
4
5
6
7
8
# 함수 선언
def grade(point):
if point >= 90:
print("A")
elif point >= 80:
print("B")
elif point >= 70:
print("C")
1
2
a = 1
ls = [1, 2, 3]
1
%whos
Variable   Type        Data/Info
--------------------------------
a          int         1
grade      function    <function grade at 0x0000025592D26820>
ls         list        n=3
1
2
# 함수 호출
grade(88)
B
1
# code ...
1
grade(78)
C

2. 파라미터와 아규먼트

  • 파라미터 : 함수를 선언할때 호툴하는 부분에서 보내주는 데이터를 받는 변수
  • 아규먼트 : 함수를 호출할때 함수에 보내주는 데이터
1
2
def plus(num1, num2=10, num3=20): # 파라미터 : 디폴트 파라미터
print(num1 + num2 - num3)
1
plus(1, 2) # 아규먼트
3
1
plus(3) # 아규먼트
13
1
plus(3, num3=100) # 아규먼트 : 키워드 아큐먼트
-87
1
2
print(1, 2, end="-")
print(3)
1 2-3

3. 리턴

  • 함수를 실행한 결과를 저장하고 싶을때 사용
  • return
1
2
3
def plus(num1, num2):
print(num1+num2)
return num1+num2
1
2
result = plus(1, 2)
print(result)
3
3
1
2
3
data1 = "python"
result = data1.upper()
print(result)
PYTHON
1
2
3
data2 = [3, 1, 2]
result = data2.sort()
print(result)
None
1
2
3
4
5
# 함수에서 return 코드가 샐행되면 무조건 함수의 코드 실행이 종료
def echo(msg):
if msg == "quit":
return
print(msg)
1
echo("python")
python
1
echo("quit")

4. *args, **kwargs

  • 함수를 호출할때 아규먼트와 키워드 아규먼트의 갯수를 특정지을수 없을때 사용
1
2
3
4
def plus(*args, **kwargs):
print(type(args), args)
print(type(kwargs), kwargs)
return sum(args) + sum(list(kwargs.values()))
1
plus(1, 2, num1=3, num2=4)
<class 'tuple'> (1, 2)
<class 'dict'> {'num1': 3, 'num2': 4}





10
1
2
3
4
def func(num1, num2, num3):
return num1, num2, num3
data = [1, 2, 3]
func(*data) # func(1, 2, 3)
(1, 2, 3)
1
2
3
4
5
data = {
"num2": 100,
"num3": 200,
}
func(1, **data) # func(1, num2=100, num3=200)
(1, 100, 200)
1

Jupyter notebook

%reset error

  • ipython 버전을 downgrade
    • conda uninstall ipython
    • conda instapp ipython=7.2.0
    • conda install jupyter

함수 2

  • docstring
  • scope
  • inner function
  • lambda function
  • map, filter, reduce
  • decorlator

1. Docstring

  • 함수의 설명을 작성
1
2
3
4
5
6
7
8
9
10
def echo(msg):
"""
echo return its input agument
The operation is:
1. print msg
2. return msg parameter
param : msg : str
return str
"""
return msg
1
echo?
1
echo??
1
help(echo)
Help on function echo in module __main__:

echo(msg)
    echo return its input agument
    The operation is:
        1. print msg
        2. return msg parameter
    param : msg : str
    return str
1
print(echo.__doc__)
    echo return its input agument
    The operation is:
        1. print msg
        2. return msg parameter
    param : msg : str
    return str
    

2. Scope 범위

  • 함수 안에서 선언되는 변수와 한수 밖에서 선언되는 변수의 범위가 다릅니다.
  • global(전역), local(지역)
1
2
3
4
5
# global
gv = 10
def echo():
print(gv)
echo()
10
1
2
3
4
5
6
# global
gv = 10
def echo():
gv = 100
print(gv)
echo()
100
1
gv
10
1
2
3
4
5
6
7
8
# global
gv = 10
def echo():
global gv
gv = 100
print(gv)
echo()
gv # 100
100





100

3. Inner Function

  • 함수가 지역영역에 선언, 함수 안에 함수가 선언
1
2
3
4
5
6
def outer(a, b):

def inner(c, d):
return c + d

return inner(a, b)
1
outer(1,2)
3
1
inner(2, 3)
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-14-468e0d571ba5> in <module>
----> 1 inner(2, 3)


NameError: name 'inner' is not defined
1
2
3
4
5
6
def outer(a, b):

def inner(c, d):
return c + d

return inner
1
outer(1,2)(3, 4)
7
1
# callback function : 함수를 아규먼트 파라미터로 설정해서 사용
1
2
3
4
5
def calc(func, a, b):
# code
a **= 2
b **= 2
return func(a, b)
1
2
def plus(a, b):
return a + b
1
2
def minus(a, b):
return a - b
1
calc(plus, 1, 2) # 덧셈
5
1
calc(minus, 1, 2) # 뺄셈
-3

4. 람다함수

  • 파라미터를 간단한 계산으로 리턴되는 함수 : 삼항연산
1
2
def plus(a, b):
return a + b
1
plus(1, 2)
3
1
2
plus2 = lambda a, b: a + b
plus(1, 3)
4
1
2
# calc(func, a, b)
calc(lambda a, b: a + b, 3, 4)
25
1
calc(plus, 3, 4)
25

5. map, filter, reduce

  • map : 순서가 있는 데이터 집합에서 모든 값에 함수를 적용시킨 결과를 출력
1
2
3
4
5
ls = [1, 2, 3, 4]
def odd_even(num):
return "odd" if num%2 else "even"

odd_even(3), odd_even(4)
('odd', 'even')
1
list(map(odd_even, ls))
['odd', 'even', 'odd', 'even']
1
2
3
# input 함수로 구분자로  " "으로 여러개의 숫자를 입력 받습니다.
# str.split(" ") 리스트로 만들고
# 만들어진 리스트의 값들을 int 형변환
1
datas = input("insert numbers : ")
insert numbers : 10 20 30 40 50 60
1
2
result = datas.split(" ")
result
['10', '20', '30', '40', '50', '60']
1
2
result = list(map(int, result))
result
[10, 20, 30, 40, 50, 60]
1
# ctrl + alt + 드래그 : 여러줄 수정

Filter

  • 리스트 데이터에서 특정 조건에 맞는 value만 남기는 함수
1
ls = range(10)
1
2
# 홀수만 출력
list(filter(lambda data: True if data % 2 else False, ls))
[1, 3, 5, 7, 9]

Reduce

  • 리스트 데이터를 처음부터 순서대로 특정 함수를 실행하여 결과를 누적시켜 주는 함수
1
from functools import reduce
1
2
ls = [3, 1, 2, 4, 5]
reduce(lambda x, y : x + y, ls)
15

6. Decorlator

  • 함수에서 코드를 바꾸지 않고 기능을 추가하거나 수정하고 싶을때 사용하는 문법
1
2
3
4
5
6
7
8
9
10
def a():
code_1
code_2
code_3

def b():
code_1
code_2
code_3

  • 데코레이터의 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def c(func):
def wrapper(*args, **kwargs):
code_1
result = func(*args, **kwargs)
code_3
return result

return wrapper

@c
def a():
code_2

@c
def b():
code_4

1
2
3
4
5
6
# a
def plus(a, b):
print("start") # code_1
result = a+b # code_2
print(f'result : {result}') # code_3
return result
1
2
3
4
5
6
# b
def minus(a, b):
print("start") # code_1
result = a-b # code_4
print(f'result : {result}') # code_3
return result
1
2
3
4
5
6
7
8
# c
def disp(func):
def wrapper(*args, **kwargs):
print("start") # code_1
result = func(*args, **kwargs) # code_2, code_4
print(f'result : {result}') # code_3
return result
return wrapper
1
plus(1, 2)
start
result : 3





3
1
2
3
4
@disp
def plus(a, b):
result = a + b
return result
1
plus(1, 2)
start
result : 3





3
1
# 데코레이터를 이용해서 함수의 실행 시간을 출력
1
import time
1
2
3
4
5
6
7
8
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time() # code_1
result = func(*args, **kwargs) # code_2, code_4
end_time = time.time() # code_3
print("running time : {}".format(end_time - start_time)) # code 3
return result
return wrapper
1
2
3
4
@timer
def test1(num1, num2):
data = range(num1, num2)
return sum(data)
1
2
3
4
5
6
@timer
def test2(num1, num2):
result = 0
for num in range(num1, num2+1):
result += num
return result
1
test1(1, 100000)
running time : 0.003003358840942383





4999950000
1
test2(1, 100000)
running time : 0.005014657974243164





5000050000
1
# 패스워드를 입력 받아야 함수가 실행되도록하는 데코레이터 작성
1
import random
1
2
3
4
5
6
7
8
9
10
11
def check_password(func):
def wrapper(*args, **kwargs):
pw = "dss11"
# check password
input_pw = input("insert pw: ")
if input_pw == pw:
result = func(*args, **kwargs)
else:
result = "not allow!"
return result
return wrapper
1
2
3
@check_password
def plus(a, b):
return a+b
1
plus(1, 2)
insert pw: dss11





3
1
2
3
4
5
6
@check_password
def lotto_func():
lotto = list(range(1, 46))
lotto = random.sample(lotto, 6)
lotto.sort()
return lotto
1
lotto_func()
insert pw: dss11





[4, 11, 12, 23, 26, 45]
1
lotto_func()
insert pw: asdf





'not allow!'
1

Jupyter notebook

1
2
3
4
user_datas = [
{"user":"test", "pw":"1234", "count":0},
{"user":"python", "pw":"5678", "count":0},
]
1
2
3
4
5
ls = ["a", "b", "c"]
print(list(range(len(ls))))
print(list(zip(range(len(ls)), ls)))
for idx, data in list(zip(range(len(ls)), ls)):
print(idx, data)
[0, 1, 2]
[(0, 'a'), (1, 'b'), (2, 'c')]
0 a
1 b
2 c
1
list(enumerate(user_datas))
[(0, {'user': 'test', 'pw': '1234', 'count': 0}),
 (1, {'user': 'python', 'pw': '5678', 'count': 1})]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# user data를 입력 받아서 아이디와 패스워드를 체크하는 데코레이터 함수를 코드로 작성하세요.
# 로그인 될때마다 count를 1씩 증가
def need_login(func):
def wrapper(*args, **kwargs):
# 아이디 패스워드 입력
user, pw = tuple(input("insert user pw :").split(" "))
# 존재하는 아이디, 패스워드 확인
# for idx, user_data in zip(range(len(user_datas)), user_datas):
for idx, user_data in enumerate(user_datas):
if user_data["user"] == user and user_data["pw"] == pw:
# count 데이터 추가
user_datas[idx]["count"] += 1
# 함수 실행
return func(*args, **kwargs)
return "wrong login data!"

# 카운트 증가 및 함수 실행
return wrapper
1
2
3
@need_login
def plus(num1, num2):
return num1 + num2
1
plus(1, 2)
insert user pw :test 1234





3
1
user_datas
[{'user': 'test', 'pw': '1234', 'count': 1},
 {'user': 'python', 'pw': '5678', 'count': 2}]
1
2
3
4
# 스타크래프트의 마린을 클래스로 설계
# 체력(health) = 40, 공격력(attack_pow) = 5, 공격(attack())
# 마린 클래스로 마린 객체 2개를 생성해서 마린1이 마린2를 공격하는 코드를 작성
# attack(self, unit)
1
2
3
4
5
6
7
8
9
10
11
12
13
class Marine:

def __init__(self, health=40, attack_pow=5):
self.health = health
self.attack_pow = attack_pow

def attack(self, unit):
unit.health -= self.attack_pow
print(unit.health)
if unit.health <= 0:
unit.health = 0
print("사망")
pass
1
marine_1 = Marine()
1
marine_2 = Marine()
1
marine_1.attack(marine_2)
사망
1
marine_1.health, marine_2.health # 40, 35
(40, 0)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 메딕 : heal_pow, heal(unit)
class Medic:

def __init__(self, health = 40, heal_pow=6):
self.health = health
self.heal_pow = heal_pow

def heal(self, unit):
if unit.health > 0:
unit.health += self.heal_pow
if unit.health >=40:
unit.health = 40
else:
print("이미 사망")

1
medic = Medic()
1
marine_1.attack(marine_2)
사망
1
marine_1.health, marine_2.health
(40, 0)
1
medic.heal(marine_2)
이미 사망
1
marine_3 = Marine(attack_pow=25)
1
marine_3.attack(marine_1)
사망

1. 상속

  • 클래스의 기능을 가져다가 기능을 수정하거나 추가할때 사용하는 방법
1
2
3
4
5
6
7
class Calculator:
def __init__(self, num1, num2):
self.num1 = num1
self.num2 = num2

def plus(self):
return self.num1 + self.num2
1
2
calc = Calculator(1, 2)
calc.plus()
3
1
2
3
4
5
6
7
8
9
10
class Calculator2:
def __init__(self, num1, num2):
self.num1 = num1
self.num2 = num2

def plus(self):
return self.num1 + self.num2

def minus(self):
return self.num1 - self.num2
1
calc2 = Calculator2(1, 2)
-1
1
calc2.minus(), calc2.plus()
(-1, 3)
1
2
3
4
# 상속을 사용하여 minus 함수 추가
class Calculator3(Calculator):
def minus(self):
return self.num1 - self.num2
1
calc3 = Calculator3(1, 2)
1
calc3.plus(), calc3.minus()
(3, -1)
1
2
3
4
5
# 메서드 오버라이딩
class Calculator4(Calculator3):
def plus(self):
return self.num1**2 + self.num2**2

1
calc4 = Calculator4(1, 2)
1
calc4.plus()
5
1
2
3
4
# 아이폰 1, 2, 3
# 아이폰 1 : calling : print("calling")
# 아이폰 2 : send msg
# 아이폰 3 : internet
1
2
3
class iPhon1:
def calling(self):
print("calling")
1
2
3
class iPhon2(iPhon1):
def send_msg(self):
print("send_msg")
1
2
3
class iPhon3(iPhon2):
def internet(self):
print("internet")
1
iphon3 = iPhon3()
1
iphon3.calling(), iphon3.send_msg(), iphon3.internet()
calling
send_msg
internet





(None, None, None)
1
2
3
class Galuxy:
def show_img(self):
print("show_img")
1
2
3
class DssPhone(iPhon3, Galuxy):
def camera(self):
print("camera")
1
dss_phone = DssPhone()
1
[func for func in dir(dss_phone) if func[:2] != '__']
['calling', 'camera', 'internet', 'send_msg', 'show_img']

2. super

  • 부모 클래스에서 사용된 함수의 코드를 가져다가 자식 클래스의 함수에서 재사용할때 사용
1
2
3
4
5
6
7
8
class A:
def plus(self):
code1

class B(A):
def minus(self):
code1 # super().plus()
code2
1
2
3
4
5
6
7
8
9
10
class Marine:

def __init__(self):
self.health = 40
self.attack_pow = 5

def attack(self, unit):
unit.health -= self.attack_pow
if unit.health <= 0:
unit.health = 0
1
2
3
4
5
6
class Marine2(Marine):
def __init__(self):
# self.health = 40
# self.attack_pow = 5
super().__init__()
self.max_health = 40
1
marine = Marine2()
1
marine.health, marine.attack_pow, marine.max_health
(40, 5, 40)

3. class의 getter, setter

  • 객체의 내부 변수에 접근할때 특정 로직을 거쳐서 접근시키는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class User:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

def setter(self, first_name):
if len(first_name) >= 3:
self.first_name = first_name
else:
print("error")

def getter(self):
print("getter")
return self.first_name.upper()

def disp(self):
print(self.first_name, self.last_name)

name = property(getter, setter)
1
user1 = User("andy", "kim")
1
user1.first_name
'andy'
1
2
# getter 함수 실행
user1.name
getter





'ANDY'
1
2
# setter 함수 실행
user1.name = "john"
1
user1.name
getter





'JOHN'

4. non public

  • mangling 이라는 방법으로 다이렉트로 객체의 변수에 접근하지 못하게 하는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Calculator:
def __init__(self, num1, num2):
self.num1 = num1
self.__num2 = num2

def getter(self):
return self.__num2

def setter(self, num2):
num2 = 1 if num2 == 0 else num2
self.__num2 = num2

def __disp(self):
print(self.num1, self.__num2)

def div(self):
self.__disp()
return self.num1/self.__num2

number2 = property(getter, setter)
1
calc = Calculator(1, 2)
1
calc.div()
1 2





0.5
1
calc.number2
2
1
calc.number2 = 0
1
calc.num2 = 0
1
calc.div()
1 1





1.0
1
calc.__num2
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-200-9422eadacb85> in <module>
----> 1 calc.__num2


AttributeError: 'Calculator' object has no attribute '__num2'
1
calc._Calculator__num2
1
1
calc.__disp()
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-203-1997f957eed5> in <module>
----> 1 calc.__disp()


AttributeError: 'Calculator' object has no attribute '__disp'
1
calc._Calculator__disp()
1 1

5. is a & has a

  • 클래스를 설계하는 개념
  • A is a B
    • A 는 B이다. 상속을 이용해서 클래스를 만드는 방법
  • A has a B
    • A 는 B를 가진다. A는 B객체를 가지고 클래스를 만드는 방법
1
# 사람 : 이름, 이메일, 정보출력()
1
2
3
4
5
# is a
class Person:
def __init__(self, name, email):
self.name = name
self.email = email
1
2
3
class Person2(Person):
def info(self):
print(self.name, self.email)
1
p = Person2("andy", "andy@gmail.com")
1
p.info()
andy andy@gmail.com
1
2
3
4
5
6
7
# has a
class Name:
def __init__(self, name):
self.name_str = name
class Email:
def __init__(self, email):
self.email_str = email
1
2
3
4
5
6
class Person:
def __init__(self, name_obj, email_obj):
self.nmae = name_obj
self.email = email_obj
def info(self):
print(name.name_str, email.email_str)
1
2
3
name = Name("andy")
email = Email("andy@gmail.com")
p = Person(name, email)
1
p.info()
andy andy@gmail.com

Magic(Spacial) Method

  • compare
    • eq‘: ==
    • ne‘: !=
    • lt‘: <
  • calculate
    • add‘: +
    • sub‘: -
  • repr : 객체의 내용을 출력(개발자용)
  • str : 객체의 내용을 출력
1
"test" == "test"
True
1
"test".__eq__("test")
True
1
1+2
3
1
'1'+'2'
'12'
1
2
3
4
5
6
7
8
9
10
11
12
class Txt:
def __init__(self, txt):
self.txt = txt

def __eq__(self, txt_obj):
return self.txt.lower() == txt_obj.txt.lower()

def __repr__(self):
return "Txt(txt={})".format(self.txt)

def __str__(self):
return self.txt
1
2
3
t1 = Txt("python")
t2 = Txt("PYTHON")
t3 = t1
1
t1 == t2, t1 == t3, t2 == t3
(True, True, True)
1
t1 
Txt(txt=python)
1
print(t1)
python
1
range(0, 5)
range(0, 5)
1
2
3
4
5
6
7
8
9
10
11
12
13
# Integer 객체
class Integer:
def __init__(self, number):
self.number = number

def __add__(self, obj):
return self.number + obj.number

def __str__(self):
return str(self.number)

def __repr__(self):
return str(self.number)
1
2
3
num1 = Integer(1)
num2 = Integer(2)
num1 + num2
3
1
num1
1
1
num2
2
1
2
3
# 계좌 클래스 만들기
# 변수 : 자산(asset), 이자율(interest)
# 함수 : 인출(draw), 입금(insert), 이자추가(add_interest)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Account:

def __init__(self, asset=0, interest=1.05):
self.asset = asset
self.interest = interest

def draw(self, money):
if self.asset >= money:
self.asset -= money
print("출금 : {}원".format(money))
else:
print("금액부족 : {}원".format(money-self.asset))

def insert(self, money):
self.asset += money
print("{}원 입금".format(money))

def add_interest(self):
self.asset *= self.interest
print("이자 지급")

def __repr__(self):
return "Account(asset:{}, interest:{})".format(self.asset, self.interest)
1
account1 = Account(10000)
1
account1
Account(asset:10000, interest:1.05)
1
account1.draw(12000)
금액부족 : 2000원
1
account1.insert(2000)
2000원 입금
1
account1
Account(asset:12000, interest:1.05)
1
account1.add_interest()
이자 지급
1
account1
Account(asset:12600.0, interest:1.05)
1

Jupyter notebook

class : 클래스

  • 변수와 함수를 묶어 놓은 개념
  • 사용 방법
    • 변수와 함수가 들어있는 클래스를 선언
    • 클래스를 객체로 만들어서 클래스 안에 선언된 변수와 함수를 사용

1. 기본 클래스의 사용

1
2
3
4
5
6
7
8
9
10
# 클래스의 선언
class Calculator:
num1 = 1
num2 = 2

def plus(self):
return self.num1 + self.num2

def minus(self):
return self.num1 - self.num2
1
2
3
# 클래스의 사용
calc = Calculator()
calc
<__main__.Calculator at 0x1d17368fca0>
1
calc.num1, calc.num2, calc.plus(), calc.minus()
(1, 2, 3, -1)
1
2
# self의 의미 : 객체 자신
calc2 = Calculator()
1
calc2.num1 = 10
1
calc2.plus()
12

2. 객체지향

  • 실체 세계를 코드에 반영해서 개발하는 방법
  • 여러명의 개발자가 코드를 효율적으로 작성해서 프로젝트를 완성시키기 위한 방법
  • 설계도 작성(class) -> 실제 물건(object)
  • 사용자 정의 데이터 타입
1
calc2.plus()
12
1
2
obj = "python"
obj.upper()
'PYTHON'
1
2
ls = [1, 3, 2]
ls.sort()
1
ls
[1, 2, 3]
1
[data for data in dir(calc) if data[:2] != '__']
['minus', 'num1', 'num2', 'plus']

3. 생성자

  • 클래스가 객체로 생성될때 실행되는 함수
  • 변수(재료)를 추가할때 사용됩니다.
1
2
3
4
5
6
7
8
9
10
11
class Calculator:
# 생정자 함수 : __init__
def __init__(self, num1, num2=10):
self.num1 = num1
self.num2 = num2

def plus(self):
return self.num1 + self.num2

def minus(self):
return self.num1 - self.num2
1
calc1 = Calculator(3)
1
calc1.plus()
13
1
calc2 = Calculator(3, 5)
1
calc2.plus()
8
1
2
3
4
# join
ls = ["python", "is", "good"]
sep = " "
sep.join(ls)
'python is good'
1
2
# pandas dataframe
import pandas as pd
1
2
3
4
5
df = pd.DataFrame([
{"name":"jin", "age":20},
{"name":"andy", "age":21},
])
df

name age
0 jin 20
1 andy 21
1

Jupyter notebook

Module Package

  • 모듈 : 변수와 함수, 클래스를 모아놓은 (.py) 확장자를 가진 파일
  • 패키지 : 모듈의 기능을 디렉토리별로 정리해 놓은 개념

1. 모듈

  • 모듈 생성
  • 모듈 호출
1
2
3
4
5
6
7
8
9
10
11
12
13
%%writefile dss.py

num = 1234

def disp1(msg):
print("disp1", msg)

def disp2(msg):
print("disp2", msg)

class Calc:
def plus(self, *args):
return sum(args)
Writing dss.py
1
!ls
01_jupyter_notebook.ipynb
02_basic_syntax.ipynb
03_condition_loop.ipynb
04_function.ipynb
05_function_2.ipynb
06_class_1.ipynb
07_class_2.ipynb
08_module_package.ipynb
dss.py
1
%reset
Once deleted, variables cannot be recovered. Proceed (y/[n])? y
1
%whos
Interactive namespace is empty.
1
2
# 모듈 호출 : import
import dss
1
%whos
Variable   Type      Data/Info
------------------------------
dss        module    <module 'dss' from 'C:\\Code\\01_python\\dss.py'>
1
dss.num
1234
1
dss.disp1("python")
disp1 python
1
calc = dss.Calc()
1
calc.plus(1,2,3,4)
10
1
import random
1
random.randint(1, 5)
1
1
# 모듈 안에 특정 함수, 변수, 클래스 호출
1
from dss import num, disp2
1
%whos
Variable   Type        Data/Info
--------------------------------
calc       Calc        <dss.Calc object at 0x0000026C12554340>
disp2      function    <function disp2 at 0x0000026C12626670>
dss        module      <module 'dss' from 'C:\\Code\\01_python\\dss.py'>
num        int         1234
random     module      <module 'random' from 'C:<...>aconda3\\lib\\random.py'>
1
dss.num
1234
1
num
1234
1
%reset
Once deleted, variables cannot be recovered. Proceed (y/[n])? y
1
from dss import *
1
%whos
Variable   Type        Data/Info
--------------------------------
Calc       type        <class 'dss.Calc'>
disp1      function    <function disp1 at 0x0000026C12626940>
disp2      function    <function disp2 at 0x0000026C12626670>
num        int         1234

2. Package

  • 패키지 생성
  • 패키지 호출
  • setup.py 패키지 설치 파일 만들기
1
# 디렉토리 생성
1
!mkdir -p school/dss
The syntax of the command is incorrect.
1
!mkdir -p school/web
The syntax of the command is incorrect.
1
!tree school
Folder PATH listing for volume Windows10
Volume serial number is E625-BBFB
C:\CODE\01_PYTHON\SCHOOL
├───dss
└───web
1
2
# 패키지 사용시 디렉토리에 __init__.py 파일을 추가
# python 3.3 버전 이상에서는 필요없음
1
2
!touch school/dss/__init__.py
!touch school/web/__init__.py
1
!tree school
Folder PATH listing for volume Windows10
Volume serial number is E625-BBFB
C:\CODE\01_PYTHON\SCHOOL
├───dss
└───web
1
2
3
4
5
%%writefile school/dss/data1.py

def plus(*args):
print("data1")
return sum(args)
Writing school/dss/data1.py
1
2
3
4
5
%%writefile school/dss/data2.py

def plus2(*args):
print("data2")
return sum(args)
Writing school/dss/data2.py
1
2
3
4
%%writefile school/web/url.py

def make(url):
return url if url[:7] == "http://" else "http://" + url
Writing school/web/url.py
1
!tree school/
Folder PATH listing for volume Windows10
Volume serial number is E625-BBFB
C:\CODE\01_PYTHON\SCHOOL
├───dss
└───web
1
%reset
Once deleted, variables cannot be recovered. Proceed (y/[n])? y
1
import school.dss.data1
1
whos
Variable   Type      Data/Info
------------------------------
school     module    <module 'school' (namespace)>
1
school.dss.data1.plus(1,2,3)
data1





6
1
import school.dss.data1 as dss
1
dss.plus(1,2)
data1





3
1
2
3
# school.web : 디렉토리
# url : 모듈
from school.web import url
1
url.make("google.com")
'http://google.com'
1
url.make("naver.com")
'http://naver.com'
1
# 패키지의 위치 : 특정 디렉토리에 있는 패키지는 어디에서나 import 가능
1
import random
1
!ls
01_jupyter_notebook.ipynb
02_basic_syntax.ipynb
03_condition_loop.ipynb
04_function.ipynb
05_function_2.ipynb
06_class_1.ipynb
07_class_2.ipynb
08_module_package.ipynb
__pycache__
dss.py
school
1
2
3
4
import sys

for path in sys.path:
print(path)
C:\Code\01_python
C:\Users\USER\anaconda3\python38.zip
C:\Users\USER\anaconda3\DLLs
C:\Users\USER\anaconda3\lib
C:\Users\USER\anaconda3

C:\Users\USER\anaconda3\lib\site-packages
C:\Users\USER\anaconda3\lib\site-packages\win32
C:\Users\USER\anaconda3\lib\site-packages\win32\lib
C:\Users\USER\anaconda3\lib\site-packages\Pythonwin
C:\Users\USER\anaconda3\lib\site-packages\IPython\extensions
C:\Users\USER\.ipython
1
2
packages = !ls C:\Users\USER\anaconda3\lib
len(packages)
207
1
packages[-5:]
['xml', 'xmlrpc', 'zipapp.py', 'zipfile.py', 'zipimport.py']
1
2
# setup.py 를 작성해서 패키지를 설치해서 사용
# setuptools를 이용
1
!tree school/
Folder PATH listing for volume Windows10
Volume serial number is E625-BBFB
C:\CODE\01_PYTHON\SCHOOL
├───dss
│   └───__pycache__
└───web
    └───__pycache__
1
2
3
%%writefile school/dss/__init__.py

__all__ = ["data1", "data2"]
Overwriting school/dss/__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
%%writefile school/setup.py

from setuptools import setup, find_packages

setup(
nume="dss",
packages=find_packages(),
include_package_data=True,
version="0.0.1",
author_email="manimahn12@gmail.com"
zip_safe=False
)
Overwriting school/setup.py
1
!rm dss.py
1
# 패키지 설치 확인
1
!pip list | grep dss # dss가 들어간 패키지 확인
grep: #: No such file or directory
grep: dss媛�: No such file or directory
grep: �뱾�뼱媛�: No such file or directory
grep: �뙣�궎吏�: No such file or directory
grep: �솗�씤: No such file or directory
ERROR: Pipe to stdout was broken
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp949'>
OSError: [Errno 22] Invalid argument
1
2
3
4
5
# 패키지 설치
# school $ python setup.py develop
# 커널 리스타트
# develop : 개발자모드, 코드를 수정하면 설치된 패키지도 같이 수정
# build : 일반모드, 코드를 수정하면 다시 설치해야 수정된 코드가 적용
1
!pip list | grep dss
1
!pip list | grep numpy
numpy                              1.19.2
numpydoc                           1.1.0
1
from dss import *
1
%whos
Variable   Type      Data/Info
------------------------------
dss        module    <module 'school.dss.data1<...>\\school\\dss\\data1.py'>
np         module    <module 'numpy' from 'C:\<...>ges\\numpy\\__init__.py'>
packages   SList     ['__future__.py', '__phel<...>file.py', 'zipimport.py']
path       str       C:\Users\USER\.ipython
random     module    <module 'random' from 'C:<...>aconda3\\lib\\random.py'>
school     module    <module 'school' (namespace)>
sys        module    <module 'sys' (built-in)>
url        module    <module 'school.web.url' <...>on\\school\\web\\url.py'>
1
data1.plus(1,2)
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-64-572e254ac59d> in <module>
----> 1 data1.plus(1,2)


NameError: name 'data1' is not defined
1
2
# uninstall
# pip uninstall dss
1
!pip list | grep dss
1

Try Except

예외처리

  • 코드를 실행중에 에러가 발생한 경우 에러를 처리하는 방법
  • try, except, finally, raise
1
2
# try, except : 에러가 발생해도 코드의 실행을 계속하고 싶을때
ls = [1, 2, 3]
1
2
print(ls[3])
print("Done!")
---------------------------------------------------------------------------

IndexError                                Traceback (most recent call last)

<ipython-input-4-f88f334466aa> in <module>
----> 1 print(ls[3])
      2 print("Done!")


IndexError: list index out of range
1
2
3
4
5
6
try:
print(ls[3])
except Exception as e:
print("error")
print(e)
print("Done")
error
list index out of range
Done
1
2
3
4
5
6
7
# finally : try, except 구문 실행된 후 finally 구문이 실행
try:
1/0
except:
print("error")
finally:
print("Done!")
error
Done!
1
# raise : 강제로 에러를 발생시키는 명령
1
2
3
4
5
6
7
try:
1/0
except Exception as e:
print("error")
raise(e)

print("Done!")
error



---------------------------------------------------------------------------

ZeroDivisionError                         Traceback (most recent call last)

<ipython-input-9-bcde7d6d4636> in <module>
      3 except Exception as e:
      4     print("error")
----> 5     raise(e)
      6 
      7 print("Done!")


<ipython-input-9-bcde7d6d4636> in <module>
      1 try:
----> 2     1/0
      3 except Exception as e:
      4     print("error")
      5     raise(e)


ZeroDivisionError: division by zero
1
2
# 에러 생성 : 10이상의 숫자가 입력되도록 하는 에러
# LowNumber
1
2
3
4
class LowNumber(Exception):

def __str__(self):
return "Number grater than 10"
1
2
3
4
def input_number(num):
if num <= 10:
raise LowNumber()
print(num)
1
input_number(8)
---------------------------------------------------------------------------

LowNumber                                 Traceback (most recent call last)

<ipython-input-15-8684a0e33c0b> in <module>
----> 1 input_number(8)


<ipython-input-13-2dcc4faaa999> in input_number(num)
      1 def input_number(num):
      2     if num <= 10:
----> 3         raise LowNumber()
      4     print(num)


LowNumber: Number grater than 10
1

hexo gitblog 만들기

목차

개요
1.파일 설치
2.깃허브 설정
3.블로그 만들기
4.깃허브에 배포하기
5.테마 설정하기
6.다른 환경에서 작업하기

개요

  • Hexo 블로그를 만들어 본다.

파일 설치

  • 1단계 : nodejs.org 다운로드
    • 설치가 되었는지 확인해본다.
1
$ node -v
  • 2단계 : git-scm.com 다운로드
    • 설치가 되었는지 확인해본다.
1
$ git --version
  • 3단계 : hexo 설치
    • npm을 통해 hexo를 설치한다.
1
$ npm install -g hexo-cli

깃허브 설정

  • 두개의 깃허브 Repo를 생성한다.
    • 포스트 버전관리 (name : myblog)
    • 포스트 배포용 관리 (name : USERNAME.github.io)
    • USERNAME 대신에 본인의 username을 입력하면 된다.
  • 생성 후, myblog repogit clone을 통해 적당한 경로에 내려 받는다.
1
$ git clone your_git_repo_address.git

블로그 만들기

  • 내려받은 myblog의 경로를 찾아 들어간다.
  • myblog폴더 안에 임의의 블로그 파일명을 만든다.
1
2
3
4
5
$ hexo init gitblog # 임의의 파일명
$ cd gitblog
$ npm install
$ npm install hexo-server --save
$ npm install hexo-deployer-git --save
  • _config.yml 파일 수정
    • 싸이트 정보 수정
1
2
3
4
title: 제목을 지어주세요
subtitle: 부제목을 지어주세요
description: description을 지어주세요
author: YourName
  • 블로그 URL 정보 설정
1
2
3
4
url: https://USERNAME.github.io
root: /
permalink: :year/:month/:day/:title/
permalink_defaults:
  • 깃허브 연동
1
2
3
4
5
# Deployment
deploy:
type: git
repo: https://github.com/USERNAME/USERNAME.github.io.git
branch: main

깃허브에 배포하기

  • 배포 전, 로컬환경에서 블로그가 뜨는지 확인해본다.
1
2
3
4
$ hexo generate
$ hexo server
INFO Start processing
INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.
  • 확인이 되면 깃허브에 배포한다.

  • 사전에, gitignore 파일에서 아래와 같이 설정을 진행한다.

1
2
3
4
5
6
7
.DS_Store
Thumbs.db
db.json
*.log
node_modules/
public/
.deploy*/
  • 최종적으로 배포을 진행한다.
1
$ hexo deploy
  • 배포가 완료가 되면 브라우저에서 USERNAME.github.io로 접속해 정상적으로 배포가 되었는지 확인한다.

테마 설정하기

  • ICARUS 테마로 변경
1
$ git submodule add https://github.com/ppoffice/hexo-theme-icarus.git themes/icarus
  • ICARUS 테마 파일을 themes 폴더 안에 이식하는 코드다.

  • 그 다음, _config.yml에서 theme: icarus로 변경한다.

  • 그 다음, hexo server 실행 시, 에러가 날 것이다.

      - 에러 예제
    
1
2
3
4
5
6
7
ERROR Package bulma-stylus is not installed.
ERROR Package hexo-component-inferno is not installed.
ERROR Package hexo-renderer-inferno is not installed.
ERROR Package inferno is not installed.
ERROR Package inferno-create-element is not installed.
ERROR Please install the missing dependencies your Hexo site root directory:
ERROR npm install --save bulma-stylus@0.8.0 hexo-component-inferno@^0.2.4 hexo-renderer-inferno@^0.1.3 inferno@^7.3.3 inferno-create-element@^7.3.3
  • 위와 같은 에러가 발생하면, 출력되는 에러 문구에 따라 패키지들을 설치한다.
1
2
3
4
5
6
7
$ npm install bulma-stylus
$ npm install hexo-component-inferno
$ npm install hexo-renderer-inferno
$ npm install inferno
$ npm install inferno-create-element
$ npm install --save bulma-stylus@0.8.0 hexo-component-inferno@^0.4.0 hexo-renderer-inferno@^0.1.3 inferno@^7.3.3 inferno-create-element@^7.3.3
$ hexo server # 로컬에서 확인
  • 로컬 테스트가 완료되면, 깃허브로 배포를 진행한다.
1
$ hexo deploy --generate
  • 마지막으로, 포스트 버전관리를 위해 수정된 내용을 깃허브에 업데이트를 진행한다.
1
2
3
$ git add .
$ git commit -m "add: new post updated"
$ git push origin master

다른 환경에서 작업하기

  • 새로운 위치에 myblogclone해 준다.

  • myblog폴더 안에 gitblog폴더 로 이동 후, hexo server로 확인을 하면 에러가 날 것이다.

      - 에러 예제
    
1
2
3
ERROR Cannot find module 'hexo' from 'C:\myblog\gitblog'
ERROR Local hexo loading failed in C:\myblog\gitblog
ERROR Try running: 'rm -rf node_modules && npm install --force'
  • 출력된 문구에 따라 실행해 준다.
1
2
rm -rf node_modules && npm install --force
hexo server
  • 로컬에서 확인이 완료되면 블로그 작업을 한다.

  • 블로그 작업이 끝나면, 위와 같이 deploy로 배포하고, 깃허브에 push해 업데이트 까지 완료해준다.