퐈니썬's LIfe - 잘 실패하자 RSS 태그 관리 글쓰기 방명록
Programming/Python (6)
2022-03-11 17:01:26
728x90
반응형

Introduction

파이썬을 처음 접했을 때, 무슨 뜻인지 몰라 헤매던 적이 있던 내용을 차근차근 정리하고자 합니다. 

파이썬 라이브러리 코드를 보다가 함수의 인자에 작성된 내용을 보고 당황했던 적 있습니다. 

# a function
func(*args, **kwargs)

어떤 의미인지 차근차근 알아가보겠습니다. 

 

 

*args, 위치인자

아래와 같은 함수가 있다고 해봅시다. 

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

이 함수는 a, b  두 가지 인자를 입력으로 받아 합을 내는 함수입니다.

하지만, 이 함수를 사용하는 사용자는 두 변수 이상을 입력하여 합을 도출하고 싶습니다.

 

이 함수는 적절하지 못하기 때문에 아래와 같은 함수를 만들어 볼 수 있습니다. 

def sum_val_list(value_list):
	answer = 0
    for val in value_list:
    	answer += val
    return answer

 

위 함수는 입력에 여러 가지 변수를 넣어 합을 도출할 수 있으나, 입력 인자가 반드시 "리스트 형" 이여야 합니다. 즉, 이 함수를 사용하는 사용자는 "리스트"를 구성하여 입력해주어야 합니다. 

 

이런 경우 *args를 사용하여 해결할 수 있습니다. 

def sum_val_args(*args):
	answer = 0
    #*args를 통해 받은 인자를 리스트형으로 받아 냅니다. 
    for val in args:    
    	answer += val
    return answer

 

*args는 함수 내에서 args로 리스트형을 받아내기 때문에 위치 인자를 저장합니다. 리스트로 하나하나 받아내기 때문에 위치인자를 받기 위해 사용되는 것이죠.

 

*args 적용 전에는 사용자가 아래와 같이 사용해야 했습니다. 

sum_val_list([1,2,4])

*args를 적용한 함수는 아래와 같이 사용이 가능합니다. 

sum_val_args(1,2,4)

 

위치 인자와 키워드 인자???

function(1, 2, a=3, b=4)

위와 같은 함수가 있을 때, 1과 2는 위치 인자이며 a, b는 키워드 인자로 값을 받는 함수입니다. 
이때, 반드시 위치 인자와 키워드인자는 위치인자 다음에 키워드 인자가 와야 합니다.

 

 

**kwargs 키워드 인자

이번엔 **kwargs를 이해하기 위해서는 또 다른 예시의 함수를 정의해보겠습니다. 

def print_keyword(name, university):
	print("name: ", name)
	print("university: ", university)

위 함수는 name, university라는 변수를 받아 출력합니다. 하지만, 사용자가 새로운 파라미터를 추가하고 싶다면, 이 함수를 바꾸어야 할 것입니다. 굉장히 번거로운 일이 될 것입니다. 

 

그래서 "딕셔너리 형"을 이용해서 아래와 같은 함수를 만들 수 있을 것입니다.

def print_keyword_dict(dictionary):
	for key in dictionary:
    	print(key + ": " + dictionary[key])

위 함수는 dictionary를 받아서, key를 통해 해당 값을 출력할 수 있기 때문에 dictionary에 새로운 파라미터를 추가하여 출력할 수 있습니다. 하지만, "딕셔너리 형"을 구성해야 한다는 불편한 점이 있습니다.

 

이런 경우 **kwargs를 사용하여 해결할 수 있습니다. 

def print_keyword_kwargs(**kwargs):
	for key in kwargs:
    	print(key + ": " + kwargs[key])

**kwargs는 함수 내에서 kwargs로 딕셔너리 형을 받아내기 때문에 키워드 인자를 저장합니다.

 

 

# **kwargs 적용 전 함수
print_keyword_dict({"name":"jaehwan", "university":"seoul", "studentID":"123155"})

# **kwargs 적용 후 함수
print_keyword_kwargs(name="jaehwan", university="seoul", studentID="123155")

 

훨씬 깔끔하고, 사용하기 편한 함수가 된 거 같습니다. 

 

 

 

요약

  • 함수에 위치 인자를 받고 싶을 때! -> *args 사용! 리스트형으로 받아내기 때문에 위치(순서)대로 받아 처리!
  • 함수에 키워드 인자를 받고 싶을 때! -> **kwargs 사용! 딕셔너리형으로 받아내기 때문에 키워드에 따라 값을 받아 처리!

 

https://www.geeksforgeeks.org/args-kwargs-python/

 

*args and **kwargs in Python - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

728x90
반응형

'Programming > Python' 카테고리의 다른 글

파이썬 f-string  (0) 2021.12.31
파이썬 모듈이란? 패키지란?  (0) 2021.07.01
파이썬 PEP8 스타일 가이드 정리  (0) 2021.07.01
파이썬 클래스 상속  (0) 2021.06.28
numpy flip을 활용한 DICOM 이미지 반전 대칭  (0) 2021.06.25
2021-12-31 10:28:56
728x90
반응형

 

문자열 및 변수의 값을 출력할 때, 깔끔하게 출력하거나 내가 원하는 자리수 까지 표현하는 등의 출력 포맷을 갖추는 것이 중요한 경우가 많습니다. 

 

f-string 포매팅

기존에 출력 포맷에 관련된 %포매팅과 str.format 방법이 있지만, 파이썬 3.6 이후에 나온 내장 기능이라고 보시면 됩니다. 

f-string는 f와 {}만 알면 됩니다. 문자열 맨 앞에 f를 붙여주고, 중괄호 안에 직접 변수 이름이나 출력하고 싶은것을 입력하면 됩니다. 


f'문자열 {변수} 문자열'


사용법

 

f-string 문장 정렬

f-string 공백 채우기

 

f-string 소수점 자리 표현하기

728x90
반응형
2021-07-01 12:30:24
728x90
반응형

00. 서문

모듈과 패키지의 차이, 함수, 클래스등과의 관계를 어렴풋이 알고는 있었지만, 명확하게 정리한적이 없었습니다. 이번 포스트를 통해 정리 하고자합니다.

[참고 블로그]

[코딩유치원] 파이썬 기초 문법 10편_함수, 모듈, 패키지 개념 총정리

 

[코딩유치원] 파이썬 기초 문법 10편_함수, 모듈, 패키지 개념 총정리

안녕하세요, 왕초보 코린이를 위한 코딩유치원에 오신 것을 환영합니다. [코딩유치원 기초문법 강의] 2021.03.09 - [파이썬 기초/기초 문법] - [코딩유치원] 파이썬 기초 문법 1편_프로그래밍과 코딩

coding-kindergarten.tistory.com

01. 모듈? 패키지?

01.1. 모듈 (Module)

각종 변수, 함수, 클래스를 담고 있는 python 파일(.py) 입니다.

어떤 기능을 만들고자 할때, 작성을 하게되고, 이를 모듈이라 통칭합니다.

저는 개인적으로 "xx_utils.py"와 같이 네이밍하여, 패키지에 포함되는 보조 모듈들을 만들곤합니다.

01.2. 패키지 (Package)

여러 모듈(Module)을 묶은 폴더입니다.

이때, 패키지의 폴더 안에는 모듈도 있을 수 있고, 패키지 폴더안에 서브 패키지 폴더가 있을 수도 있습니다. 개발자의 목적에 따라 구성이 달라지겠지만, 기본적인 개념은 모듈들의 집합입니다.

 

❗"init.py" 란?

"init.py"는 패키지임을 명시하기 위한 모듈이라고 보시면 됩니다. 물론 python 3.3 이상 버전

에서는 작성할 필요가 없지만, 호환성 및 기본적인 룰에 따라 개인적으로 작성하고 있습니다.

02. 모둘, 패키지, 라이브러리 관계

 

728x90
반응형
2021-07-01 10:17:46
728x90
반응형

00. 서문

프로그래밍을 할 때, 특히 협업을 통한 코드 공유가 있을때는 좋은 코드와 나쁜 코드라는 것이 있다고 생각합니다. 코드의 구조가 파악하기 쉽다면 협업을 할 때에도 효율적으로 업무를 진행 할 수 있습니다.

코드 작성하는 스타일에 "정답은 없지만", 잘못된 작성법은 있다고 생각합니다. 즉, 코드 구조를 파악하기가 어려운 코딩 스타일이 겠죠.

이를 막기 위해서는 여러가지 파이썬 코드 작성 가이드가 있습니다.

이 중 가장 대표격인 PEP8을 정리해보겠습니다.

 

PEP 8

  • 파이썬 개선 제안서, 파이썬 코드를 어떻게 구상할 지 알려주는 스타일 가이드
  • 다른 사람과 원활하게 협업하려면 공통된 스타일 공유가 필요
  • 일관성 있는 스타일은 나중에 수정하기도 쉽다.

01. 들여 쓰기

  • 들여쓰기 공백은 스페이스 4칸으로 사용합니다.
  • 연속적 라인에 대하여 구분되도록 정렬
#Correct
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

#Wrong

def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)

01.2. tap or space?

  • "스페이스" 사용을 권장합니다.
  • 스페이스와 탭의 혼용을 지양합니다.

01.3. 최대 라인 글자 수

  • 한 라인 (줄) 코드에 대하여 79자 이내로 작성할 것을 권장합니다.

01.4. 연산자 위치

  • 가독성을 위하여, 연속적인 라인에서 연산자는 문장 시작부에 작성 할것을 권장합니다.
#Correct
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

#Wrong
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)

01.5. 빈 줄 생성

  • 2줄: top-level function (최상위 함수), 클래스 작성 후에 권장합니다.
  • 1줄: 클래스의 메소드간의 간격에 권장합니다.

01.6. 함수 임포팅

  • 한줄에 하나의 함수를 호출하기를 권장합니다.

02. 불필요한 공백 줄이기

  • 리스트, 인덱스, 함수호출, 키워드 인수할등 등에는 스페이스를 사용하지 않도록합니다.
  • "," 과 ";" 의 구분자들 뒤에 한번의 스페이스 사용을 권장드립니다. (앞에 사용 x)
  • 소괄호, 중괄호, 대괄호 사이에 추가 공백을 사용하지 않도록합니다.
#Correct
spam(ham[1], {eggs: 2})
foo = (0,)
if x == 4: print x, y; x, y = y, x

#Wrong
spam( ham[ 1 ], { eggs: 2 } )
bar = (0, )
if x == 4 : print x , y ; x , y = y , x

03. 주석

03.1. 주석 블록

  • 일반적으로 뒤에 오는 코드 일부나 전체에 대한 내용을 작성합니다.

03.2. 인라인 주석

  • 인라인 주석의 경우 불필요한 경우 사용을 지양합니다.
  • 코드가 명백하지 않을 경우만 사용합니다.
x = x + 1                 # Increment x

04. 네이밍

  • 기본적으로 혼란을 주는 문자사용을 지양합니다. (ex 대문자 I와 소문자 L)

04.1. 패키지, 모듈 네이밍

  • 모듈이름은 간결하고 소문자 사용을 권장합니다.
  • 가독성을 위해 "_" (underscores) 사용을 권장합니다.
  • ex) main.py, main_function.py

04.2. 클래스 네이밍

  • 클래스는 Capitalized 형식(첫자만 대문자)을 권장합니다.
  • 예외처리 또한 클래스와 동일하므로 동일하게 네이밍 하도록 합니다.
  • ex) MainClass

04.3. 상수, 변수 , 함수, 메서드 네이밍

  • 함수, 변수 (클래스 속성포함), 메소드는 소문자, "_" (underscores) 사용을 권장합니다.
    • 보호(protected) 인스턴스 속성: 맨앞에 '_'를 붙여줍니다.
    • 비공개(private) 인스턴스 속성: 맨앞에 '__' 를 붙여줍니다.
    • 스페셜 인스턴스 속성: 앞뒤에 '__' 를 붙여줍니다.
  • 모듈에서 정의되는 상수는 대문자를 사용합니다.

 

https://www.python.org/dev/peps/pep-0008/

 

PEP 8 -- Style Guide for Python Code

The official home of the Python Programming Language

www.python.org

 

728x90
반응형

'Programming > Python' 카테고리의 다른 글

파이썬 *arg 와 **kwargs 이해 하기  (0) 2022.03.11
파이썬 f-string  (0) 2021.12.31
파이썬 모듈이란? 패키지란?  (0) 2021.07.01
파이썬 클래스 상속  (0) 2021.06.28
numpy flip을 활용한 DICOM 이미지 반전 대칭  (0) 2021.06.25
2021-06-28 11:10:56
728x90
반응형

01. 파이썬 클래스 (Class)란?

클래스는 어떤 것이고 왜 필요할까?

01.1. 클래스의 개요

  • 클래스는 객체의 구조와 행동을 정의한다.
  • 객체의 클래스는 초기화를 통해 제어한다.
  • 클래스는 복잡한 문제를 다루기 쉽게 한다.

 

💡메모

객체란, 어떠한 속성의 값, 행동을 가지는 데이터를 일컫습니다. 파이썬에서 숫자, 문자, 함수 등등 모든 데이터들은 여러 속성과 행동을 가지고 있고 각각이 객체라 볼 수 있습니다.

예시)

세탁기라는 객체는 "빨래를 한다", "빨래 정지한다", "가로 100cm" 등의 속성과 행동으로 표현할 수 있습니다. 이렇든 정의된 데이터가 속성과 행동을 가진다면 객체라고 말할 수 있겠네요!

 

클래스는 위와 같은 특성을 가지는데요, 왜 그러한지에 대해 차근차근 보겠습니다.

 

02. 클래스는 복잡한 문제를 다루기 쉽게 한다?

아래의 예시를 통해 이를 확인 할 수 있습니다.

클래스를 통해 복잡하게 반복해야하는 행동을 쉽게 정의하여 해결 할 수 있습니다.

 

곱셈 계산 기능을 가지는 계산 프로그램 multiply가 있습니다.

이 계산 프로그램은 현재 까지 입력된 모든 숫자들의 곱을 구해야합니다.

예시)

result = 1

def multiply(num):
    global result
    result *= num
    return result

print(multiply(3))
print(multiply(4))
print(multiply(6))

[out]
3
12
72

 

그런데, 어떠한 상황에서 multiply의 기능을 하는 계산 프로그램이 두개가 필요하다고 생각해봅시다.

예를들어, 1 x 4 x 10 라는 연산과 20 x 4 라는 연산을 한번에 진행해야 할 때, 이러한 상황을 고려해보면 위 와같은 multiply 프로그램을 multiply_1, multiply_2와 같이 두개를 만들어야 합니다.

 

예시)

result_1 = 1
result_2 = 1

def multiply_1(num):
    global result_1
    result_1 *= num
    return result_1

def multiply_2(num):
    global result_2
    result_2 *= num
    return result_2

print(multiply_1(1))
print(multiply_1(4))
print(multiply_1(10))

print(multiply_2(20))
print(multiply_2(4))

[out]
1
4
40
20
80

 

좋습니다. 2개까지는 충분히 만들 수 있을거 같습니다. 하지만, 5개, 20개 혹은 그이상이 필요할 때는 어떻게 해야할까요, 하나하나 직접 구현 하는 것은 굉장히 복잡하고, 비효율적입니다.

여기서! 클래스는 이러한 상황을 매우 간단하게 해결합니다!

 

예시)

#Multiply 클래스 생성
class Multiply:
    def __init__(self):
        self.result = 1
    
    def multiply(self, num):
        self.result *= num
        return self.result

# 클래스를 통한 계산기 1 
multiply_1 = Multiply()
print("계산기 1 결과")
print(multiply_1.multiply(2))
print(multiply_1.multiply(5))

# 클래스를 통한 계산기 2
multiply_2 = Multiply()
print("계산기 2 결과")
print(multiply_2.multiply(10))
print(multiply_2.multiply(9))

 

위와 같이 Multiply라는 클래스를 생성하여, multiply_1, multiply_2의 인스턴스를 형성하여 사용할 수 있습니다!

많이 비유되는 거처럼, 클래스는 마치 틀, 공장과 같은 역할을 해서 자신의 형태 결과물인 인스턴스를 만들어냅니다!

 

3. 객체의 클래스는 초기화를 통해 제어?

클래스를 생성하고 생성된 클래스를 인스턴스로 형성하여 반복적으로 기능을 할 수 있는 것이 클래스의 특징인데요, 여기서 항상 들어가는 "__init__()" 이라는 함수가 있습니다.

이는 생성자라하며, 인스턴스가 생성될때 항상 실행되는 것입니다.

즉, 위의 Multiply라는 클래스를 통해, Multiply_1, Multiply_2 라는 두개의 인스턴스가 생성되었는데요, 생성할때마다 __init__() 함수가 실행되면서 모두 self.result = 1이라는 문장을 실행합니다.

 

즉, result라는 변수를 인스턴스 형성때마다 초기화가 됩니다. 이러한 장점은 많은 변수를 추가할 필요없게 합니다.

 

💡메모

클래스에는 생성자와 소멸자라는 개념이 있습니다.

생성자는 위에서 설명한 "__init__()"에 해당되며, 이 생성자를 통해서 객체가 생성될때 어떤 변수의 값을 세팅하는 등 여러가지 작업을 할 수 있습니다.

반면에, "__del__()" 라는 소멸자는 리소스 해제등의 종료 작업을 하기위해 사용됩니다.

 

#Multiply 클래스 생성
class Multiply:
    def __init__(self):
        self.result = 1
    
    def multiply(self, num):
        self.result *= num
        return self.result

#클래스가 인스턴스로 형성될 때마다 __init__() 함수는 실행된다. 
#즉 result 인스턴스 형성 마다 개별적으로 초기화

4. 클래스는 객체의 구조와 행동을 정의?

이 특징은 위를 잘 읽으셨다면 충분히 이해 하실 겁니다.

즉, 어떠한 객체에 대해 복잡한 구조를 만들 필요 없이 클래스를 통해서 객체에 대한 행동과 속성을 구조화 시켜 간단하게 해결 할 수 있습니다!!

 

 

728x90
반응형
2021-06-25 15:31:11
728x90
반응형

01. 서문

최근에 DICOM 이미지를 축대칭을 하는 과정에서 numpy의 flip 메소드를 편하게 사용하여 작성합니다. 물론, 일반 이미지의 경우, cv2의 flip기능을 사용해도 편합니다.

다만, DICOM 의 array만 받아서 처리할때 배열을 다루는 numpy 함수를 사용했던 것을 메모차 작성합니다.

도움이 된다면 좋겠습니다.

02. 이미지 축 대칭

대칭에는 여러가지가 있지만, 본 포스트에서는 "반사대칭" 즉, 차원에 대한 대칭에 대해 다루었습니다.

2 차원에는 대칭축 (일명 대칭 선)이 있고 3 차원에는 대칭 평면이 있습니다.

모든 점에 대해 공통 평면의 반대편에서 등거리에있는 다른 점과 일대일 매핑이있는 객체 또는 그림을 대칭 대칭이라고합니다.

03. numpy flip

numpy의 문서를 보면 numpy flip은 다음과 같이 설명되어 있습니다.

 

flip 메소드는 배열의 원소들의 순서를 재배치 해주는 역할인것이고, 배열(array)을 입력으로 출력 또한 배열형태 이고, axis라는 옵션에 따라서 차원이 정해집니다.

예시.

>>> A = np.arange(10).reshape(2,5)
>>> print(A)
[[0 1 2 3 4]
 [5 6 7 8 9]]

>>>print(np.flip(A,0))
[[5 6 7 8 9]
 [0 1 2 3 4]]

>>>print(np.flip(A,1))
[[4 3 2 1 0]
 [9 8 7 6 5]]

위 와 같이 axis가 0, 1에 따라 위와 아래가 바뀌던지 원소들의 배열이 바뀐다던지 등의 차원 반전이 생깁니다. axis는 차원에 따라 최대 숫자가 늘어납니다.

 

04. numpy flip을 활용한 이미지 축 대칭 시키기

이를 통해서 이미지를 반전시키는 것이 가능한데요, 최근에 DICOM 이미지를 통해 변환한 경험으로, 오픈 DICOM 데이터인 "Digimouse"를 사용해보았습니다.

주로 사용하시는 DICOM형태는 아니고, nifty 파일 형식으로 되어 있는 이미지 파일이지만, DICOM 또한 pydicom으로 array를 출력하면 동일하게 적용됩니다. 

 

DICOM 오픈이미지; Digimouse

https://neuroimage.usc.edu/neuro/Digimouse_Download

 

Digimouse_Download - Biomedical Imaging Group"

Digimouse_Download (2012-02-12 07:26:42에 cpe-76-170-79-250가(이) 마지막으로 수정)

neuroimage.usc.edu

여기서 Atlas 데이터를 변형 해보았습니다.

4.1 R-L 대칭

좌: 원본

우: 변환본

4.2 A-P 대칭

좌: 원본

우: 변환본

4.3 I-S 대칭

좌: 원본

우: 변환본

위 와 같이 axis가 0, 1에 따라 위와 아래가 바뀌던지 원소들의 배열이 바뀐다던지 등의 차원 반전이 생깁니다. axis는 차원에 따라 최대 숫자가 늘어납니다.

5. 작성코드

import nibabel as nib
import numpy as np
# ctfn = '/home/hwan/code/study/04.DICOM/nibabel/ct_380x992x208.nii'
niifn = '/home/hwan/code/study/04.DICOM/nibabel/nii/atlas_380x992x208.nii'


proxy = nib.load(niifn)
data = proxy.get_fdata()
array = data.view(type=np.ndarray)
# np.flip(array,0) -> 좌우대칭 RL
# np.flip(array,1) -> 앞뒤대칭 AP 
# np.flip(array,2) -> 상하대칭 IS
array_flip = np.flip(array,2)
aff = proxy.affine
hdr = proxy.header

zflip = nib.Nifti1Image(array_flip,aff, hdr)
nib.save(zflip, './ISflip_atlas_380x992x208.nii')
728x90
반응형

'Programming > Python' 카테고리의 다른 글

파이썬 *arg 와 **kwargs 이해 하기  (0) 2022.03.11
파이썬 f-string  (0) 2021.12.31
파이썬 모듈이란? 패키지란?  (0) 2021.07.01
파이썬 PEP8 스타일 가이드 정리  (0) 2021.07.01
파이썬 클래스 상속  (0) 2021.06.28