알고리즘과 Better Code

Park, Jinyong·2020년 4월 10일
0

Code States - Pre Course

목록 보기
7/11

Achievement Goals

  • 요구사항이 하나 이상의 문제를 여러 개로 쪼개서 생각할 수 있다.
  • 해당 위치에 바르게 주석을 남길 수 있다.
  • 잘게 쪼갠 특정 문제를 JavaScript의 개념과 연결시킬 수 있다.
  • 함수를 재귀 호출하는 방법에 대해 이해할 수 있다.
  • 모든 사람이 읽기 쉬운 코드를 작성할 수 있다.

알고리즘

알고리즘은 문제를 해결하기 위한 절차를 만들어내는 과정을 뜻한다.

큰 문제를 작은 문제로 분해하고, 절차를 추론하며, 반복되는 패턴을 찾는 과정으로 알고리즘 문제를 해결한다. 문제를 풀기 전에 의사코드(pseudocode)를 작성할 수 있어야 한다. 프로그램의 절차를 일반적인 언어로 작성할 수 있어야 한다.

예시

양의 정수가 주어졌을 때, 주어진 수의 각 자리의 숫자를 곱했을 때 한 자릿수가 될 때까지 계산 횟수를 반환하는 코드를 작성하라.
ex) input: 39, output: 3

의사코드

  • 숫자를 입력받는다.
    • 각 자릿수를 한 자릿수로 분할해서 한 곳에 묶는다. (234 -> [2,3,4])
    • 묶은 수를 곱한다. ([2,3,4] -> 2 * 3 * 4 = 24)
    • 곱한 수가 한 자릿수가 될 때까지 위의 과정을 반복하고, 반복한 횟수를 저장한다.
  • 결과인 반복한 횟수를 반환한다.

JavaScript의 개념과 연결

  • 숫자 num을 입력받는 multiplicativePersistence 함수를 작성한다.
    • num의 각 자릿수를 한 자릿수로 분할한다.
    • numtoString 메서드를 이용해 문자열로 변환한다.
    • split 메서드를 이용해 한 자릿수로 분할해서 배열로 만든다.
    • 배열의 요소를 모두 곱하고 그 결과를 num에 저장한다.
    • 그 값이 10 이상이면 다시 자신을 호출한다. 미만이라면 1을 반환한다.
    • 반환된 1은 자신이 호출된 곳으로 돌아가 호출된 스택만큼 1씩 증가한다.
  • 그 결과를 반환한다.

문제 분해

  1. 자릿수 분할한다.

    let separatedNumbers = num.toString().split('');
  2. 배열의 요소를 모두 곱한다.

    num = separatedNumbers.reduce((acc, val) => acc * val);
  3. 그 값이 10 이상이면 자신을 호출하고, 아니면 1을 반환한다.

    return num > 10 ? multiplicativePersistence(num) + 1 : 1;

복잡한 형태가 요구된다면 함수로 분할해 모듈화할 수 있다.

최종 코드

function multiplicativePersistence(num) {
  let separatedNumbers = num.toString().split('');
  num = separatedNumbers.reduce((acc, val) => acc * val);
  return num > 10 ? multiplicativePersistence(num) + 1 : 1;
}

console.log(multiplicativePersistence(39)); // 3

알아보기 쉬운 코드 작성법

Style Guide 항목과 관련해서 가장 많이 하는 실수는 indentation, spacing, semicolon, and variable naming이다. 이런 부분에서 발생하는 실수는 일반적인 언어에서 문법을 틀리고 잘못된 표현을 여기저기 사용하는 것과 비슷하다. 작은 문제를 해결할 때는 별로 상관없지만 큰 프로젝트에서 점점 쌓이다보면 생산성이 낮아지고, 개발속도가 더뎌지는 원인이 된다.


코드 가독성

코드 가독성을 높이려면, 코드의 목적이 뚜렷하고 자명해야 한다. 또한, 구조가 일관되고, 예측 가능해야 한다. 코드의 일관성이 부족하면 코드를 해석하는데 어려워진다. 다른 사람은 물론이고, 시간이 지나 자신이 작성한 코드를 보는데도 난감해질 수 있다. 해석하기 쉬운 코드를 작성하자.


Indentation

종속되어 있는 코드를 작성할 때, 자식 코드 블록은 부모 코드 블록보다 두 칸 들여쓰기를 해야 한다.
이 때 가장 중요한 점은 tab이 아닌 space를 사용해야 한다.


Naming

표기법

  • 파스칼
    • 단어의 머리 문자마다 대문자를 사용
    • Person, RepublicOfKorea
  • 카멜
    • 첫 단어는 소문자. 그 대문자로 단어를 구분
    • numbers, capitalizedString
  • 스네이크
    • '_'로 단어를 구분
    • target_input, MAX_INTERGER
  • 헝가리안
    • 각 변수마다 특성을 앞에 기술
    • sName, iNumber, cAlphabet

JavaScript에서 변수의 이름은 모두 카멜 표기법을 사용한다. 클래스 이름은 파스칼 표기법을 사용한다.

Variable names

변수 이름은 한 단어로 표현하는 것이 가장 이상적이다. 특히 포괄적인 의미의 단어보다. 핵심을 잘 담은 특정한 의미를 가지는 단어를 사용하는 것이 좋다. 변수가 존재하는 목적을 고려서해서 지어야 한다.

배열과 같이 여러 항목을 담을 수 있는 변수는 복수 명사를 사용한다. 단순히 List를 붙이는 것은 지양된다.

Boolean names

Boolean에 관한 변수 이름은 형식을 가지고 있다. 변수의 앞에 is 혹은 are를 붙인다. be동사가 들어가는 만큼 뒤에는 형용사가 많이 온다.

Function names

함수 이름을 지을 때는 동사로 시작해야 한다. 함수의 동작을 가장 잘 표현해줄 수 있는 동사가 있다면 함수의 목적이 명확한 것이다. 코드를 읽는 사람 입장에선 함수의 이름만으로 동작을 파악하기 쉬워진다.

Capital letters in variable names

classConstructor function의 이름을 지을 때는 변수 이름 첫 글자를 대문자로 한다.
const를 이용한 상수의 이름을 지을 때는 변수 이름 전체를 대문자로 하고 띄어쓰기는 _로 구분한다.


Symbol / Punctuation

문법적으로 중괄호가 생략 가능하더라도 항상 써야 한다.

Quoting

JavaScript에서 문자열을 쓸 때는 " 큰 따옴표를 사용하지 말고 ' 작은 따옴표를 사용한다. 섞어 쓰는 것은 좋지 않다. HTML에서는 큰 따옴표를 사용한다. Backquote(`)도 좋은 선택이다.

Semicolon은 생략 가능하지만 항상 붙인다.


Operators and keywords

엄격한 비교 연산자 (===, !==)를 사용해야 한다.

Ternary Operator (condition ? a : b)

3항 연산자는 if/else 문 대신 작성하기 적합하다. 그러나 긴 코드의 경우 읽기 어렵게 만들 수 있으므로 아주 짧고 명확하게 작성할 수 있을 것 같을 때만 사용해야 한다.

not 연산자는 부정하는 대상 바로 옆에 붙여 사용해야 한다.


짧게 쓰기

코드를 분명하고, 가능하면 짧게 작성해야 한다.

되도록 not 연산자를 적게 쓰는 방향으로 작성해야 한다.

함수에서 Boolean 결과값을 바로 반환해야 한다.


코드 문장과 구문 사이의 공간

줄바꿈을 최소로 사용해야 한다.

= 연산자로 줄맞춤한다고 들여쓰기를 사용하지 말아야 한다.

콤마 뒤는 띄어 써야 한다.

연산자 양 옆은 띄어 써야 한다.


주석

  • 주석을 사용하기 보다 명확한 naming으로 그 의미를 분명히 하는 것이 좋다.
  • 주석으로 코드의 흐름을 전달하려고 하지말고 코드로 전달해야 한다.
  • 주석은 코드의 목적을 설명해야 한다. 코드가 어떻게 작동하는지를 설명하면 안 된다.
  • 임시 주석은 필요 없어지면 모두 지워야 한다.

0개의 댓글