Devin.KR

신청 규칙의 경계값

140분 안팎

학습 목표

조건의 경계와 예외를 실행 가능한 예제로 확인합니다.

개념

마감이라는 한 단어에도 여러 결정이 들어 있습니다

운영자가 “마감 전에 정원만큼 신청받아 주세요”라고 요청했습니다. 마감 시각과 같은 순간을 허용하는지, 정원이 승인 인원인지 접수 건수인지, 두 조건이 함께 막히면 어떤 안내를 먼저 보여 줄지는 비어 있습니다. 이번 레슨은 규칙 문장을 숫자 예제로 좁혀 조건문과 대조합니다. 이 규칙은 새 교육용 제안이며 m03 모의 API에 이미 있는 기능이 아닙니다. 업무 담당자의 결정을 받아야 할 항목도 문서에 남깁니다.

입력의 의미와 단위를 먼저 고정합니다

브라우저 실습은 한 줄에 now deadline count capacity 네 정수를 받습니다. now와 deadline은 같은 기준에서 센 분 단위 시각이며 실제 날짜 문자열을 변환하지 않습니다. count는 지금까지 접수된 신청 수, capacity는 접수 정원입니다. 네 값은 0 이상 안전한 정수이고 정원보다 count가 큰 입력도 허용합니다. 숫자 변환과 줄 읽기 코드는 제공되며 판정 함수 decide를 완성합니다. 개수 줄은 없고 빈 입력·공백 줄에는 출력을 만들지 않습니다.

업무 상태 PENDING인 신청도 접수 건수에 포함하는 제안입니다. APPROVED만 세면 승인 대기 중에도 정원을 넘길 수 있습니다. 취소 이후 정원을 되돌리는 규칙은 이번 입력에 없으므로 별도 검토 항목입니다. 정원 0은 “제한 없음”이 아니라 신규 접수 불가로 정합니다. 이런 의미는 JavaScript 언어가 정해 주는 것이 아니라 업무 정책입니다. 정책 담당자와 명세의 capacityBasis를 먼저 맞춥니다.

서로 겹치는 조건의 순서를 정합니다

첫 판단은 now가 deadline보다 크거나 같으면 CLOSED입니다. 마감 시각 자체는 허용하지 않는 제안입니다. 아직 마감 전이라면 count가 capacity보다 크거나 같을 때 FULL, 나머지는 OPEN입니다. 따라서 now=60, deadline=60, count=10, capacity=10에서는 CLOSED 하나만 출력합니다. 정원 조건도 참이지만 이번 안내 우선순위는 마감→정원→신청 가능입니다. 우선순위를 바꾸려면 정책 문장·코드·기대값을 함께 고칩니다.

return은 해당 판정 문자열을 돌려주고 함수의 나머지를 실행하지 않습니다. if 두 개를 두고 각각 console.log를 하면 마감과 정원이 동시에 막힐 때 두 줄을 출력할 수 있습니다. 실습에서는 한 입력에 하나의 최종 분류가 필요합니다. 함수가 결과를 하나 반환하고 줄 처리 코드가 그것을 한 번 출력하게 합니다. >=는 같은 값까지 포함하고 >는 같은 값을 제외하므로 비교 기호 하나가 업무의 포함 범위를 바꿉니다.

시간 경계의 전·동일·후를 비교합니다

deadline=60과 빈자리 한 개라는 조건을 고정하고 now=59·60·61을 비교합니다. 기대 결과는 OPEN·CLOSED·CLOSED입니다. now > deadline으로 잘못 쓰면 60도 OPEN이 되어 결함을 드러냅니다. 59와 61만 테스트하면 두 값은 통과할 수 있으므로 “전후를 확인했다”는 보고만으로는 충분하지 않습니다. 경계 자체를 포함했는지 입력 목록을 읽습니다. 기대값은 실행 전에 규칙 문장에서 작성합니다.

실제 서비스에서는 서버가 판단한 접수 시각을 기준으로 삼는 제안을 검토합니다. 기기 시계나 화면에 보이는 카운트다운만으로 서버 접수 여부를 결정하지 않습니다. 네트워크를 통과하는 동안 마감이 지나면 화면은 신청 가능으로 보였어도 서버가 거절할 수 있습니다. 이때 서버 응답을 기준으로 마감 안내와 내역 확인을 연결할 인수 기준이 필요합니다. 분 단위 숫자 실습은 시간대 변환이나 네트워크 지연을 검증하는 도구가 아닙니다.

정원 경계와 0의 의미를 비교합니다

마감 전 now=59, deadline=60을 유지하고 count=9·10·11, capacity=10을 비교합니다. OPEN·FULL·FULL이 기대 결과입니다. count=capacity를 허용하면 마지막 남은 자리가 없는데 신청을 열게 됩니다. count가 정원보다 큰 경우는 기존 자료 불일치나 정책 변경으로 생길 수 있으며 신규 접수는 막는다고 정합니다. 초과 건을 자동 삭제하는 기능은 이 판정의 결과가 아닙니다. 정원 초과 원인 확인은 담당자 후속 업무입니다.

now=0, deadline=1, count=0, capacity=0은 FULL입니다. 빈 자료가 아니라 실제 정원 0이라는 입력입니다. capacity || 10 같은 기본값을 쓰면 JavaScript에서 0을 다른 정원으로 바꿀 수 있어 약속과 달라집니다. 이번 함수는 입력값을 그대로 비교하고 기본값을 추가하지 않습니다. count=0, capacity=1이면 OPEN입니다. 두 사례를 함께 두어 0 자체를 오류로 처리하는 실수와 정원 0 의미 누락을 구별합니다.

조건의 조합을 예제로 검토합니다

시간 세 사례와 정원 세 사례가 있어도 조건 우선순위는 놓칠 수 있습니다. 같은 시각에 정원이 꽉 찬 60 60 10 10을 추가하여 CLOSED를 기대합니다. 같은 입력을 FULL로 기대하는 동료가 있다면 코드 오류를 논하기 전에 어떤 안내를 먼저 보낼지 합의합니다. 조건 표는 정책 충돌을 발견하는 도구이기도 합니다. 각 사례가 어떤 실수를 찾으려는지 옆에 이유를 붙이면 테스트 수만 늘리는 작업을 피할 수 있습니다.

빈 입력과 공백만 있는 입력은 신청 데이터가 한 건도 없다는 채점 입력입니다. 그래서 출력도 없습니다. 숫자 네 개가 모두 0인 행은 실제 판정 입력이며 마감과 같은 시각이므로 CLOSED입니다. 빈 문자열을 Number로 바꾸어 0으로 계산하면 두 상황을 섞습니다. 제공 파서는 trim 후 비어 있는지 검사하고 빈 행을 제외합니다. 입력 계약 밖의 음수·소수·열 개 열이나 문자 행을 복구하는 기능은 이번 과제에 포함하지 않습니다.

실행 오류와 규칙 불일치를 나누어 읽습니다

SyntaxError가 나타나면 괄호와 중괄호, 문자열 따옴표를 확인합니다. ReferenceError는 now나 deadline의 이름이 선언된 매개변수와 같은지 확인합니다. 실행은 끝났는데 OPEN과 CLOSED가 다르면 실패 입력의 시간부터 평가하고, FULL과 OPEN이 다르면 정원 비교를 봅니다. 분류를 설명하는 부가 문장을 출력하면 채점 문자열이 달라집니다. 코드 밖 설명에는 이유를 쓰되 표준 출력에는 행마다 CLOSED·FULL·OPEN 중 하나만 씁니다.

작은 함수가 보장하지 않는 것을 명세에 남깁니다

빈자리 하나에 두 사람이 동시에 제출하면 둘 다 이전 count를 읽을 수 있습니다. 이번 함수는 숫자 하나의 판정만 하므로 접수 저장까지의 동시성은 검증하지 않습니다. 서버가 검사와 저장을 어떤 원자적 처리로 묶는지 개발 담당자와 별도로 확인합니다. 후속 인수 기준에는 동시 접수에서 정원을 넘기지 않는 저장 결과와 거절 안내를 적을 수 있지만 지금 실행하지 않은 테스트를 통과했다고 쓰지 않습니다.

브라우저 solution 통과 뒤 spec.json의 rules와 boundaryCases를 완성합니다. 새 마감·정원 정책의 담당자, 제안 상태, 단위, 우선순위, 미검증 구현을 기록합니다. 더 읽기의 제어문 장은 비교와 반복의 문법을 보충합니다. 최종 미션에서는 이 숫자 규칙뿐 아니라 사용자 시나리오와 화면 복귀 행동이 모순되지 않는지 동료가 검토합니다. 함수 테스트 통과와 업무 개선 효과의 확인은 서로 다른 근거로 남깁니다.

따라하기

같은 시각을 비교합니다

Node 실행기에서 입력 없이 실행합니다. 빈자리가 있다는 전제에서 시간 경계를 대조합니다.

for (const now of [59, 60, 61]) {
  console.log(now, now >= 60 ? 'CLOSED' : 'OPEN');
}

실행 결과

59 OPEN
60 CLOSED
61 CLOSED

정원 자체를 비교합니다

마감 전이라는 전제에서 정원 직전·동일·초과를 실행합니다.

for (const count of [9, 10, 11]) {
  console.log(count, count >= 10 ? 'FULL' : 'OPEN');
}

실행 결과

9 OPEN
10 FULL
11 FULL

겹치는 조건과 0을 실행합니다

마감 우선과 정원 0 의미를 실제 출력에 대조합니다.

function decide(now, deadline, count, capacity) {
  if (now >= deadline) return 'CLOSED';
  if (count >= capacity) return 'FULL';
  return 'OPEN';
}
for (const row of [[60,60,10,10], [0,1,0,0], [0,1,0,1]]) {
  console.log(decide(...row));
}

실행 결과

CLOSED
FULL
OPEN

브라우저 판정과 미션을 연결합니다

아래 실습의 decide를 완성하고 경계 테스트를 통과시킵니다. 같은 8조합을 spec.json/boundaryCases에 옮기고 rules에 새 제안과 담당자를 기록합니다.

확인 문제

실습

행마다 now deadline count capacity 네 값을 받아 CLOSED·FULL·OPEN 하나만 출력합니다. 시각 두 값은 같은 기준의 분 단위, count는 접수 건수, capacity는 접수 정원이며 네 값은 0 이상 안전한 정수입니다. now가 deadline 이상이면 CLOSED, 마감 전이지만 count가 capacity 이상이면 FULL, 나머지는 OPEN입니다. 정원 0은 접수 불가이며 정원 초과 건수도 허용 입력입니다. 빈 입력과 공백 줄에는 출력하지 않습니다. 개수 줄·추가 설명은 없습니다. 제공 파서를 유지하고 decide만 수정합니다.

모범 답안
function decide(now, deadline, count, capacity) {
  if (now >= deadline) return 'CLOSED';
  if (count >= capacity) return 'FULL';
  return 'OPEN';
}
const raw = require('fs').readFileSync(0, 'utf8').trim();
const lines = raw === '' ? [] : raw.split(/\r?\n/).filter(line => line.trim() !== '');
for (const line of lines) {
  const values = line.trim().split(/\s+/).map(Number);
  console.log(decide(...values));
}

더 읽기

면접 질문

  • 개발자와 같은 결과를 떠올릴 수 있는 명세를 설명해 주시면 됩니다.