Quiet Time



ㅁ■ 객체와 클래스 (가장 중요한 단원) 

  • 9장 목차
  1. 객체와 클래스
  2. 클래스의 정의
  3. __init__() 메소드를 이용한 초기화작ㅇ업
  4. self에 대한 이해 
  5. 정적 메소드와 클래스 메소드 
  6. 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
  7. 상속
  8. 오버라이딩
  9. __call()__ 메소드 
  10. for문으로 순회를 할 히 있는 객체 만들기 
  11. 추상기반 클래스 
■ 9.1 객체와 클래스
객체(object) = 속성(attribute) + 기능 
    자동차          ↑            ↑
               자동차 색깔  전진, 후진,좌회전,우회전
               바퀴의 크기

코드로 구현을 하면 ? 

객체      =      변수      +      함수 

예제 :
class Car
     def __init__(self):
          self.color =0xFF0000 # 자동차의 색
          self.whell_size = 16
          self.displacement = 2000 # 엔진 배기량 


     def forward(self) : # 전진하는 기능
          pass
     def backward(self) : # 후진하는 기능
          pass
     def turn_right(self): # 우회전 하는 기능 
          pass

     def turn_left(self): #좌회전 하는 기능
          pass

if __name__ == '__main__' : # 메인 모듈일때만 아래의 스크립트를 실행해라

     my_car = Car() # 클래스를 가지고 인스턴스화 하는 코드
                    # Car() 클래스로 my_car라는 객체를 생성했다. 

     print('0x{:02X}'.format(my_car.color))
     print(my_car.whell_size))
     print(my_car.displacement)

     my_car.forward()                    # my_car 의 메소드(기능) 를 호출 
     my_car.backward()
     my_car.turn_left()
     my_car.turn_right()

■ 9.2. 클래스의 정의 


     클래스(자료형) ----> 객체(변수) 

     위의 클래스는 자료형이고 아직 객체가 되지 않았다
                    붕어빵 틀     붕어빵 (인스턴스, 실체라고 얘기함) 
                    (속성: 붕어빵 색
                           붕어빵 앙금(팥, 슈크림)

                     기능: 왼쪽으로 가라 오른쪽으로 가라 
     my_car = Car()           # Car() 클래스에 의해서 my_car라는 객체가 생성됨 인스턴스화 됨


객체 = 속성 + 기능 
      (변수)  (함수)
 
  • 코드 설명 :
     
    def __init__(self): 

1. __init__ ? 객체가 생성될때 호출되는 메소드로서 객체의 초기화를 담당한다
2.self      ? 메소드의 첫번째 매개변수로 객체 자신임을 나타냄 
3.my_car = Car() ? car() 생성자는 car 클래스의 인스턴스를 생성하여 반환한다. 
   ↑         
 인스턴스    생성자
   (실체)    (설계도)


■ 9.3 __init__() 메소드를 이용한 초기화 

클래스의 생성자가 호출이되면 내부적으로 두개의 메소드가 호출된다.
  1. __new__()   : 클래스의 인스턴스를 만드는 역할 ( 내부적으로 자동으로 호출된다.)
  2. __init__()  : 객체가 생성될  대 객체를 초기화하는 역할 
  • 만약 __init__() 메소드를 클래스 생성할 때 지정안하며 ㄴ어떻게 되는지 테스트 

1.__init__() 메소드를 지정 안 했을때

class ClassVar:
     text_list = [] # 클래스의 정의 싷점에서 바로 메모리에 할당됨 
     
     def add(self,text):
          self.text_list.append(text) 

     def print_list(self):
          print(self.text_list)

if __name__ == '__main__':
     a = ClassVar()

ㅁ■ 객체와 클래스 (가장 중요한 단원) 

  • 9장 목차
  1. 객체와 클래스
  2. 클래스의 정의
  3. __init__() 메소드를 이용한 초기화작ㅇ업
  4. self에 대한 이해 
  5. 정적 메소드와 클래스 메소드 
  6. 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
  7. 상속
  8. 오버라이딩
  9. __call()__ 메소드 
  10. for문으로 순회를 할 히 있는 객체 만들기 
  11. 추상기반 클래스 


9.4 self 에 대한 이해 
" 클래스에서 사용하는 최도 매개변수인데 self는 자기 자신을 가리킨다"

9.5 정적 메소드와 클래스 메소드 
1.인스턴스 메소드   : 로봇의 팔이 잘 작동하는지 로봇을 만들어노혹 작동해 보면 확이하는 메소드
2.클래스(정적) 메소드 : 로봇의 팔이 잘 작동하느니즈이 확인을 로봇을 만들지 않고 어떻게 하면 로봇팔이 움진인다는                     프로그램 코드를 실행히셬 확인하는 메소드 



class Calculator:
    @staticmethod
    def plus(a, b):
        return a+b

    @staticmethod
    def minus(a, b):
        return a-b

    @staticmethod
    def multiply(a, b):
        return a*b

    @staticmethod        
    def divide(a, b):
        return a/b
        
if __name__ == '__main__':        
    print("{0} + {1} = {2}".format(7, 4, Calculator.plus(7, 4)))
    print("{0} - {1} = {2}".format(7, 4, Calculator.minus(7, 4)))
    print("{0} * {1} = {2}".format(7, 4, Calculator.multiply(7, 4)))
    print("{0} / {1} = {2}".format(7, 4, Calculator.divide(7, 4)))



■ 어제 배웠던 내용 복습

   1. 클래스 와 객체
   (붕어빵틀)  (붕어빵)

      객체의 구성요소 2가지
      1. 속성(변수)
      2. 기능(함수)



   class gorilla   class pingpong
   속성: 고릴라 색깔   공과 판의 색깔, 위치
   기능: 고릴라 기능   좌로 이동, 우로 이동
   gorilla() = gorilla() -----> 생성자   pingpoing = pingpoing()

   2. 객체를 초기화 해주기 위해서 필요한 키워드, 메소드?

         self, __init__


■ 9.6 클래스 내부에게만 열려있는 프라이빗 멤버(pg200)

* 파이썬에서 사용하는 멤버 2가지

   1. public member : 클래스 안에서든 밖에서든 접근 가능 한 멤버

     예: 접두사가 두개의 밑줄이고 접미사도 두개의 밑줄이면
   __number__

   2. private member : 클래스 안에서만 접근 가능한 멤버
            클래스의 사생활을 지켜줘야할 때 요긴하게 사용됨

     예: 접두사가 두개의 밑줄이고 접미사는 없거나 하나의 밑줄

   __number
   __number_



6. 클래스 내부에게만 열려있는 프라이빗 멤버
      ○ 파이썬에서 사용하는 멤버 2가지
         i. public member - 클래스 안에서든 밖에서든 접근 가능한 멤버
            □ 접두사가 두개의 밑줄이고 접미사도 두개의 밑줄이면 퍼블릭 멤버, __number__

         ii. private member - 클래스 안에서만 접근 가능한 멤버, 클래스의 사생활을 지켜줘야할 때 요긴함
            □ 접두사가 두개의 밑줄이고 접미사는 없거나 하나의 밑줄, __number_ / __number

   • 예제 - 퍼블릭 멤버로 사용했을 경우

           class yourclass:
               pass

           class myclass:
               def __init__(self):
                   self.message = "Hello"

               def some_method(self):
                   print(self.message)

           obj = myclass()
           obj.some_method()  #메소드를 실행했기 때문에 출력이 된 것, 객체명.기능 --> 실행
           print(obj.message)  #따로 message라는 변수의 내용을 출력, print해서 본 것


   • 예제 - 프라이빗 멤버로 사용했을 경우

           class yourclass:
               pass

           class myclass:
               def __init__(self):
                   self.message = "Hello"
                   self.__private = "private"

               def some_method(self):
                   print(self.message)
                   print(self.__private)

           obj = myclass()
           obj.some_method()
           print(obj.message)
           print(obj.__private)  #프라이빗이라서 에러가 난다.

9.7 상속

   • 상속 : 클래스들끼리 유산(기능) 을 물려주는 것
      클래스  ---------------------------------> 클래스
      부모                  유산(기능)                자식  으로 물려주는 것

   • 상속을 받게 되면 자식 클래스에 부모 기능을 코딩하지 않아도 됨.
      학습시키는 클래스(짝꿍) --------------------------> 나는 핑퐁게임 클래스만 만들고 나머지는 상속 받아서 사용

   • 예제1
      class father :
def base_method(self) :


클래스 부모 ------------------- 클래스 자식 상속

상속을 받게되면 부모의 기능을 굳이 자식 클래스에 코딩하지 않아도 된다.


학습 시키는 클래스 (짝꿍) -------------------------> 나는 핑퐁게임 클래스 
                          머신러닝 기능 유산

예제 1 : 

class father 
     def base_mothod(self) :
          print("hello")

class child(father):
     pass

father = father()

father.base_method()

child = child() 
child.base_method()


예제2. __init__ 메소드를 가지고 실행하는데 부모와는 틀리게 자식에message라는 속성이 없어서 상속을 시키고 싶을때?


class father:
     def __init__(self):
          print("hello~~")
          self.message="Good Morning"

class child(father):
     def __init__(self):
          print("hello~~ I am child")

child = child()
print(child.message) <==========애기는 굿모닝 못하네여





class father:
     def __init__(self):
          print("hello~~")
          self.message="Good Morning"

class child(father):
     def __init__(self):
          father.__init__(self) # 파이썬은 암묵적인 것을 싫어하고 명시적인것을 좋아한다.
          프로그래머가 명시적으로 클래스의 초기화 메소드를 호출해주길 원함
          print("hello~~ I am child")

child = child()
print(child.message)

■ super()

child = child() 
print(child.message)

super() 는 부모클래스의 객체 역할을 하는 내장 함수.
사실상 super() 함수의 반환값을 상위객체로 지정한다 다른 클래스로 교체되거나 수정되어도 파생클래스가
받는 영향을 최소화 할 수 있다. 

class father:
     def __init__(self):
          print("hello~~")
          self.message="Good Morning"

class child(father):
     def __init__(self):
          #father.__init__(self)
          super.__init__()

          print("hello~~ I am child")

child = child()
print(child.message)

■ 다중상속

다중 상속이란 두개 이상의 클래스를 상속 받는것을 말한다
이 경우에는 두 클래스의 모든 속성을 물려받게된다
이는 하나의 자식 클래스가 두개 이상의 부모 클래스를 가지는 것이라고 할 수 있다. 


          father1            father2
               ↘              ↙
                    child
예제 1:

class father1:
     def func(self):
          print("지식")

class father2:
     def func(self):
          print("지혜")

class child(father1,father2):
     def childfunc(self):
father1.func(self)
father2.func(self)

objectchild = child()
objectchild.childfunc()
objectchild.func() # 결과 : 지식 (물려 받은 순서 우선순위 출력 father1 의 지식이 출력된다.)

■ 그런데 둘다 출력하기 싫고 하나만 출력하고 싶어서 

                 grandfather 

                          

          father1            father2

                ↘           ↙

                 grandchild



예제 : 
class grandfather:
     def __init__ (self):
          print("튼튼한 두팔")

class father1(grandfather):
     def __init__ (self):
          grandfather.__init__(self)
          print("지식")

class father1(grandfather):
     def __init__ (self):
          grandfather.__init__(self)
          print("지혜")

class grandchild(father1, father2):
     def __init__(self):
          father1.__init__(self)
          father2.__init__(self)
          print("난 행복해")

grandchild = grandchild()
결과 :
튼튼한 두팔
지식
튼튼한 두팔
지혜
난 행복해

다이아몬드 상속을 받았더니 그만 팔이 4개가 되어부럿당!

문제166. (점심시간 문제) 다시 팔이 2개가 되게 하시오 

class grandfather:
     def __init__ (self):
          print("튼튼한 두팔")

class father1(grandfather):
     def __init__ (self):
          super().__init__()
          print("지식")

class father2(grandfather):
     def __init__ (self):
          super().__init__()
          print("지혜")

class grandchild(father1, father2):
     def __init__(self):
          super().__init__()
          print("난 행복해")

grandchild = grandchild()




6     클래스내부에게만 열려잇느 프라이빗 멤버
7     상속
8     오버라이딩
9     __call()__메소드
10    for 문으로 순회를 하룻 잇는 객체 만들기
11    추상 기반 클래스

9.6 오버라이딩

~ 보다 우선한다는 뜻이다
부모로 부터 상속받은 메소드를 다시 Override(재정의) 하겠다.

예제: 
class grandfather:
     def __init__(self):
          print("튼튼한 두팔")
class father2(grandfather):
     def __init__(self):
          print("지혜")

father2 = father2()
지혜도 주요지만 건강도 물려받고싶다면
class grandfather:
     def __init__(self):
          print("튼튼한 두팔")
class father2(grandfather):
     def __init__(self):
          super().__init__()
          print("지혜")

father2 = father2()

■ super() 에 대해서?
1.super()를 이용하면 부모클래스의 멤버에 접근을 할 수 있따.
2.super()를 이용하면 부모 클래스 명이 변경되어도 일일이 코드를 고치는 수고를 줄일 수 있다.
3.super()를 이요함녀 죽음의 다이아몬드 상속을 피할 수 있다. 

aa■ 9.6 데코레이터 사용법 
데코레이터의 사전적 의미? 꾸미다
데코레이터는 함 수를 꾸며주는 함수 
데코레이터는 함수의 능력을 확장 시켜준다. 
 
어떤 동작을 수행하기 전에 @ 로 시작하는 키워드를 사용해서 수행한다.

  • 데코레이터의 중요한 2가지 기능
  • 1. 함수를 강력하게 해준다.
  • 2. 공통적으로 사용하는 코드를 쉽게 관리하기 위해서 사용한다


  • 파이썬 함수의 4가지 특징
  • 1. 변수에 할당 할 수 있다.
  • 2. 다른 함수내에서 정의 될 수 있다. 
  • 3. 함수의 인자(매개변수)값으로 전달될 수 있다.
  • 4. 함수의 반환값이 될 수 있다. 


  1. 함수를 !!!  변수에 할당!!!!

def greet(name):
     return "Hello {} ".format(name) 

greet_someone = greet # 함수를 변수에 할당
print(greet_someone("scott")) 

  1. 다른 함수내에서 정의 할수 있어!!!!!
def greet(name):
    def greet_message():
       return 'Hello'
    return "{}  {}".format(greet_message(),name)

print(greet("scott"))

  1. 함수의 인자값으로 전달 될 수 있다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
예: 
def greet(name):
     return "Hello {}".format(name)

def change_name_greet(func):
     name = "king"
      return func(name)

print( change_name_greet(greet))


  1. 함수의 반환값이 될 수 있다.


def greet (name):
     return "Hello {}".format(name)

 def uppercase (func):
     def wrapper(name):
          result = func(name)
          return result.upper()
     return wrapper

new_greet = uppercase(greet) ("scott")
print(new_greet)
print(new_greet("scott"))
문제167. 이름을 입력하고 함수를 실행하면
          해당하는 사원들의 직업이 소문자로 출력되는 함수를 생성하시오 !

함수1. 이름을 입력했을때 직업이 출력되는 함수 (find_job)
함수2. 문자를 입력했을때 소문자로 출력하는 함수 (lower_case)



def find_job(name):
    import pandas as pd
    emp = pd.DataFrame.from_csv("d:/data/emp.csv")
    job = emp[['job']][emp['ename'] == name].values[0][0]

    return job


def lowercase(func):
    def wrapper(name):
        result = func(name)
        return result.lower()

    return wrapper



new_find_job = lowercase(find_job)

print(new_find_job('SCOTT'))



■ 데코레이터 표현법을 보기전에 먼저 데코레이터와 같은
역할을 하는 함수를 생성

class greet(object):
    current_user = None
    def set_name(self,name): # current_user 라는 변수인 속성은 선언
        if name =='admin': #name 에 admin 이라는 문자를 담고
            self.current_user = name
        else:                  #admin 이 아니라면 권한이 없다는 에러를
            raise Exception("권한이 없네요") #발생시키는 함수

    def get_greeting(self,name): #name 이라는 매개변수에 admin 이
        if name == 'admin':  # 입력이 됬다면
            return "Hello {}".format(self.current_user)

                    #Hello 와 current_user 를 리턴하는
                    #함수


실행방법:

greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin'))

'Error cuz of object is not callable'

greet = greet()
greet.set_name('scott')
print(greet.get_greeting('scott')) # scott 은 안되거든?

문제168.어드민만 헬로 출력되게하라 

class greet(object):          # current_user 라는 변수인 속성을 선언

     current_user = None     # name에 admin이라는 문자가 들어오면
     def set_naem(self,name):     #current_user 에 admin 이라는 문자를 담고
          if name == 'admin':
               self.currnet_user = name
          else:                #admin이 아니라면 권한이 없다는 에러를 발생시킴
               raise Exception("권한이 없네요")

     def get_greeting(self,name):     # name이라는 매개변수에 admin이 입력되면
          if name == 'admin':
               return "Hello {}".format(self.current_user)
                                       # Hello와 current_user를 리턴하는 함수 
                                       

실행방법 :
greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin') )


위의 코드에서 중복되는 부분 즉 admin이 맞는지 확인하는 공통적인 코드를 하나의 함수로 만들어서 따로 떼어낼 수 있을 것 같다.



def is_admin(user_name):
     if user_name != 'admin':
          raise Exception("권한이 없다니까요 ")

class greet(object):
     current_user = None
     def set_name(self,name):
         is_admin(name)
         self.current_user = name

     def get_greeting(self,name):
         is_admin(name)
         return "Hello {}".format(self.current_user)

greet = greet()
greet.set_name('admin')
print(greet.get_greeting('admin') )
문제169. 이름을 넣어서 함수를 실행하면 해당 사원의 월급이 출력되게 함수를 생성하는데
     KING 만 월급을 볼 수 있게 하고 KING이 아닌 다른 사원들은 권한이 없다면서 볼 수 없게 에러가 나게 하시오 !

import pandas as pd
def is_admin(user_name):
     if user_name != 'KING' and :
          raise Exception("권한이 없다니까요 ")

class find_sal(object):
     current_user = None
     def set_name(self,name):
         is_admin(name)
         self.current_user = name

     def get_sal(self,name):
         is_admin(name)
         emp = pd.DataFrame.from_csv("d:/data/emp.csv")
         sal= emp[['sal']][emp['ename'] == name].values[0][0]
         return sal

find_sal  = find_sal ()
find_sal.set_name('KING')
print(find_sal.get_sal('KING') )

문제170.위에 is_admin(name) 이라는 함수를 사용해서 코드가 더 좋아졌다 하지만 데코레이터를 이용하면 함수가 더 
     좋아진다. 데코레이터를 써서 구현하시오 

def is_admin(func):
  def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
                              # **kwargs 딕셔너리 가변 매개변수
    if kwargs.get('name') != 'admin':
        raise Exception("권한이 없다니까요 ")
    return func(*arg,**kwargs)
  return wrapper

class greet(object):
     current_user = None
     @is_admin
     def set_name(self,name):
         self.current_user = name

     @is_admin
     def get_greeting(self,name):
         return "Hello {}".format(self.current_user)

greet = greet()
greet.set_name(name='admin')
print(greet.get_greeting(name='admin') )

문제171. 문제169 코드를 데코레이터 함수를 이용해서 더 좋게 개선시키시오



import pandas as pd
def is_admin(func ):
  def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
                              # **kwargs 딕셔너리 가변 매개변수
    if kwargs.get('name') != 'KING' :
        raise Exception("권한이 없다니까요 ")
    return func(*arg,**kwargs)
    if arg[1] == 'SCOTT' :
        raise Exception("스콧이당!")
    return func(*arg,**kwargs)
  return wrapper

class find_sal(object):
     current_user = None
     @is_admin
     def set_name(self,name):
         self.current_user = name

     def get_sal(self,name):
         emp = pd.DataFrame.from_csv("d:/data/emp.csv")
         sal= emp[['sal']][emp['ename'] == name].values[0][0]
         return sal

find_sal  = find_sal ()
find_sal.set_name(name = 'KING')
print(find_sal.get_sal(name = 'KING') )



import pandas as pd
def is_admin(func ):
  def wrapper(*arg,**kwargs): # *arg 리스트의 가변 매개변수
                              # **kwargs 딕셔너리 가변 매개변수
    if arg[1] == 'SCOTT' :
        raise Exception("스콧이당!")
    return func(*arg,**kwargs)
    if kwargs.get('name') != 'KING' :
        raise Exception("권한이 없다니까요 ")
    return func(*arg,**kwargs)
  return wrapper

class find_sal(object):
     current_user = None
     @is_admin
     def set_name(self,name):
         self.current_user = name

     @is_admin
     def get_sal(self,name):
         emp = pd.DataFrame.from_csv("d:/data/emp.csv")
         sal= emp[['sal']][emp['ename'] == name].values[0][0]
         return sal
find_sal  = find_sal ()
find_sal.set_name(name = 'KING')
print(find_sal.get_sal('SCOTT') )


객체와 클래스 (가장 중요한 단원) 


■ 어제 배운내용 복습
1. 클래스 멤버 2가지
                    -- public member
                    -- private member
2. 상속
     - 상속이 필요한 이유? 코드를 간결하게 하기위해서
       객체 지향언어를 제대로 활용하는 방법(object -oriented )
          1팀 : 로폿팔 클래스
          2팀 : 로봇다리 클래스
          3팀 : 로봇 몸체 클래스
          4팀 : 로봇 두뇌(인공신경망) 클래스 
          로봇팔에 버그가 있어 개선하는데 다리까지 영향을 끼친다 안돼!
          ==> 결국 유지보수 비용을 줄일수 있다.
          파이썬 (코어) 개발
          파이썬 개발자 중급 400 ~ 600 

  • 객체 (인스턴스)? 리스트 , 튜플, 딕셔너리 처럼 데이터를 다루기 위한 논리적 집합
                              ↓                                 ↓
                데이터를 어떤 형식으로 저장할 건가?    속성(변수)에 데이터를 넣고     
                                                   기능(함수)로 데이터를 다루는 역할


3만건의 영어 단어장 ----- 겨울왕국 스크립트 리스트 --->
       리스트                리스트                  full table scan 
                                                    (100초)

       딕셔너리              딕셔너리                index scan
       key:value            key:value               (1초)

  • 클래스란? 변수 + 기능 으로 구성된 논리적 집합 ! 
     인스턴스? 클래스(설계도) 를 실체화 한것

문제172. gun이라는 인스턴스를 생성하기 위해서 gun() 클래스를 생성하시오
     gun = gun()    # 총 설계도로 총을 실체화 시킴
     gun.charge(10) # 총알 10발 충전
     gun.shoot(3) 
       탕
       탕
       탕 
     7발 남았습니다. 

     gun.print() # 현재 총알이 얼마나 남았습니다. 
     7발 남았습니다. 

class gun:
    def __init__(self):
        self.bu =0
    def print(self):
        print('{} 발 남았습니다.'.format(self.bu))

    def charge(self,n):
        self.bu += n

    def shoot(self,a):
        for i in range(a):
            if self.bu > 0 :
                self.bu -= 1
                print ('탕 !')
            elif self.bu == 0 :
                print('총알이 없습니다')
                break

        print(self) 

gun = gun()    # 총 설계도로 총을 실체화 시킴
gun.charge(10) # 총알 10발 충전
gun.shoot(4)
gun.print()

예제2. 클래스를 사용하는 이유? 

class employee(object) 
  pass

emp_1 = employee()
emp_2 = employee()

예제2. 클래스를 사용하는 이유?

- 딕셔너리를 사용하는 경우

student = {'name': '김인호', 'year':2,'class':3,'student_id':35}

print('{}, {}학년 {}반 {}번'.format(student['name'],student['year'],student['class'],student['student_id']) )

- 클래스를 사용하는 경우 

class student(object):
     def __init__(self,name,year,class_num,student_id):
          self.name = name
          self.year = year
          self.class_num = class_num
          self.student_id = student_id

     def introduce_myself(self):
          return '{}, {}학년 {}반 {}번'.format(self.name, self.year, self.class_num,self.student_id)

student = student('김인호',2,3,35)

print (student.introduce_myself())


문제173. 위의 student 클래스를 다시 실행하는데 self 빼고해라

TypeError: introduce_myself() takes 0 positional arguments but 1 was given

introduce_myself()라는 메소드는 인자값을 안받게 만들어줘놓고 왜 하나를 줬느냐

인스턴스의 메소드를 호출하면 인스턴스 자기 자신인 self가 첫번째 인자로 자동으로 전달되기 때문이다.

def introduce_ myself():  # <-- self가 없습니다.

파이썬에서는 인스턴스의 메소드를 호출함녀 인스턴스 자기자신인 self가 첫번재 인자로 자동으로 전달되므로 
반드시

def introduce_myself(self)  # <=== self를 넣어줘야 한다. 

문제173. 자기 자신이 인스턴스의 메소드에 인자로 전달된다는 것이 어떤것인지 인스턴스를 통하지 않고
바로 클래스 introduce_myself를 직접 호출해서 확인하시오 

class student(object):
     def __init__(self,name,year,class_num,student_id):
          self.name = name
          self.year = year
          self.class_num = class_num
          self.student_id = student_id

     def static introduce_myself(self):
          return '{}, {}학년 {}반 {}번'.format(self.name, self.year,

self.class_num,self.student_id)

student1 = student('김인호',2,3,35)

print (student.introduce_myself())


■  self 를 왜 강조하느냐?

파이썬은 객체함수를 나타낼때 무조건 def(self,x,y)
이렇게 self를 첫번째 인자로 넣어야한다.
자바나 c++에서는 this 를 명시 안해도 되나 파이썬은 강제입니다.
 
■ static method ?
(정적 메소드 ) 

 - self를 매개변수로 받지 않는 메소드
 - 여러 인스터스가 공유해서 사용하는 메소드

  

class gun:
    def __init__(self):
        self.bu =0
    def print(self):
        print('{} 발 남았습니다.'.format(self.bu))

    def charge(self,n):
        self.bu += n

    def shoot(self,a):
        for i in range(a):
            if self.bu > 0 :
                self.bu -= 1
                print ('탕 !')
            elif self.bu == 0 :
                print('총알이 없습니다')
                break

        print(self) 

gun1 = gun()   
gun1.charge(10)
gun1.shoot(4)
gun1.print()

gun2 = gun()   
gun2.charge(10)
gun2.shoot(4)
gun2.print()

설명: gun1 총과 gun2총은 서로 다른 총입니다.
     같은 설계도를 사용했지만 별개의 총이다.
     별개의 총이 맞는지 확인해본다.
print(gun1)
print(gun2)
<__main__.gun object at 0x000000000C497828>
<__main__.gun object at 0x000000000C525D30>

print(gun1.__class__)
print(gun2.__class__)
<class '__main__.gun'>
<class '__main__.gun'>
 
 둘은 다른 메모리 주소값을 가지고 있어서 
같은 클래스를 쓰는 서로 별개의 오브젝트라는 것을 확인함

문제174. gun class 의 메소드들을 static method들로 변경해서 다시 총을 쏘시오 


class gun:

    bu = 0
    @staticmethod
    def charge(n):
        gun.bu += n

    @staticmethod
    def shoot(a):
        for i in range(a):
            if gun.bu > 0 :
                gun.bu -= 1
                print ('탕 !')
            elif gun.bu == 0 :
                print('총알이 없습니다')
                break

    @staticmethod
    def print():
        print('{} 발 남았습니다.'.format(gun.bu))

gun1 = gun()
gun1.charge(10)
gun1.shoot(3)
gun1.print()

gun2 = gun()
gun2.shoot(7)
gun2.print()
결과 :
탕 !
탕 !
탕 !
7 발 남았습니다.
탕 !
탕 !
탕 !
탕 !
탕 !
탕 !
탕 !
0 발 남았습니다.

문제175. static method로 선언한 클래스를 이용해서 인스턴스화한 두개의 총의 쏘는 메소드(shoot) 이 서로 같은 메모리를 쓰는지 다른 메모리를 쓰는지 확인하시오 


  • 9장 목차
  1. 객체와 클래스
  2. 클래스의 정의
  3. __init__() 메소드를 이용한 초기화작ㅇ업
  4. self에 대한 이해 
  5. 정적 메소드와 클래스 메소드 
  6. 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
  7. 상속
  8. 오버라이딩
  9. __call()__ 메소드 
  10. for문으로 순회를 할 히 있는 객체 만들기 
  11. 추상기반 클래스 


■9.10 마법의 __call__ 메소드

예제:
class sample(object):
     def __init__(self):
          print("전 생성하면 바로 생성이 돼요")

sample = sample()

설명: __init__ 메소드는 인스턴스를 생성하면 바로 실행이 된ㄷ.

예제2 :
class sampel2(object):
     def __call__(self):
          print("인스턴스에 괄호를 붙이면 제가 실행돼요")

sample2 = sample2()
sample()

클래스의 인스턴스를 함수처럼 호출하기 위해서 
클래스의 __call__ 이란느 매직 메소드를 정의했다
이 원리를 이용해서 클래스를 데코레이터로 구현할 수 있다
어제 우리가 데코레이터로 구현한건 클래스가 아니라 함수였다.

■ 클래스를 데코레이터로 구현하는 예제

from functools import wraps

class onlyadmin(obejct):               # 함수에 들어가는 매개변수의 문자열을 받아서
     def __init__(self,func):          # 대문자로 변환해줌
          self.func= func

     def __call__(self,*args,**kwargs):
          name = kwargs.get('name').upper()
          self.func(name)

def greet(name):
     print("Hello {}".format(name) )

greet(name = 'Scott')
결과 : Hello Scott

문제176. 위의 onlyadmin 데코레이터를 활용해서 find_job이라는 함수를 강력하게 하시오 ! 
find_job(name= 'scott')

당신의 직업은 ANALYST 입니다.



from functools import wraps
import pandas as pd

class OnlyAdmin(object):
    def __init__(self, func):  # 대문자로 변환해주며 함수를 실행해주는 클래스
        self.func = func

    def __call__(self, *args, **kwargs):
        name = kwargs.get('name').upper()
        return self.func(name)

@OnlyAdmin
def find_job(name):

    emp = pd.DataFrame.from_csv('d:/data/emp.csv')

    job = emp[['job']][emp['ename'] == name].values[0][0]
    return job


find_job(name='SCOTT')



  • 9장 목차
  1. 객체와 클래스
  2. 클래스의 정의
  3. __init__() 메소드를 이용한 초기화작ㅇ업
  4. self에 대한 이해 
  5. 정적 메소드와 클래스 메소드 
  6. 클래스 내부에게만 ㅇ려려있는 프라이빗 멤버
  7. 상속
  8. 오버라이딩
  9. __call()__ 메소드 
  10. for문으로 순회를 할 히 있는 객체 만들기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  11. 추상기반 클래스 

■ 9.11 for 문으로 순회를 할 수 잇는 객체 만들기

Iterator 는 next() 메소드로 데이터를 순차적으로 호출하는 object이다. 

예제 :
for i in range(5) :
     print(i) 

우리가 당연하게 사용했던 위와 같은 for 문은 사실 range() 로 생성된 list 가 iterable 하기 때문에 순차적으로
member 들을 불러서 사용이 가능했던 것이다.

x = [1,2,3]
next(x)


■ 9.12 추상 기반 클래스 

상속일나 클래스의 재사용을 높임으로써
  1. 코드의 반복을 줄이고
  2. 유지보수 비용을 낮추는데 큰 역할을 한다

이러한 상속과 함께 객체지향(object-oriendted) 프로그램의 가장 중요한 특징중 하나가 다형성이다

다형성이란 클래스에 선언된 메서드가 상속 받은 클래스에서 같은 이름으로 
오버라이딩 되어 여러 형태로 동작함을 의미한다. 
예 :                동물 

               메소드 : 짓는다 (비어있는 메소드)
               ↙                        ↘
          고양이                         개

     짖는다 메소드 : 야옹               짖는다 메소드 : 멍멍 



                    동물   <--- 아직 덜 구체화된 상태 --> 그래서 객체화 시키기에는
                ↙          ↘
               고양이        개 <---- 구체화 된 상태

동물 넌 너무 추상적이야 그러니 너는 객체를 만들지마
!

그래서 추상 클래는 상속을 위해서 필요하긴 하지만 개체화해서는 안되는 클래스

추상 클래스는 추상 메소드가 있는 클래스를 말한다
추상 메소드는 바디(내용)가 없는 메소드이다.

추상 클래스를 상속 받는 자식 클래스에서 반드시 지켜줘야 할 사항은 ?

추상 클래스내에는 추상 메소드와 일반 메소드들이 있을 텐데 
그중에 추상 메소드는 반드시 가져와서 오버라이드 해야한다.

예제: 

from abc import ABCMeta, abstractmethod # 파이썬은 추상 클래스를 제공하지 않아서 import받아야한다.


class animal(object):

__metaclss__ = ABCMeta # 추상 클래스로 선언
@abstractmethod # 추상 메소드 선언
def bark(self):
     pass # 비어있는 메소드, 상속받는 자식들이 반드시 구현해야 하는 중요한 메서드

class cat(animal):

def __init__(self):
     self.sound = '야옹'


def bark(self):
     return self.sound


class dog (animal) :

def __init__(self):
     self.sound = '멍멍'
def bark(self) :
     return self.sound

cat = cat()

dog = dog()


print(cat.bark())

print(dog.bark())




문제177. 음료(beverage) 라는 추상클래스 생성하고
          아메리카노(americano)와 카페라떼 (caffelatte) 클래스를
          자식 클래스로 생성하시오 
          
          추상 클래스를  통해서 반드시 구현해야 하는 데메소드는 음료 가격임 












'PYTHON' 카테고리의 다른 글

English stopword , 영어 불용어  (0) 2018.09.18
gcp를 이용해서 jupyter notebook / jupyter lab 서버 만들기  (0) 2018.08.27
8장. 모듈  (0) 2017.09.10
7장. 함수  (0) 2017.09.10
6장. if 문과 loop문 (p126)  (0) 2017.09.10

8장. 모듈

PYTHON2017. 9. 10. 00:43
8장 모듈
- 모듈이란?
- import 사용법
- 모듈 찾는방법
■8장 목차

  1. 모듈이란. ?          : 함수 생성한 것들을 모아놓은 스크립트
  2. import사용법         : 다른 모듈내의 코드에 접근 가능하게 하는 명령어
  3. 모듈찾는방법         : sys.path의 내용을 출력해서 파이썬이 어떻게 모듈을 탐색해 나가는지 확인
  4. 메인모듈과 하위모듈  : 오늘 부터 !배울 내용
  5. 패키지
  6. __init__.py
  7. site - package

■ 8.4 메인 모듈과 하위 모듈 (p 171) 

               파이썬 문법 + 중요한 알고리즘 20가지는 외워버려야 한다.

  1. 코드를 어떻게 만드느냐? 함수 생성, 함수 생성을 한 것을 모아 놓은 모듈
  2. 코드를 어떻게 실행하느냐 ? 메인 모듈 ( 최상위 수준으로 실행되는 스크립트 ) 
                                             예 : 실뭉치의 끝

  • _name_ (내장 전역변수) 를 이용하면 지금 쓰고있느 모듈이 메인 모듈인지 하위 모듈인지 확인할 수 있다.

     메인 모듈: _name_ ---> main 이라고 나오고
     하위 모듈: _name_ ---> 모듈명으로 나온다

예제 : top_level.py 란느 이름으로 저장하고 실행

print('name : {0} '.format(__name__) )

결과 : name : __name__

예제2: sub.py 라는 이름으로저장하고 실행
print("beginning of sub.py...")
print('name : {0}'.format(__name__) ) 
print("end of sub.py...")

먼저 실행하면 결과가 어떻게 나오는가 ?


■ 8.5 패키지 
패키지란 ? 모듈을 모아놓은 디렉토리를 말한다 ( 모듈 꾸러미)

모듈일나? 실행할 함수들을 모아놓은 스크립트

글너데 평범한 디렉토리가 파이썬의 패키ㅣㅈ로 인정 바등려며 ㄴ

__ini__.py 라는 파일이 그 디렉토리 안에 있어야 한다. 

예 : d\python <--- 퍀키지로 인정을 받으려면 ?

__init__.py   <------- 비어있는 문서
calculator.py   <------ 모듈


■ 8.6 _ini_.py 에 대해 (p 175) 

_init_.py 는 보통 비워둡니다 . 이 파일을 손대는 경우는 __all__ 이라는 변수를 조정할 때이다.

__all__ 변수? 패키지로 부터 반입할 모듈의 목록을 정의하기 위해 사용한다

즉 어제 from  패키지 import * 라고 했는데 

이 * 가 패키지 내에 모든 모듈들을 반입하겠다 라는 뜻인데

그 모든 모듈들이 뭐가 있는지 파이썬이 알려며 _ini_.py에 __all__ 변수에 
아래와 같이 명시를 해줘야 한다. 

예: __all__ =['plus_module','minus_module','multiply_modue','divide_module']

  • 실습 : 
  1. d:\python 폴더 아래에 4개의 모듈을 만들어서 저장한다. 
-- plus_module.py로 아래의 스크립트를 저장 


def plus(a,b):
     return a+b

-- minus_module.py로 아래의 스크립트를 저장

def minus(a,b):
     return a-b

-- multiply_module.py로 아래의 스크립트를 저장

def multiply(a,b):
     return a*b

  1. d:\python 폴더 아래에 _ini_.py에 아래의 내용을 저장
__all__ =['plus_module','minus_module','multiply_moduㅣe']
  1. d:\python 폴더의 상위 디렉토리에 cal_test.py라는 이름으로 아래의 스크립트를 저장하고 실행

from python import *

print ( calculator.plus(10,5))
print ( calculator.minus(10,5))


■8.7 site - package 에 대해서 

 site - package 란 파있너 기본 라이브러리 패키지외에 추가적인 패키지를 설치하는 디렉토리이다.

 site - package 디렉토리에 여러가지 소프트웨어가 사용할 공통 모듈을 넣어두면 ㅁ루리적안장소에 구애받지 않고 모듈에  접근하여 반입할 수 있다.

import sys

sys.path
C:\ProgramData\Anaconda30\Lib\site-packages
문제 163. d:\my_loc2라는 디렉토리를 만들고 cal_test.Py 스크립트를 가져다 두고 실행해보세요 

'PYTHON' 카테고리의 다른 글

gcp를 이용해서 jupyter notebook / jupyter lab 서버 만들기  (0) 2018.08.27
9장. 객체와 클래스 (가장 중요한 단원)  (0) 2017.09.10
7장. 함수  (0) 2017.09.10
6장. if 문과 loop문 (p126)  (0) 2017.09.10
1-5장  (0) 2017.09.10

7장. 함수

PYTHON2017. 9. 10. 00:42
■ 7장. 함수 

  • 7장. 목차 
  • 1.함수생성하는 방법
  • 2.기본값 매개변수와 키워드 매개변수 (mit 코드 이해)
  • 3.가변 매개변수  (mit 코드 이해)
  • 4.매개 변수로 함수를 사용하는 경우
  • 5.함수 밖의 변수, 함수 안의 변수
  • 6.재귀함수  (mit 코드 이해)
  • 7.중첩함수 

■ 7.1. 함수 생성하는 방법

def 함수일므 (매개변수):

     실행문
      return 결과


예제: def my_abs(arg):
       if (arg < 0 ) :
          result = arg * -1 
       else:
          result = arg
       return result
      print ( my_abs(-5) )

문제146. 아래와 같이 이름을 입력하새 함수를 실행하면 
          해당 사원의 부서위치가 출력되게하시오!

print( find_loc('SMITH') )

def find_loc(name)
 for e in emp:
  for d in dept:
   if e['deptno'] == d['deptno'] :
      if e['ename']  == name :
          print( e['ename'].ljust(7),d['loc'])

find_loc('SMITH')

import pandas as pd
def find_loc(val):
    emp= pd.read_csv("D:\data\emp.csv")
    dept= pd.read_csv("D:\data\dept.csv")
    result  = pd.merge(emp,dept,on='deptno')
    result2 = result[['loc']][result['ename']== val]

    return result2
문제147. 미분계수를 구하는 함수를 생성하는데 
 함수 f(x) = 2x^2 +1 일때 

def mibun_fun(n):
 return 'x가 '+ str(n) +'에서의 기울기는 '+ str(round((2*(n + 0.00000001)
*(n + 0.00000001)+1 - (2* n*n+1) ) / 0.00000001)) + ' 입니다.'
print(mibun_fun(-2))


■ 매개변수로 함수를 받는 경우 


def numerical_diff(f,x):
    delta = 0.0001 # 1e-4로 해도된다
    return ( f(x+delta) - f(x-delta) ) / (2*delta)
함수  f(x) 2x^2 + 1 생성

def function_1 (x) :
     return 2*pow(x,2) +1

print( numerical_diff(function_1,-2) )


문제148. 함수 f(x) = x^2 -x +5 함수의 x가 -2일때 미분계수를 구하시오 





■ 지난 주에 배웠던 내용 복습
  1. 함수
- 머신 러닝을 이해하기위한 Mit TTT 코드 구현
- 웹 스크롤링 ----> 빅데이터 수집
  1.  
6장함수 
for 
while
continue
break

5장. 파이썬 자료형 3가지 
  1. 리스트 []
  2. 튜플 ()
  3. 딕셔너리 {} (키와 값으로 구성된 자
   - 어순 번역기
   - nested loop join 구현
          ↓ data 양이 많아지면 느려진다.
   - hash join 으로 구현 (해쉬 알고리즘)  오라클이 이걸로 다른rdb회사 눌러버림

  1. Pandas 모듈을 이용해서 데이터 검색
          판다스 데이터 프레임 [ 열 ] [ 행 ]
            ↓  <---- 그룹함수 구현
           판다스 데이터 프레임 [ 열 ] [ 행 ] .max()
                                              .sum()
                                              .min()
                                              .mean()

           ↓  
          판다스 데이터 프레임.groupby([열])['기준컬럼(sal)'].max()

요번주 : 7장 함수, 8장. 모듈과 패키지 , 9장 .클래스 , 10장. 예외처리  
          11장. 파일에서 데이터 읽고 쓰기 ------> Tic Tac Toe 게임

     1세대 인공지능: 1954년 캠브리지 대학에서 Tic Tac Toe 를 사람과 게임할 수 잇또록 구현
          ↓ 
     체스가 구현 
          ↓ ----> 신경망(딥러닝) 
     오목, 바둑  (2016년)

     인공지능에서 무언가 혁신적인게 나온다면 그것은 바로 구글에서 나올것이다.
      - 에릭 슈미스 (구글 사장 ㅋ)




■ 7장. 함수 

  • 7장. 목차 
  • 1.함수생성하는 방법
  • 2.기본값 매개변수와 키워드 매개변수 (mit 코드 이해)
  • 3.가변 매개변수  (mit 코드 이해)
  • 4.매개 변수로 함수를 사용하는 경우
  • 5.함수 밖의 변수, 함수 안의 변수
  • 6.재귀함수  (mit 코드 이해)
  • 7.중첩함수 

■ 7.2. 기본값 매개변수와 키워드 매개변수 (p 145)
기본값 매개변수? 입력하지 않으면 기본으로 할당되는 매개변수

예 : log(4   ,   2)    ,    log(10)
         ↑      ↑              ↑
       지수     밑수             지수    밑수는 자연상수e 가된다.

예제 : 
 def print_string(text,count = 1): #  count = 1 디폴드 값을 지정
  for i in range(count):
    print(text)
 
 print(print_string("안녕하세요") )
 print(print_string("안녕하세요"),3 )

문제149. 아래와 같이 이름만 넣으면 소속팀과 직위가 출력되는 함수를 생성하시오 
def print_string(name='장경원',team='머신러닝팀',position='팀장'):
  print(name)
  print(team)
  print(position)

 
def print_string(name,team='머신러닝팀',position='팀장'):
  print('이름 = {0}'.format(name) )
  print('소속팀 = {0}'.format(team ) )
  print('직위 = {0}'.format(position ) )

설명 : 문자열.format()

■ Mit TTT코드에서 기본값 매개변수 사용하는 부분 

class Agent(object):

    def __init__(self, player, verbose = False, lossval = 0, learning = True):

        self.values = {}

        self.player = player

        self.verbose = verbose

        self.lossval = lossval

        self.learning = learning

        self.epsilon = 0.1

        self.alpha = 0.99

        self.prevstate = None

        self.prevscore = 0

        self.count = 0

        enumstates(emptystate(), 0, self)

■ 가변 매개변수 (p147) 
문자열.format() 함수 처럼 매개변수의 수가 유동적인 함수를 만들고 싶을 때 사용하는 변수 
함수 실행할때 매개변수를 10개 , 20개를 입력해도 제대로 동작을 한다. 

예 :
def 함수이름(*매개변수):
          코드 블럭

예제:
def merge_string(*text_list):
     result = ''
     for s in text_list:
      result = result + s + '  '
     return result
merge_string('아버지가','방에','들어가신다')  

파이썬에서 * 가 쓰이는 경우 
  1.가변 매개 변수
  2.리스트 변수내의 요소들을 뽑아낼ㄸ ㅐ--> mit 코드


문제150. mit TTT코드에서 보드판을 출력하는 printboard 함수를 분석하시오
(리스트 변수내의 요소를 ㅃ보아내는 문법이 나온다.

# States as integer : manual coding
EMPTY = 0
PLAYER_X = 1
PLAYER_O = 2
DRAW = 3

BOARD_FORMAT = """----------------------------
| {0} | {1} | {2} |
|--------------------------|
| {3} | {4} | {5} |
|--------------------------|
| {6} | {7} | {8} |
----------------------------"""
NAMES = [' ', 'X', 'O']

def printboard(state):
    """ Print the board from the internal state."""
    cells = []
    for i in range(3):
        for j in range(3):
            cells.append(NAMES[state[i][j]].center(6))
    print(BOARD_FORMAT.format(*cells))


printboard([[1,2,0],[0,0,0],[0,0,0]])

print(BOARD_FORMAT.format('a','b','c','d','e','f','g','h','g'))  

print(BOARD_FORMAT.format('x','o','x','o','x',' ',' ',' ',' '))

print(BOARD_FORMAT.format('x'.center(6),'o','x','o','x',' ',' ',' ',' '))


7.4.매개 변수로 함수를 사용하는 경우

  • 함수의 종료의 의미로  return 을 사용하는 경우
예제:
def stop_fun(num) :
  for i in range(1, num + 1) :
    print ('숫자 {0} 울 출력합니다'.format(i)) 
    if i =0 5:
     return 
stop_fun(10)



def enumstates(state, idx, agent):
    if idx > 8:
        player = last_to_act(state)
        if player == agent.player:
            agent.add(state)
    else:
        winner = gameover(state)
        if winner != EMPTY:
            return
        i = int(idx / 3)
        j = idx % 3
        for val in range(3):

               state[i][j] = val
               enumstates(state, idx+1, agent)

문제151. (점심시간 문제) 아래와 같이 숫자를 입력하고 함수를 실행하면 숫자가 세로로 출력되게 하시오 

def print_something(*num):

     for s in num :
         print(s)

  1. 함수 밖의 변수, 함수 안의 변수

     로컬 변수? 함수 내에서만 사용하는 변수
     글로벌 변수? 함수 내,외 둘다 사용 가능한 변수 
               특정함수에서 출력된 결과를 다른 함수에서 사용할 때 
               사용합니다. 


함수안의 변수와 함수 밖의 변수가 서로 이름이 같다해도 전혀 다른 변수이다. 
만약 같은 변수로 취급하려면 global 변수로 선언해야한다. 

예제: 
def scope_test():
  a = 1  # 함수 내에서 사용하는 변수 (로컬변수)
  print ('a : {0}'.format(a) )

scope_test()


문제152. 마지막 위의 스크립트에서 마지막 scope_test()를 실행했을때 a가 1 이 아니라 0이 출력이 되려면
         scope_test() 함수를 생성할 때 어떻게 생성해야 했을가요?
a = 0
def scope_test():
  a = 1  # 함수 내에서 사용하는 변수 (로컬변수)
  print ('a : {0}'.format(a) )

scope_test()

  • 재귀함수
  • 스택구조 
  • 큐구조 : 선입선출( 먼저 들어온게 먼저 처리)

sql에서 큐를 경험해봤다
Enqueuue 락 
서로 업데이트 하려면 락이걸린다. 
a b c 
a: lock holder
b,c : lock waiter 

scott A

update emp
 set sal = 0 
 where ename = 'KING';

* 스택 구조 : 먼저들어간 데이터가 가장 마지마겡 나오는 구조 LIFO
후입 선출 

스택 루프 반복문 
반복문 (LOOP) + 스택 구조 ===> 재귀 알고리즘 

예 : 
def some_func(count) :
  if count > 0 :
     some_func(count -1) 
  print (count)

some_func(100)

10 ---> call하고 기다림 ---> 기다림이 끝나면 print 10
 9 ---> call하고 기다림 ---> 기다림이 끝나면 print 9
 8 ---> call하고 기다림 ---> 기다림이 끝나면 print 8
 7 ---> call하고 기다림 ---> 기다림이 끝나면 print 7
                         :
                         :
                                             print 0 
0 ---> 함수 호출 끝 


문제153. 10! 을 재귀함수로 구현해서 출력하시오 !

def factorial2(count) :

  if count > 0 :
     return count * factorial2 (count -1)
  elif count == 0:
     return 1

문제154. 16과 28의 최대공약수를 출력하는데 재귀함수를 이용해서 
          구현하시오 ! 
find_gcd(20,16)
최대 공약수는 4

find_gcd(108,72) 
최대 공약수는36

def find_gcd(num1, num2):
 if num1%num2 != 0: return find_gcd(num2, num1%num2)               
 else : return num2


li=[]
def find(*num):
if a%b != 0: return find_gcd(b, a%b)               
 elif a%b == 0 : return find_gcd(c, b%c)  
 return c
li=[]
def print_something(*num):





문제155. 오늘 오전에 배운 가변 매개변수와 재귀 알고리즘을 이용해서 최대 
          공약수를 출력하는 함수를 생성하시오 

def find_gcd(a,b,c):
 if a%b != 0: return find_gcd(b, a%b,c)
 elif b%c != 0: return find_gcd(a, b ,b%c)
 return b

def find_gcd(a,b,c):
 if a%b != 0: return find_gcd(b, a%b)               
 elif a%b == 0 : return find_gcd(c, b%c)  
 return c
li=[]
def print_something(*num):

     for s in num :
       li.append(s)

a= 1000%700%74
print (a)


내일 PL/SQL 알고리즘 문제 시험범위: 오픈북, 실습가능

오늘 배운 재귀 알고리즘을 PL/SQL로 구현하는 문제 2개
예 SQL> exec dbms_output.put_line( factorial(5) )



7.7 중첩함수 ( p 158)
" 파이썬에서는 함수 안에 함수를 정의하는거싱 가능하다"
중첩함수는 자신이 소속된 함수의 매개변수에 접근할 수 있다는 특징이 있다. 

예제: p159 쪽 (표준편차를 출력하는 함수)

* 표준편차를 구현하기 위한 함수 2개

   1. 평균값 구하는 함수
   2. 분산을 구하는 함수
   3. 구해진 분산값에 루트를 씌운 값을 출력하는 함수

예제:

(pg159)

import math
def stddev(*args):
    def mean():                               #평균 구하는 함수
        return sum(args)/len(args)

    def variance(m):                       # 분산을 구하는 함수
        total = 0
        for arg in args:
            total += (arg - m) **2
        return total/(len(args)-1)
    v= variance(mean())                # 분산을 구함
    return math.sqrt(v)                 # 분산에 루트를 씌워서 표준편차를 구함

stddev(2.3,1.7,1.4,0.7,1.9)


import math
def stddev(*args):
 def mean():
    return sum(args)/len(args)

 def variance(m):
   total = 0
   for arg in args:
      total += (arg -m) **2
   return total / (len(args)) - 1
v= variance(mean() )
return math .sqrt(v)
stddev(2.3, 1.7, 1.4, 0.7, 1.9)

  
문제156. 가변 매개변수를 이용해서 여러개의 숫자를 입력 받아 최대공약수를 
출력을 해낸 준호의 코드를 가져다가 중첪함수를 구성하시오 ! 

def gcdtwo(a,b):                    두 수의 최대공약수를 출력
                                    분모가 0일경우 에러가 발생하므로 0인 경우를 따로 생각
    if min(a,b) == 0:               # 0 A의 최대공약수는 무조건 A 이기 떄문에
        return max(a,b)             두 수중 최소값이 0인경우 두 수중 맥스값으로 최대공약수 출력
    return gcdtwo(b,a%b)            # 0이 아닌경우에 대해 유클리드호제법으로 재귀

def gcd(a):                         여러 수 중에서 최대공약수를 출력하는 알고리즘
    b=gcdtwo(max(a),min(a))         여러 수 중 두수를 뽑아서 최대공약수를 구하고
                                    다른 두수를 뽑아서 최대공약수를 구하고를 반복해서
    a.remove(min(a))                마지막에 남는 최대공약수가 전체의 최대공약수인 점을 이용
    a.remove(max(a))                정렬할 필요가 없게 전체 수에서 최대최소값을 뽑아서
                                    최대공약수를 구하는데 계산에 사용한 수는 제거하고
    a.append(b)                     위에서 구한 최대공약수를 리스트에 추가
    if max(a)==min(a):              위 과정을 재귀를 통해 반복하면 최대공약수만 2개 남는데
        print('최대공약수는 : ',a[0])  그경우에서 재귀를 종료하고 최대공약수를 출력
    else:
        gcd(a)


def list(*n):                       가변 매개변수로 데이터를 여러개 입력받으면
                                    튜플 형태이기 때문에 데이터 변경이 불가능
    a = []                          리스트를 생성하고 데이터 변경이 가능하도록
    for in n:                     튜플 데이터를 잘라서 리스트에 입력
        a.append(i)
    gcd(a)                          최종적으로 생성한 리스트 변수를
                                    위에 생성한 최대공약수 함수에 입력해서 최대공약수 계산




def list(*n):
    def gcdtwo(a,b):

        if min(a,b) == 0:
            return max(a,b)
        return gcdtwo(b,a%b)

    def gcd(a):
        b=gcdtwo(max(a),min(a))

        a.remove(min(a))
        a.remove(max(a))

        a.append(b)
        if max(a)==min(a):
            print('최대공약수는 : ',a[0])
        else:
            gcd(a)

    a = []
    for i in n:
        a.append(i)
    gcd(a)

list(4,8,12)
list(6842,176,154)

■ 재귀 알고리즘을 완성하는 문제
 MIT 코드를 이해하기 위해서 반드시 알아야하는 알고리즘 
  1. greedy (탐욕) 알고리즘
     당장 눈 앞의 이익만 추구하는 것 
     먼 미래를 내다 보지 않고 지금 당장의 최선이 무언인가만 판단 
 
     예 : 틱택토 코드가 가장 유명한 예이다.


문제157. 탐욕 알고리즘을 이용하여 금액과 화폐가 주어졌을 때 
          가장 적은 화폐로 지불 하시오 !
액수입력 : 362
화폐 단위를 입력 !: 1 50 100

결과 :
100원     3개
50원       1개
1원          12개 




def coinGreedy(money, cash_type):
    cash_type.sort(reverse=True)

    def coinGreedyRecursive(money, cash_type, res, idx):
        if idx >= len(cash_type): #화폐 다 사용 시 종료
            return res

        dvmd = divmod(money,cash_type[idx] )
        res[cash_type[idx]] = dvmd[0]
        return coinGreedyRecursive(dvmd[1] ,cash_type,res,idx+1)

    return coinGreedyRecursive(money,cash_type,{},0)
money = int(input('액수입력 : '))
cash_type = [int(x) for x in input('화폐단위를 입력하세요 : ').split(' ')]
res = coinGreedy(money,cash_type)
for key in res:
    print('{0}원 : {1}개'.format(key,res[key]))



■8장. 모듈과 패키지 
  • 8장 목차 
    • 1. 모듈이란?
    • 2. import 사용법
    • 모듈 찾는 방법
    • 메인 모듈과 하위 모듈
    • 패키지
    • _init_.py

8.1 모듈이란? 독자적인 기능을 갖는 구성요소
              파이썬에서는 각각의 소스파일을 일컬어 모듈이라고 한다. 

모듈 생성 예 :

save as calculator.py
def plus(a,b):
  return a+b

def minus(a,b):
  return a-b

def multiply(a,b):
  return a*b

def divide(a,b):
  return a/b

import calculator

print (calculator.plus(10,5))
print (calculator.minus(10,5))
print (calculator.multiply(10,5))
print (calculator.minus(10,5))

■8.2. import 사용법 
import 의 역할은 정확하게는 다른 모듈 내의 코드에 대한 접근을 가능하게 하는 것이다.
import 가 접근 가능하게 하는 코드에는 변수, 함수 , 클래스등이 모두 포함된다.

앞에서 썼던 문법 :
import 모듈명

import calculator 

print ( calculator.plus(10,5) )
               
         ↓
좀더 편하게 코딩 : from 모듈명 import 변수 또는 함수 

                   from calculator import plus
                   from calculator import minus 
                   from calculator import multiply
                   from calculator import divide

               print ( plus(10,5) )

 
                ↓
좀더 편하게 코딩 : from 모듈명 import *
                    print ( plus(10,5) )

p 168  import * 와 같은 코드는 사용하지 않는것이 좋다.

이유?       코드가 복잡해지고 모듈의 수가 많아지면 어떤 모듈에 또는 어떤 함수를 불러오고 있는지 파악하기 힘들다

좀더 편하게 코딩 : import calculator as c
                    print (c.plus(10,5) )



문제159.오전에 만들었던 준호의 최대공약수를 구하는 함수를 모듈화 하시오 !



if _name_=="__main__": 모듈을 불러올때 이문장 이후의 문장은 수행되지 않음
list (1000,3350,150)

문제160. 표준편차를 출력하는 함수를 모듈화 시켜서 다른 실행창에서 아래와 같이 실행되게 하시오!




■8.3. 모듈 찾는 방법

방금 만든 calculator 모듈의 위치는 우리가 직접 지정한 위치에 저장되어있었고
calc_test.py 에서 calculator 모듈을 불러올 수 있었다. 

sys 라는 모듈( 예: random 함수를 포함하고 있는 모듈) 어디에 있는가?
 
파이썬은 import를 만나면 아래와 같은 순서로 모듈 파일을 찾아나선다.
  1. 파이썬 인터프리터 내장 모듈
  2. sys.path 에 정의 되어 있는 디렉토리 

sys 모듈은 파이썬의 내장 모듈이다. 

sys 모듈에 들어있는 함수들이 뭐가 있는지 확인하는 코드 

import sys
print ( sys.builtin_module_names)

문제161. 혜승이가 sys모듈의  random 함수를 이용해서 경이로운 방법으로 구현해낸 원주율 구하는 코드를 실행해보자 























 
 

'PYTHON' 카테고리의 다른 글

gcp를 이용해서 jupyter notebook / jupyter lab 서버 만들기  (0) 2018.08.27
9장. 객체와 클래스 (가장 중요한 단원)  (0) 2017.09.10
8장. 모듈  (0) 2017.09.10
6장. if 문과 loop문 (p126)  (0) 2017.09.10
1-5장  (0) 2017.09.10