def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
if filepath.split('.')[-1] == 'pcm':
pcm = np.memmap(filepath, dtype='h', mode='r')
sig = np.array([float(x) for x in pcm])
elif filepath.split('.')[-1] == 'wav':
sig, _ = librosa.core.load(filepath, sr=16000)
else:
raise ValueError("Invalid format !!")
if del_silence:
non_silence_ids = librosa.effects.split(sig, top_db=30)
sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
if input_reverse:
mfcc = mfcc[:,::-1]
return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )
[출처] [좋은 코딩 습관] 깔끔한 코드 짜는 10가지 규칙|작성자 Sooftware
1) 변수, 클래스명에는 동사를 넣지 않는다
class: FeatureExtract (X)
class: FeatureExtractor (O)
var: work (X)
var: worker (O)
var: log (X)
var: logger (O)
변수, 클래스 명은 다음과 같이
count, worker_num, image, user ... 등
숫자, ~을 하는 객체, ~한 여부 (bool) 등이기 때문에
동사보다는 명사가 가장 잘 어울린다.
2) 함수명에는 동사를 넣는다
function: feature() (X)
function: get_feature() (O)
function: trainer() (X)
function: train() (O)
반면, 함수의 경우 ~을 하는 행동을 정의한다.
feature를 받아오는 함수라고 하면, feature() 보다는 get_feature() 과 같이 ~하다 라는
의미가 담긴 명명이 잘 어울린다.
3) 변수 명에 굳이 관사를 넣지 않는다
var: a_cat (X)
var: cat (O)
가장 좋은 변수 명은 짧으면서도 효과적으로 의도를 전달하는 변수명이다.
굳이 관사를 넣어 변수 명이 길어 질 필요가 없다.
관사를 넣는다고 의도 전달이 더 명확하게 되는 것도 아니므로
변수 이름, 함수 이름, 클래스 이름에 특수한 경우를 제외하고는
굳이 관사를 넣지 않는다.
4) 변수 이름에 전치사는 최대한 생략
var: the_number_of_worker (X)
var: worker_num (O)
number_of_worker 같이 전치사를 넣는 경우가 있다.
그러나 단순히 의도만 표현하는데 굳이 문법을 갖출 필요는 없다.
'number_of_worker' 보다는 'worker_num'이 의미가 같으며 더 간결하다.
참고로 수를 세거나 숫자를 표기하는 변수는 some_num, count_some, cnt_some 형식을 많이 사용한다.
class: Seq2seq
function: sentence_to_id()
var: char2id
위와 같이 'to' 는 함수나 변수에서 자주 쓰이는데 이는 짧지만 의도를 잘 전달하는 단어이기에 그렇다.
더불어 to 의 경우 2(two) 와 발음의 유사성으로 _to_ 라는 네 글자를 2라는 한 글자로 줄여 char_to_id 가 char2id 처럼 쓰인다.
5) 단수와 복수를 구분
items = [1,2,3,4,5]
for item in items:
print(item)
단수와 복수를 구분해놓으면 코드 읽기가 편하다
단수형이면 어떤 값 혹은 객체가 하나인 자료형, 복수형이라면 여러 값 혹은 객체가 들어 있는 자료형으로 구분 가능하다.
6) 사용하는 언어의 암묵적 Rule을 지킨다
CamelCase: Java
snake_cake: c
Hybrid: python
어떤 언어를 사용 시, 대부분 프로그래머가 지키는 암묵적 Rule이 있다.
프로그램 실행이나 결과에 영향을 주는건 아니지만, 타인의 코드를 더 읽기 편하게 하거나 사용하기 용이하게 하는 규칙이다.
예시로 Java의 CamelCase와 C언어의 snake_case가 있다.
camel case는 단어&단어 사이를 대문자로 구분하는 방법으로, Java에서 변수, 함수, 클래스 명 모두 camel case를 권장한다.
반면 c언어는 snake case를 자주 사용하며, 단어&단어 사이를 ' _ ' 로 구분한다.
CamelCase Example
var: raiseValueError
var: sentenceToId
snake_case Example
var: raise_value_error
var: sentence_to_id
파이썬은 'PEP-8'이라는 권장 형식이 있다. 그러나 권장 사항일 뿐 더 깔끔한 코딩이 가능하다면 규칙을 지킬 필요는 없다.
- 클래스 명은 대문자로 시작하고 CamelCase를 따르며, 함수 명은 snake case를 따른다.
- 클래스 내부에서 사용하는 메소드는 메소드 앞에 ' _ '로 시작한다.
7) 보편적으로 사용하는 변수명/규칙 을 사용한다.
temp, obj, worker
some_num, count_some
flag, idx, is_condition
info, freq, token
타인의 코드를 보면 보통 꼭 등장하는 변수 이름이 있다.
- temp : 특정 변수를 임시 저장하는 변수
- flag : 특정 조건이 성립했는지 체크하는 변수
- is_condition : bool 타입 변수에서 쓰는 변수
- some_num : 특정 수를 세거나 표기하는 변수
특정 변수 명은 이름만으로 어떤 역할을 할 지 예측 가능한데, 예시로 bool 타입과 int 타입 등이 있다.
자주 사용하는 변수 명이나 형식은 분야에 따라 차이가 있으므로, 같은 분야의 여러 코드를 보면 많은 도움이 된다.
8) 상수는 모두 대문자로 표시
var: layer_size = 6 (X)
var: L = 6 (O)
var: main_width = 1024 (X)
var: MAIN_WIDTH = 1024 (O)
var: main_height = 768 (X)
var: MAIN_HEIGHT = 768 (O)
불변 값의 상수라면 그 값이 변하지 않음을 표시해줘야 한다.
그에따라 보통 모두 모두 대문자와 _ 로만 구성된 변수는 상수로 통한다. (물론 단어 사이를 구분할 때도 _ 를 쓴다.)
9) 변수가 길면 적당히 자른다.
var: total_distance (△)
var: total_dist (O)
var: user_information (△)
var: user_info (O)
var: worker_number (△)
var: worker_num (O)
var: index (△)
var: idx (O)
var: indices (△)
var: ids (O)
var: probability (△)
var: prob (O)
명확한 의도 전달을 위해 자세히 쓰는건 좋지만, 너무 긴건 코드를 복잡하게 한다.
10) 로직이 끝나면 한 줄 띄어준다.
같은 함수 내에도 여러 로직이 있다.
변수를 선언 부분, 계산 부분, for 등의 반복문 등이 그렇다.
'하나의 함수를 한 화면 내에 모두 들어오게' 하기 위해 줄 띄우기 없이 모두 붙이는 경우가 있으나, 이는 가독성이 매우 떨어지는 일이다.
[예시.1] 한 화면에 모두 채운 경우
def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
if filepath.split('.')[-1] == 'pcm':
pcm = np.memmap(filepath, dtype='h', mode='r')
sig = np.array([float(x) for x in pcm])
elif filepath.split('.')[-1] == 'wav':
sig, _ = librosa.core.load(filepath, sr=16000)
else:
raise ValueError("Invalid format !!")
if del_silence:
non_silence_ids = librosa.effects.split(sig, top_db=30)
sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
if input_reverse:
mfcc = mfcc[:,::-1]
return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )
[예시.2] 한 줄씩 띄어쓰는 경우
def get_librosa_mfcc(filepath, n_mfcc = 40, del_silence = False, input_reverse = True):
if filepath.split('.')[-1] == 'pcm':
pcm = np.memmap(filepath, dtype='h', mode='r')
sig = np.array([float(x) for x in pcm])
elif filepath.split('.')[-1] == 'wav':
sig, _ = librosa.core.load(filepath, sr=16000)
else:
raise ValueError("Invalid format !!")
if del_silence:
non_silence_ids = librosa.effects.split(sig, top_db=30)
sig = np.concatenate([sig[start:end] for start, end in non_silence_ids])
mfcc = librosa.feature.mfcc(sig, sr=16000, hop_length=160, n_mfcc=n_mfcc, n_fft=400, window='hamming')
if input_reverse:
mfcc = mfcc[:,::-1]
return torch.FloatTensor( np.ascontiguousarray( np.swapaxes(mfcc, 0, 1) ) )
'Programing > TIP' 카테고리의 다른 글
[Code Review] Egoless Programing (코드 리뷰 자세 10계명) (0) | 2022.05.13 |
---|---|
[Console] win10 의 Console 명령어 (0) | 2022.05.12 |
[JavaScript] ';' 을 왜 써야하는가? (0) | 2022.01.25 |
[Java] 이클립스 단축기 TIP (0) | 2021.03.05 |
댓글