Decorater, Class


In [4]:
def word_replace2(sentence, old_word, new_word):
    word_list = [i for i in sentence]
    a = ""
    for i in range (len(sentence)):
        if functools.reduce(
            lambda x, y: x+y, word_list[i:i+len(old_word)]) == old_word:
                a += new_word
                for j in range(len(old_word)):
                    word_list[i+j] = ""
        else:
            a += word_list[i]
    return a

In [5]:
word_replace2("슬로슬로우캠퍼스슬로우","슬로우","slow")


Out[5]:
'슬로slow캠퍼스slow'

3번 문제였던 Calendar


In [6]:
def calendar(month, day):
    common_year = [
        31,
        28,
        31,
        30,
        31,
        30,
        31,
        31,
        30,
        31,
        30,
        31
    ]
    
    leap_year = [
        31,
        29,
        31,
        30,
        31,
        30,
        31,
        31,
        30,
        31,
        30,
        31
    ]
    changed_day = {
        0: "목요일",
        1: "금요일",
        2: "토요일",
        3: "일요일",
        4: "월요일",
        5: "화요일",
        6: "수요일"
    }
    
    temp_days = 0
    
    if (2016 % 4 == 0 and 2016 % 100 != 0) or 2016 % 400 == 0:
        for i in range(month-1):
            temp_days += leap_year[i]
        temp_days += day
    else:
        for i in range(month-1):
            temp_days += common_year[i]
        temp_days += day
        
    for key, value in changed_day.items():
        if temp_days % 7 == key:
            print("{value}".format(value=value))
            
calendar(7, 12)


화요일

In [7]:
def is_leap_year(year):
    return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0

def calendar(month, day):
    common_year = [
        31,
        28 + int(is_leap_year(2016)),
        31,
        30,
        31,
        30,
        31,
        31,
        30,
        31,
        30,
        31
    ]
    
    date_list = ["목", "금", "토", "일", "월", "화", "수"]
    
    changed_day = {}
    for i in range(7):
        changed_day[i] = date_list[i] + "요일"
        
    temp_days = 0
    
    if is_leap_year(2016):
        for i in range(month-1):
            temp_days += common_year[i]
    else:
        for i in range(month-1):
            temp_days += common_year[i]
            
    temp_days += day
    return changed_day[temp_days % 7]

calendar(7, 12)


Out[7]:
'화요일'

In [8]:
import functools

def check_same_keyword(keyword, keyword_dict):
    for key in keyword_dict:
        if key == keyword:
            return True
    return False

def histogram(keyword_list):
    
    keyword_dict = {}
    
    # make dict
    for keyword in keyword_list:
#         if not check_same_keyword(keyword, keyword_dict):
#            keyword_dict[keyword] = 0
#         keyword_dict[keyword] += 1
        if not keyword_dict.get(keyword):
            keyword_dict[keyword] = 0
        keyword_dict[keyword] += 1
    return keyword_dict

def disp_histogram(keyword_dict):
    
    max_length = 0
    
    # find max_length
    for keyword in keyword_dict:
        if len(keyword) > max_length:
            max_length = len(keyword)
            
    # using reduce
    max_length = len(functools.reduce(    
        lambda x,y:x if len(x) > len(y) else y,
        keyword_dict
    ))
    
    # display kyword_dict
    for keyword, count in keyword_dict.items():
        count_str = "=" * count
        space = max_length - len(keyword) + 4
        whitespace = " " * space
        print("{keyword}{whitespace}{count_str}"
            .format(keyword=keyword, whitespace=whitespace, count_str=count_str
        ))

keyword_dict = histogram(["fast","fast", "campus", "fastcampus", "fast", "track", "asia", "track", "asia"])
disp_histogram(keyword_dict)
print(keyword_dict)

# keyword_dict.get("fast", 0) 키워드가 없으면 0을 리턴


track         ==
fastcampus    =
campus        =
asia          ==
fast          ===
{'track': 2, 'fastcampus': 1, 'campus': 1, 'asia': 2, 'fast': 3}

In [9]:
import functools


def histogram(keyword_list):
    keyword_dict = {}
    for keyword in keyword_list:        
        if not keyword_dict.get(keyword):
            keyword_dict[keyword] = 0
        keyword_dict[keyword] += 1
        
    return keyword_dict


def disp_keyword_str(keyword_dict):
    
    max_length = len(functools.reduce(lambda x,y: x if len(x)>len(y) else y, keyword_dict))    
        
    for key, value in keyword_dict.items():
        space = " " * (max_length - len(key) + 4) 
        count = "=" * value
        print("{key}{space}{count}".format(
            key=key, space=space, count=count
        ))

keyword_dict = histogram(["fast", "fast", "campus", "fastcampus", "fast", "track", "asia"])
print(keyword_dict)
disp_keyword_str(keyword_dict)


{'track': 1, 'fastcampus': 1, 'campus': 1, 'asia': 1, 'fast': 3}
track         =
fastcampus    =
campus        =
asia          =
fast          ===

In [10]:
def fibonacci(n):
    # 현재값(i), 이전의 피보나치값(i-1) => i+1 
    prev_n, cur_n = 0, 1
    i=1
    
    while i<n:
        # temp_n 가 필요없이 바로 관계가 있는 2개의 값을 바꿀 수 있습니다.
        """
        temp_n = cur_n
        cur_n = cur_n + prev_n
        prev_n = temp_n
        """
        cur_n, prev_n = cur_n + prev_n, cur_n  
        i += 1
    return cur_n

In [11]:
fibonacci(7)


Out[11]:
13

In [12]:
# 공민서 님이 푼 방법
def fibonacci_re(x):
    if x <= 0:
        return 0
    if x == 1:
        return 1
    return fibonacci_re(x-1) + fibonacci_re(x-2)

In [13]:
fibonacci_re(5)


Out[13]:
5

In [14]:
memo = []
len(memo)


Out[14]:
0

In [15]:
#  1 2 3 4 5 6 7 8   9.... 메모의 길이
# [0 1 2 3 4 5 6 7   8 ...] 
# [0,1,1,2,3,5,8,13,21....] 피보나치 수열의 결과값

def fibonacci_dp(x):
    if x <= 0:
        return 0
    if x == 1:
        return 1
    if len(memo)-1 >= x:
        return memo[x]
    if len(memo)-1 < x:
        new_number = fibonacci_dp(x-1) + fibonacci_dp(x-2)
        memo.append(new_number)
        return new_number

In [16]:
fibonacci_dp(5)


Out[16]:
6

In [17]:
memo


Out[17]:
[1, 2, 1, 3, 6]

In [18]:
# 각각의 시간을 측정하는 함수를 만들어보겠습니다.
import time
time.time()


Out[18]:
1470724736.7656944

In [19]:
start_time = time.time()
fibonacci_re(30)
end_time = time.time()

end_time - start_time


Out[19]:
1.176649570465088

In [20]:
start_time = time.time()
fibonacci_dp(30)
end_time = time.time()

end_time - start_time


Out[20]:
0.0

In [21]:
def get_timer(function, n):
    start_time = time.time()
    function(n)
    end_time = time.time()
    return end_time - start_time

In [22]:
get_timer(fibonacci_re, 30)


Out[22]:
1.1506462097167969

In [23]:
get_timer(fibonacci_dp, 30)


Out[23]:
0.0

다시 데코레이터

  • 데코레이터 어떤 순서로 되는 지 다시 복습
  • 먼저 fibonacci(20) 실행 시키면서 동시에 timer가 실행되게끔
  • decorator("장식자" X)

In [24]:
# 함수를 입력 받아 => 새로운 함수를 리턴하는 함수

def get_timer(function):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = function(*args, **kwargs)
        end_time = time.time()
        print("{time}s 초 걸렸습니다.".format(time=end_time-start_time))
        return result
    return wrapper

In [25]:
@get_timer
def fibonacci_dp(x):
    if x <= 0:
        return 0
    if x == 1:
        return 1
    if len(memo)-1 >= x:
        return memo[x]
    if len(memo)-1 < x:
        new_number = fibonacci_dp(x-1) + fibonacci_dp(x-2)
        memo.append(new_number)
        return new_number

In [26]:
fibonacci_dp(20)   #get_timer함수에 들어가서 wrapper라는 함수 실행한 것


0.0s 초 걸렸습니다.
Out[26]:
12543

In [27]:
#흔히 사용하는 예제
def fridge(function):
    def wrapper(*args, **kwargs):
        print("냉장고를 연다.")
        function(*args, **kwargs)
        print("냉장고를 닫는다.")
    return wrapper

In [28]:
@fridge
def put_fridge(food):
    print("{food}을 냉장고에 넣는다.".format(food=food))

In [29]:
put_fridge("족발")


냉장고를 연다.
족발을 냉장고에 넣는다.
냉장고를 닫는다.

In [30]:
fridge("족발")


Out[30]:
<function __main__.fridge.<locals>.wrapper>

In [ ]:


In [31]:
# @before_execute => "_____ 함수를 실행을 시작합니다."
def before_execute(function):
    def wrapper(*args, **kwargs):
        print("@before_execute")
        print("{function}을 실행합니다.".format(function=function))
        return function(*args, **kwargs)
    return wrapper

# @after_execute => "_____ 함수 실행을 종료합니다."
def after_execute(function):
    def wrapper(*args, **kwargs):
        print("@after_execute")
        result = function(*args, **kwargs)
        print("{function}을 종료합니다.".format(function=function))
        return result
    return wrapper

# @timer => "_____ s 초 걸렸습니다."
def timer(function):
    def wrapper(*args, **kwargs):
        print("@timer")
        start_time = time.time()
        result = function(*args, **kwargs)
        end_time = time.time()
        print("{time}s가 소요되었습니다.".format(time=end_time-start_time))
        return result
    return  wrapper

In [32]:
@timer
@after_execute
@before_execute   #decorater의 실행 순서는 밑에서부터 시작합니다.
def something():
    print("something")
    return "This is something"

In [33]:
# something 함수를 실행합니다.
# ...
# something 함수를 종료합니다.
# something 함수를 실행하는데 ____s 걸렸습니다.
something()


@timer
@after_execute
@before_execute
<function something at 0x000000000A9FCBF8>을 실행합니다.
something
<function before_execute.<locals>.wrapper at 0x000000000A9FC7B8>을 종료합니다.
0.0s가 소요되었습니다.
Out[33]:
'This is something'

In [ ]:


In [34]:
# 서식 함수
def bold(function):
    def wrapper(*args, **kwargs):
        return "<b>{text}<\b>".format(
            text=function(*args, **kwargs)
        )
    return wrapper

def italic(function):
    def wrapper(*args, **kwargs):
        return "<i>{text}<\i>".format(
            text=function(*args, **kwargs)
        )
    return wrapper

In [35]:
@italic
@bold
def introduce(name, course):
    return "안녕하세요, 저는 {name} 입니다. {course} 에서 공부하고 있습니다.".format(
        name=name,
        course=course,
    )

In [36]:
introduce("김기표", "패캠")


Out[36]:
'<i><b>안녕하세요, 저는 김기표 입니다. 패캠 에서 공부하고 있습니다.<\x08><\\i>'

In [ ]:


In [37]:
def prettify(function):
    def wrapper(*args, **kwargs):
        result = function(*args, **kwargs)
        return result.replace("오", "5").replace("칠", "7").replace("삼","3").replace("육", "6")
    return wrapper

In [38]:
@prettify
def crawl_phonenumber(naver_cafe_name, naver_cafe_post_id):
    # 어떤 식으로 크롤링이 되어서...
    return "010-6235-삼삼오칠"

crawl_phonenumber("중고나라", "34567")


Out[38]:
'010-6235-3357'

5T_Class Inheritance


In [39]:
class Student():
    
    def __init__(self, name):
        self.name = name
    
    def coding(self):
        print("일반 학생은 코딩을 할 수 없습니다.")

In [40]:
student = Student("김기표")

In [41]:
student.coding()


일반 학생은 코딩을 할 수 없습니다.

In [42]:
class Student():
    
    def __init__(self, name):
        self.name = name
        
    def study(self):
        print("공부를 합니다.")
    
    def introduce(self):
        print("안녕하세요, 저는 {name}입니다.".format(name=self.name))

In [43]:
student = Student("김기표")
student.study()
student.introduce()


공부를 합니다.
안녕하세요, 저는 김기표입니다.

In [44]:
class WPSstudent(Student):
    
    def introduce(self):
        print("안녕하세요, 저는 웹프스 {name}입니다.".format(
            name=self.name))
    
    def coding(self):   #Class의 함수=>Method(메쏘드)=>겹쳐 쓰는 행위? 메쏘드 오버라이딩
        print("vim과 bash를 이용해서 웹개발을 합니다.")
        
class DSSstudent(Student):
    
    def introduce(self):
        print("안녕하세요, 저는 데사스 {name}입니다.".format(
            name=self.name))
    
    def coding(self):
        print("Jupyter Notebook에서 pandas 라이브러를 이용하여 분석을 합니다.")

In [45]:
student = WPSstudent("지형민")
student.introduce()
student.coding()
student.study()


안녕하세요, 저는 웹프스 지형민입니다.
vim과 bash를 이용해서 웹개발을 합니다.
공부를 합니다.

In [46]:
#명단이 삭제되어 없지만 이런식으로 하면 됩니다.
with open("../wps.csv", "r") as f:
    wps_student_list = [
        WPSstudent(line.split(",")[0])
        for line
        in f.readlines()
    ]
    
with open("../dss.csv", "r") as f:
    dss_student_list = [
        DSSstudent(line.split(",")[0])
        for line
        in f.readlines()
    ]


---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
<ipython-input-46-074351dbed25> in <module>()
      1 #명단이 삭제되어 없지만 이런식으로 하면 됩니다.
----> 2 with open("../wps.csv", "r") as f:
      3     wps_student_list = [
      4         WPSstudent(line.split(",")[0])
      5         for line

FileNotFoundError: [Errno 2] No such file or directory: '../wps.csv'

In [47]:
class Student():
    
    __skills = []
    #외부에서 못 부르게 할 때 => 정보 은닉(information hiding)
    
    def __init__(self, name):
        self.name = name
        self.age = 0
        
    def print_skills(self):
        for skill in self.__skills:
            print("{skill} 일을 할 수 있습니다.".format(skill=skill))
            
    def add_skill(self, skill):
        self.__skills.append(skill)
        
    def get_age(self): #getter(즉, 정보를 가져오는 메쏘드)
        return self.age
    
    def set_age(self, age): #setter(즉, 정보를 입력하는 메쏘드)
        self.age = age

In [48]:
kkp = Student("김기표")

In [49]:
kkp.add_skill("WPS")
kkp.add_skill("DSS")
kkp.print_skills()


WPS 일을 할 수 있습니다.
DSS 일을 할 수 있습니다.

In [50]:
class Human():
    
    def __init__(self, name):  #초기화 될 때 => Human("...")
        self.name = name
        self.age = 0
        print("{name}이라는 사람이 태어났다.".format(name=self.name))
        
    def after_a_year(self):
        self.age += 1
        print("{name}이라는 사람이 나이를 1살 더 먹었다.".format(
            name=self.name))
        
    def __str__(self):  #출력 형태로 불릴 때 => print
        return "'{name}'이라는 사람".format(name=self.name)
    #__str__(self)
    #__unicode__(self)
    
    def __del__(self):  #삭제될 때 => del human
        print("{name}이라는 사람이 메모리에서 잊혀졌다.".format(
            name=self.name))

In [51]:
human = Human("김기표")


김기표이라는 사람이 태어났다.

In [52]:
print(human)


'김기표'이라는 사람

In [53]:
# 파이썬이 이 사람을 기억 못할 때 => 더이상 필요없다고 생각했을때 
# 메모리에서 지워버리는 겁니다.

In [54]:
del human


김기표이라는 사람이 메모리에서 잊혀졌다.

In [55]:
human


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-55-dd8889b15ae2> in <module>()
----> 1 human

NameError: name 'human' is not defined
  • 우리가 지금까지 만든 모든 클래스가 객체화 가능한 애들
  • 학생, 데사스 학생, 웹프스 학생, 동물, 사람 ...

  • 동물, 조류, 포유류 클래스
  • "먹을 수 있는", "날아다니는", "생각하는 것이 가능한" 클래스

In [56]:
class Animal():
    pass

In [57]:
class Chicken(Animal):
    pass

In [58]:
class Flyable():
    
    def fly(self):
        print("날기가 가능하다.")
        
class Pigeon(Animal, Flyable):
    pass

class Sparrow(Animal, Flyable):
    pass

In [59]:
sparrow = Sparrow()

In [60]:
sparrow.fly()


날기가 가능하다.

In [61]:
class Student():
    pass

In [62]:
class GoodStudentFeature():
    def study(self):
        print("열심히 공부한다.")
        
class ILikeToPlayFeature():
    def study(self):
        print("공부 안하고 놀러 다닌다.")

In [63]:
class GoodStudentButILikeToPlayStudent(Student, ILikeToPlayFeature, GoodStudentFeature):
    pass

In [64]:
student = GoodStudentButILikeToPlayStudent()

In [65]:
student.study()


공부 안하고 놀러 다닌다.

In [66]:
#mro => Method Resolution Order(Python2, Python3 우선순위)