8. 파이썬 잘하는 척 해보자__LMS Node 브레이커

허남철·2021년 12월 31일
0

LMS Node 브레이커

목록 보기
3/4
  1. 파이썬 어디까지 써 봤니?!

    왜 파이썬일까?

    • 퍼포먼스(성능)은 특정 연산 속도이다. C가 빠르다
    • 생산성 : 똑같은 기능을 하는 프로그램을얼마나 빨리 작성할 수 있는가 이다.
    • 파이썬은 성능은 좀 떨어지지만, 생산성이 좋다.
    • 성능과 생산성은 언어마다 장단이 있으므로 목적과 상황(프로젝트의 성능과 개발 기간)에 맞게 선택하면 된다.

    파이썬의 성능

    • 높은 생산성 : 다양한 모듈을 라이브러리로 제공. pip과 import로 쉽게 설치 및 사용.기능을 구현하기 전에 이미 검색해보자.
    • 코드의 간결함 java vs python
      if(true) {
          System.out.println("첫 번째");
          if(true) {
              System.out.println("두 번째");
          }
      }
      if True :
          print("첫 번째")
          if True :
              print("두 번째")
    • 빠른 개발속도 : 같은 문제도 C++은 11시간, 파이썬 3시간 소요. 성능에 관계없이 빠르게 개발해야하는 프로젝트라면 파이썬!
    • 스크립트 언어(인터프리터 언어) vs 컴파일 언어
      • 컴파일 언어

        실행전, 소스코드를 기계어 변환후 파일 실행

        기계어를 실행하므로 비교적 빠르다.

        컴파일 시점에서 소스코드의 오류를 잡기 쉽다.

        같은 소스코드도 다른 환경에서 실행하려면 다시 컴파일해야함

      • 스크립트언어

        코드 작성과 함께 인터프리터가 기계어로 번역, 실행

        번역 과정이 있어 비교적 느리다.

        목적에 뚜렷하게 개발되어 사용하기 쉬운 편

        코드줄로 코드 즉시 실행 가능

    • 요약 : 높은 생산성, 간결한 코드 , 빠른 개발 속도, 스크립트 언어의 장점
  2. 파이썬을 더 잘 사용해 보자!
    2.1 For문 잘 써보기

    enumerate() : 문자열 튜플 리스트 등의 순서와 함께 리스크의 값을 반환.
    
    ```python
    my_list = ['a','b','c','d']
    
    for i, value in enumerate(my_list):
        print("순번 : ", i, " , 값 : ", value)
    
    >>>
    순번 :  0  , 값 :  a
    순번 :  1  , 값 :  b
    순번 :  2  , 값 :  c
    순번 :  3  , 값 :  d
    ```
    
    이중 for 문 : **`[0, 1]`과 `['a','b','c','d']` 두 리스트를 조합**
    
    ```python
    my_list = ['a','b','c','d']
    result_list = []
    
    for i in range(2):
        for j in my_list:
            result_list.append((i, j))
            
    print(result_list)
    >>>
    [(0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (1, 'a'), (1, 'b'), (1, 'c'), (1, 'd')]
    ```
    
    리스트 컴프리헨션(List Comprehension) : 순회형객체에서 이를 가공한 새로운 객체 생성하는 간결한 방법
    
    ```python
    my_list = ['a','b','c','d']
    
    result_list = [(i, j) for i in range(2) for j in my_list]
    
    print(result_list)
    >>>
    [(0, 'a'), (0, 'b'), (0, 'c'), (0, 'd'), (1, 'a'), (1, 'b'), (1, 'c'), (1, 'd')]
    ```
    
    제너레이터(Generator) : 데이터를 전부 메모리에 올려두지 않고, 현재 처리할 데이터를 1개씩 로드하여 사용. 빅데이터를 다룰 머신러닝에서 요긴하다.
    
    예) 단순 이중 for 문을 사용할 경우 이다.  result_list 에 모든 데이터가 담기길 기다렸다가 반환받는다. 
    
    ```python
    my_list = ['a','b','c','d']
    
    # 인자로 받은 리스트를 가공해서 만든 데이터셋 리스트를 리턴하는 함수
    def get_dataset_list(my_list):
        result_list = []
        for i in range(2):
            for j in my_list:
                result_list.append((i, j))
        print('>>  {} data loaded..'.format(len(result_list)))
        return result_list 
    
    for X, y in get_dataset_list(my_list):
        print(X, y)
    
    >>>
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  1 data loaded..
    >>  8 data loaded..
    0 a
    0 b
    0 c
    0 d
    1 a
    1 b
    1 c
    1 d
    ```
    
    예) 제네레이터 yield 를 사용한 코드이다. yield 는 양보라는 뜻으로, 코드 실행의 순서를 밖으로 양보한다.
    
    ```python
    my_list = ['a','b','c','d']
    
    # 인자로 받은 리스트로부터 데이터를 하나씩 가져오는 제너레이터를 리턴하는 함수
    def get_dataset_generator(my_list):
        result_list = []
        for i in range(2):
            for j in my_list:
                yield (i, j)   # 이 줄이 이전의 append 코드를 대체했습니다
                print('>>  1 data loaded..')
    
    dataset_generator = get_dataset_generator(my_list)
    for X, y in dataset_generator:
        print(X, y)
    
    >>>
    0 a
    >>  1 data loaded..
    0 b
    >>  1 data loaded..
    0 c
    >>  1 data loaded..
    0 d
    >>  1 data loaded..
    1 a
    >>  1 data loaded..
    1 b
    >>  1 data loaded..
    1 c
    >>  1 data loaded..
    1 d
    >>  1 data loaded..
    ```
    
    이처럼, 제네레이터가 없다면 1억짜리 리스트를 리턴받아 메모리에 두고 사용해야하지만, 제네레이터는 사용할 데이터를 1개씩 로드하므로 빅데이터, 머신러닝에 활용가치가 높다.
    
    **2.2 Try - Except**
    
    **에러 처리를 위한 방법이다.** 코드를 수행중 예외(에러)가 발생하면 예외(에러)를 무시하거나 적절한 처리를 하는 작업이다.
    
    ![Untitled](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a6e0ff6d-6c8f-4257-b649-8b378502ca75/Untitled.png)
    
    statements를 수행하다가 에러발생시 except코드를 실행한다.
    
    ```python
    a = 10
    b = 0 
    
    try:
        #실행 코드
        print(a/b)
    		
    except:
        print('에러가 발생했습니다.')
        #에러가 발생했을 때 처리하는 코드
        b = b+1
        print("값 수정 : ", a/b)
    ```
    
    **2.3 Multiprocessing**
    
    병렬처리하는 방법을 배워보자
    
    ```python
    import multiprocessing # 1. multiprocessing 모듈 임포트
    import time
    
    num_list = ['p1','p2', 'p3', 'p4']
    start = time.time()
    
    def count(name): # 2. 병렬처리할 함수 작성
        for i in range(0, 100000000):
            a = 1+2
        print("finish:"+name+"\n")
        
    
    if __name__ == '__main__':  # 3. '코드의 시작 지점을 여기로 하라' 라는 명령어
    
    		# 4. 병렬처리시 4개 프로세스사용 (cpu코어수 만큼 사용시 최대효과)
        pool = multiprocessing.Pool(processes = 4)
    
    		# 5. 병렬화 함수, count함수에 num_list원소 하나씩 넣어 놓는다.
    		# count('p1'), count('p2'), count('p3'), count('p4')가 만들어진다.
        pool.map(count, num_list)
    
    		# 6. 병렬화 끝부분, 더이상 pool로 새로운 추가 작업 않을 때
        pool.close()
    
    		# 7. 프로세스 종료까지 대기하라는 구문. 병렬처리작업이 끝날 때 까지 기다림.
        pool.join()
    
    print("time :", time.time() - start)
    ```
  3. 같은 코드 두 번 짜지 말자!
    3.1 함수(Function)

    **코드의 효율성, 재사용성, 가독성**
    
    pass문 : 제어흐름도구, 아무것도 하지 않는다. 특별히 할 일이 없을 때 사용
    
    ```python
    def empty_function():
        pass
    ```
    
    함수에 함수 사용
    
    ```python
    def say_something(txt):
        return txt
    
    def send(function, count):
        for i in range(count):  
            print(function)
        
    send(say_something("안녕!"), 2)
    ```
    
    함수 안의 함수& 2개 이상의 retrun
    
    **함수 내부에서 정의된 함수는 함수 내부에서만 호출할 수 있다.**
    
    ```python
    list_data = [30, 20, 30, 40]
    
    def minmax_function(x_list):
            
        def inner_min_function(x):
            length = len(x)
            min_result = x[0]
            for i in range(length):
                if min_result > x[i]:
                    min_result = x[i]
            return min_result
        
        def inner_max_function(x):
            length = len(x)
            max_result = x[0]
            for i in range(length):
                if max_result < x[i]:
                    max_result = x[i]
            return max_result
            
        x_min = inner_min_function(x_list)
        x_max = inner_max_function(x_list)
    
     # 2개 이상의 값을 리스트에 넣어 반환하므로 인덱싱으로 사용하면 된다.
        minmax_list = [x_min, x_max] 
    
        return minmax_list
    
    print("최솟값, 최댓값은 : ", minmax_function(list_data))
    print("최솟값은 : ", minmax_function(list_data)[0])
    print("최댓값은 : ", minmax_function(list_data)[1])
    ```
    
    여러 변수로 받아 반환 할 수도 있다.
    
    ```python
    ....
    # , 콤마로 여러값으로 반환하고 이를 받아 각각 활용
    return x_min, x_max
    
    min_value, max_value = minmax_function(list_data)
    
    print("최솟값은 : ", min_value)
    print("최댓값은 : ", max_value)
    ```
    
    **3.2 람다 표현식**
    
    익명함수 : 함수를 간결히 한다. 함수며으 return등 틀을 최대한 생량하는 문법. 함수명이 없기 때문에 한번 만들면 다시 호출할 수 없는듯하다.
    
    ```python
    기존 함수
    
    def 함수명 (매개변수) :
         실행코드
          return 반환값
    함수명(인수)
    
    람다- 익명이라 함수명이 없습니다.
    
    (lambda 매개변수 : 반환값)(인수)
    또는
    lambda 인자 : 표현식
    
    여기서 반환값, 표현식은 return 값인데,
    일반함수에서 실행코드부분도 함께 결합해서 반환값으로 만들어야하는 것같습니다.
    ```
    
    ```python
    # 더하기함수 2줄
    def add(x, y):
        return x + y
    # 한줄로 줄이기
    def add(x, y): return x + y
    
    # 람다로 만들면?
    
    print( (lambda x,y: x + y)(10, 20) )
    #(lambda 매개변수 : 반환값)(인수)
    # 매겨변수 : 함수내부
    # 인수 : 함수외부에서 매개변수에 전달할 값
    ```
    
    **인수부분을 간단히 하는 효과!**
    
    ```python
    # 람다 없이
    def list_mul(x):
         return x * 2
    
    result = list(map(list_mul, [1, 2, 3]))
    print(result)
    
    # 람다 사용
    result = list(map(lambda i: i * 2 , [1, 2, 3]))
    print(result)
    ```
    
    map(), filter(), reduce()등과 자주 쓰인다.
    
    **3.3 클래스(Class), 모듈(Module), 패키지(Package)**
    
    클래스(Class) : 비슷한 역할을 하는 함수 집합
    
    모듈(Module) : 함수, 변수, 클래스를 모아놓은 파일. 코드 저장소
    
    패키지(라이브러리) : 여러 모듈을 하나로 모아둔 폴더.
    
    패키지 설치 : pip install 패키지이름
  4. 프로그래밍 패러다임과 함수형 프로그래밍

    패러다임(Paradigm) : 시대의 사고를 근본적으로 규정하는 테두리

    프로그래밍 패러다임 : 프로그래머의 프로그래밍 관점. 결정하는 역할. 여러 프로그램이 패러다임이 존재한다.

    절차 지향 프로그래밍 & 객체 지향 프로그래밍

    절차 지향 프로그래밍 : 진행 순서로 프로그래밍

    장 : 순차적 작성으로 순서대로 읽으면 이해 가능

    단 : 위에서 하나라도 잘못되면 연쇄적 문제 발생. 유지보스 어렵다. 코드가 길어 분석이 어렵다.

    객체 지향 프로그래밍 : 프로그램을 상호작용하는 객체들의 집합으로 인식. 객체릴 작성하고 함수를 작성. 객체 간의 상호작용.

    장 : 코드 재사용, 코드분석 용이. 아키텍처 수정 쉽다.

    단 : 객체간 상호작용을 설계에 시간이 소요. 설계를 잘못하면 전체적으로 수정이 필요할 수 있다.

    파이썬은 객체지향이다.

    파이썬 - OOP Part 1. 객체 지향 프로그래밍(OOP)은 무엇인가? 왜 사용하는가? - schoolofweb.net

    함수형 프로그래밍

    • 데이터사이언티스트에게 적합.
    • 효율성, 버그 없는 코드, 병렬프로그래밍 등의 장점!
    • 함수로 문제를 분해.
    • 입력을 받아 출력을 만들기 때문에 입력데이터를 수정하지 않는다
    • 따라서 병렬처리에서 여러함수가 같은 데이터를 사용할때 에러를 만들지 않는다.
    • GPU 활용한 병렬처리 기반의 AI 발전을 가져옴.
    1. 순수성 : 반환값 이외의 변견상항을 만들지 않는, 부작용이 없는 순수함수

      # 순수성이 없는 코드 
      # 함수 외부의 데이터 A를 사용하기때문
      A = 5
      
      def impure_mul(b):
          return b * A
      
      print(impure_mul(6))
      
      # 순수성이 있는 함수
      def pure_mul(a, b):
          return a * b
      
      print(pure_mul(4, 6))
    2. 모듈성 : 문제를 작은 조각으로 분해하도록 강제한다. 작은 함수는 가독성이 좋고, 오류 확인이 용이하다.

    3. 디버깅, 테스트 용이성 : 각 함수에서 데이터가 바른지 확인할 수 있는 포인트가 된다.

    Functional Programming HOWTO - Python 3.10.1 documentation

  5. 파이써닉하게 코드를 짜보자!

  • Whitespace
#한 줄의 코드 길이가 79자 이하여야 합니다.
y = a + a + a + a # 79자 이하

#함수와 클래스는 다른 코드와 빈 줄 두 개로 구분합니다.
class a():
    pass
# 빈 줄
# 빈 줄
class b():
    pass
# 빈 줄
# 빈 줄
def c():
    pass
# 빈 줄
# 빈 줄

#클래스에서 함수는 빈 줄 하나로 구분합니다
class a():
	
		def b():
				pass
	
		def c():
				pass

#변수 할당 앞뒤에 스페이스를 하나만 사용합니다.
y = 1

#리스트 인덱스, 함수 호출에는 스페이스를 사용하지 않습니다.
my_list = [1, 2, 3]
my_list[0] # 리스트 인덱스 호출

my_function(0) # 함수 호출

#쉼표(,), 쌍점(:), 쌍반점(;) 앞에서는 스페이스를 사용하지 않습니다
my_list = [1, 2, 3]; my_list[0:1]
if len(my_list) == 3: print my_list
  • 주석 코드의 내용과 일치하지 않는 주석은 피해야 합니다.
    불필요한 주석은 피해야 합니다.
  • 이름 규칙
#변수명 앞에 _(밑줄)이 붙으면 함수 등의 내부에서만 사용되는 변수를 일컫습니다.
_my_list = []

#변수명 뒤에 _(밑줄)이 붙으면 라이브러리 혹은 파이썬 기본 키워드와의 충돌을 피하고 싶을 때 사용합니다.
import_ = "not_import"

#소문자 L, 대문자 O, 대문자 I를 가능하면 사용하지 마세요. 
#특정 폰트에서는 가독성이 굉장히 안 좋습니다.

#모듈(Module) 명은 짧은 소문자로 구성되며, 필요하다면 밑줄로 나눕니다.
my_module.py

#클래스 명은 파스칼 케이스(PascalCase) 컨벤션으로 작성합니다. 
class MyClass():
	pass

#함수명은 소문자로 구성하되 필요하면 밑줄로 나눕니다.

def my_function():
	pass

#상수(Constant)는 모듈 단위에서만 정의하고 
#모든 단어는 대문자이며, 필요하다면 밑줄로 나눕니다.
MY_PI = 3.14 # 상수는 변하지 않는 변수입니다.
  • 네이밍 컨벤션

snake_case

모든 공백을 "_"로 바꾸고 모든 단어는 소문자입니다.

파이썬에서는 함수, 변수 등을 명명할 때 사용합니다.

ex) this_snake_case

PascalCase

모든 단어가 대문자로 시작합니다.

UpperCamelCase, CapWords라고 불리기도 합니다.

파이썬에서는 클래스를 명명할 때 사용합니다.

ex) ThisPascalCase

camelCase

처음은 소문자로 시작하고 이후의 모든 단어의 첫 글자는 대문자로 합니다.

lowerCamelCase라고 불리기도 합니다.

파이썬에서는 거의 사용하지 않습니다 (Java 등에서 사용)ex) thisCamelCase

profile
AI꿈나무

0개의 댓글