여러 기록 순서대로 처리하기
65분 안팎
학습 목표
입력 개수와 반복 횟수를 연결합니다.
개념
왜 여러 건을 순서대로 읽는가
한 건의 제목과 쪽수를 검사한 다음에는 여러 기록의 합계를 요청받습니다. 첫 책과 둘째 책마다 코드를 따로 쓰면 책이 추가될 때 코드도 늘어납니다. 반복문은 데이터 개수만 달라져도 같은 처리를 적용합니다. 이번 목표는 개수를 읽고 각 쪽수를 한 번씩 더하는 것입니다. 개수 줄 자체는 쪽수가 아닙니다. 첫 줄이 3이면 다음 세 줄만 합계에 넣습니다. 0쪽도 유효한 기록 한 건입니다. 0을 종료 신호로 해석하면 뒤의 기록을 놓칩니다.
for와 range의 종료
for index in range(n):은 0부터 n 직전까지의 값을 차례로 index에 연결합니다. n이 3이면 0, 1, 2로 본문을 세 번 실행합니다. 끝값 n은 포함하지 않습니다. index가 본문에서 필요 없어도 반복 횟수는 그대로입니다. range(n + 1)은 한 번 더 읽고 range(1, n)은 한 번 덜 읽습니다. 빈 목록에서 range(0)은 값을 내주지 않아 본문을 실행하지 않습니다. 입력을 읽는 줄과 합계를 갱신하는 줄은 같은 깊이로 들여쓰고 최종 출력은 for와 같은 깊이에 놓습니다.
누적값이 지켜야 할 약속
total = 0은 반복 전에 한 번 둡니다. total = total + pages는 지금까지의 합계에 이번 쪽수를 더한 결과를 다시 total에 연결합니다. total += pages도 같은 목적입니다. 반복 안에서 total을 0으로 초기화하면 앞선 기록을 잊습니다. 0, 10, 80을 처리할 때 시작 합계는 0이고 각 회차 뒤에는 0, 10, 90입니다. k건을 읽은 직후 total은 처음 k건의 합이라는 약속을 지킵니다. 이 설명은 코드를 읽을 때 초기화와 갱신이 어디 있어야 하는지 판단하는 근거입니다.
목록을 직접 순회하는 방법
pages_list = [0, 10, 80]처럼 값을 순서대로 모은 것이 리스트입니다. for pages in pages_list:는 번호 대신 원소를 직접 읽습니다. 이번 레슨에서는 모아 둔 값에도 같은 누적 계산을 적용하는 정도로 사용합니다. 자료구조 선택은 뒤 모듈에서 다룹니다. 합계 중 원소를 삭제하거나 append로 추가하지 않습니다. 삭제하면 다음 원소를 건너뛸 수 있고 추가하면 처리 대상이 달라집니다. 원본은 읽고 누적 변수만 바꾸면 합계 뒤에도 같은 기록을 재사용할 수 있습니다.
while과 중간 종료를 선택하는 기준
입력 개수가 정해져 있으므로 for가 자연스럽습니다. while count < n:을 쓰려면 본문에서 count를 증가시켜 종료 조건에 도달해야 합니다. 종료 조건을 바꾸는 줄을 빠뜨리면 반복이 끝나지 않을 수 있으므로 이번 따라하기는 세 번만 도는 유한한 예제로 확인합니다. break는 반복 전체를 끝내고 continue는 이번 회차의 남은 본문을 건너뜁니다. 전체 쪽수 합계는 모든 기록을 포함해야 하므로 0에서 break를 쓰지 않습니다. 숫자가 작다는 이유로 데이터를 제외하는 정책도 추가하지 않습니다.
완료 기준을 작은 입력으로 확인
실습에서는 합계 한 줄을 출력합니다. 빈 목록은 0, 한 건 7은 7, 세 건 0·10·80은 90이어야 합니다. 같은 값 5가 세 번 있으면 15로 더하며 중복이라는 이유로 한 번만 세지 않습니다. 큰 정수도 같은 덧셈 규칙으로 처리합니다. 출력이 마지막 값만 남으면 초기화 위치를 먼저 보고 여러 줄이면 출력 들여쓰기를 봅니다. 입력을 모두 읽었다는 종료 이유와 빈 경우에 초기값이 결과가 되는 이유를 설명한 뒤 다음 함수 레슨으로 넘어갑니다.
실행 전에 입력과 출력을 적습니다
브라우저 실습의 첫 줄은 기록 개수 n입니다. n은 0 이상의 정수이며 이어지는 데이터 줄은 정확히 n개입니다. 안내 문구 없이 input()으로 읽고, 숫자를 int로 변환합니다. 입력창에 따옴표를 넣지 않습니다. 따옴표는 소스의 문자열 표현에 쓰는 기호입니다. 이번 실습에서는 설명된 범위를 만족하는 입력이 주어집니다. 숫자가 아닌 문자열이나 부족한 줄까지 처리하는 예외 정책은 다음 모듈에서 이어갑니다. 정상 범위의 계산과 오류 정책을 동시에 바꾸지 않으면 실패 원인을 좁히기 쉽습니다.
오류 종류와 실제 위치를 함께 봅니다
EOFError: EOF when reading a line은 읽을 입력 줄이 없다는 뜻입니다. 첫 줄의 개수와 실제 줄 수, 반복 횟수를 먼저 비교합니다. ValueError: invalid literal for int()는 읽은 문자열이 정수 변환에 맞지 않는 경우입니다. 제목을 숫자로 읽었는지, 빈 줄이 끼었는지 확인합니다. TypeError는 연산에 맞지 않는 자료형을 조사하는 출발점입니다. traceback의 마지막 줄에서 종류를 읽고 그 위에서 자신의 파일과 줄 번호를 찾습니다. 숫자로 바꾸는 줄과 합치는 줄을 구분해 원문과 계산값을 각각 확인합니다.
관찰용 출력과 제출 출력을 나눕니다
따라하기에서는 중간값을 print로 관찰하지만 실습 제출에는 계약에 적힌 최종 결과만 남깁니다. print를 반복 안에 두면 여러 줄이 나오고 빈 목록에서는 출력되지 않을 수 있습니다. 최종 출력은 반복이 끝난 뒤 실행합니다. SyntaxError가 def나 for 줄을 가리키면 콜론을 확인하고 IndentationError는 들여쓰기를 확인합니다. 공백 네 칸으로 본문을 맞추며 탭과 섞지 않습니다. 문법이 맞아도 결과가 틀릴 수 있으므로 빈 목록, 한 건, 여러 건을 별도로 실행합니다. 기대값을 손으로 먼저 적고 실제 결과와 비교합니다.
프로젝트로 옮길 때의 검토 기준
이 레슨은 독서 기록 프로그램의 계산 부분을 표준 입력과 출력으로 작게 연습합니다. 모듈 미션에서는 앞 모듈의 app.py와 파일 기준 경로를 유지하고 여러 기록을 처리합니다. 읽은 쪽수는 책의 전체 분량이 아니라 이 기록에 적힌 수량입니다. 같은 책을 두 번 적었을 때 중복을 제거하는 정책은 이번 계약에 없습니다. 입력 목록을 읽기만 하고 수정하지 않으면 같은 자료로 다음 계산을 이어갈 수 있습니다. 결과가 맞는지뿐 아니라 호출 후 원래 자료가 같은지도 확인합니다. 더 읽기에서는 언어 기능의 폭을 넓히고 여기서는 자신의 입력과 반환 계약을 말로 설명합니다.
따라하기
반복 횟수
각 단계는 독립된 파일에 저장해 python3 파일이름.py로 실행합니다.
for index in range(3):
print(index)
실행 결과
0 1 2
회차별 누적
각 단계는 독립된 파일에 저장해 python3 파일이름.py로 실행합니다.
total = 0
for pages in [0, 10, 80]:
total += pages
print(pages, total)
실행 결과
0 0 10 10 80 90
세 건 입력
첫 줄 3 뒤에 0, 10, 80을 한 줄씩 입력합니다.
n = int(input())
total = 0
for index in range(n):
total += int(input())
print(total)
실행 결과
90
빈 목록
개수 0 한 줄만 입력합니다.
n = int(input())
total = 0
for index in range(n):
total += int(input())
print(total)
실행 결과
0
유한한 while
각 단계는 독립된 파일에 저장해 python3 파일이름.py로 실행합니다.
count = 0
while count < 3:
count += 1
print(count)
실행 결과
3
확인 문제
실습
첫 줄 n 다음 n줄의 0 이상 정수 쪽수를 모두 더해 정수 한 줄을 출력합니다. n=0이면 0입니다. 0쪽은 종료 신호가 아닙니다.
모범 답안
n = int(input())
total = 0
for index in range(n):
total += int(input())
print(total)
더 읽기
면접 질문
- for와 while은 어떤 기준으로 선택하나요?
- 누적값 초기화와 최종 출력을 반복 밖에 두는 이유는 무엇인가요?