프로그래밍웹 교과서
이 페이지의 목차
3단원 · 4차시

설계한 프로그램의 알고리즘 작성

알고리즘 설계예외 상황의사 코드검토

학습 목표

  • 설계한 각 기능의 알고리즘을 순서도 또는 의사 코드로 작성한다.
  • 알고리즘의 빈틈과 예외 상황을 찾아 보완한다.

관련 성취기준

  • 프그03-02

    산업 현장에서 필요로 하는 프로그램의 구조를 설계하여 기본 개발 설계서를 작성한 후, 설계된 프로그램의 알고리즘을 작성할 수 있다.

생각 열기 — “평균을 낸다”의 안쪽

3차시 설계서에 summarize 부품을 이렇게 적었다.

받는 것: 정수 목록 · 돌려주는 것: 결과 묶음 하는 일: 범위 밖 값을 빼고 인원·평균·최고·최저를 낸다

이제 이 부품을 맡은 사람이 코드를 쓰려고 앉았다. 그런데 손이 멈춘다. 값을 하나씩 보면서 무엇을 어떤 순서로 갱신해야 하는지, 최고점의 처음 값은 무엇으로 두어야 하는지가 적혀 있지 않기 때문이다.

부품마다 알고리즘을 적는다

설계서가 부품의 겉모습을 정했다면, 알고리즘은 부품의 안쪽을 정한다. 1단원 7차시에서 익힌 의사 코드를 그대로 쓴다.

summarize의 알고리즘은 이렇게 된다.

[summarize — 점수 목록에서 통계를 낸다]
 1  입력: 점수 목록
 2  출력: 결과 묶음, 또는 쓸 수 있는 값이 없으면 "없음"
 3
 4  인원 ← 0
 5  제외 ← 0
 6  합계 ← 0
 7  최고 ← 아직 없음
 8  최저 ← 아직 없음
 9
10  점수 목록의 각 점수에 대하여 되풀이한다
11      만약 is_valid(점수) 가 거짓이면
12          제외 ← 제외 + 1
13      아니면
14          만약 인원 = 0 이면
15              최고 ← 점수
16              최저 ← 점수
17          아니면
18              만약 점수 > 최고 이면  최고 ← 점수
19              만약 점수 < 최저 이면  최저 ← 점수
20          합계 ← 합계 + 점수
21          인원 ← 인원 + 1
22
23  만약 인원 = 0 이면
24      "없음" 을 돌려주고 끝낸다
25
26  평균 ← 합계 ÷ 인원
27  (인원, 제외, 평균, 최고, 최저) 를 돌려준다

14~16줄이 생각 열기의 함정을 막는 부분이다. 최고·최저를 0이나 100 같은 특정 값으로 시작하지 않고, 첫 번째 쓸 수 있는 점수를 그대로 넣는다. 이렇게 하면 점수 범위가 무엇이든 옳게 동작한다.

23~24줄은 쓸 수 있는 값이 하나도 없을 때 빠져나가는 출구다. 이 줄이 없으면 26줄에서 0으로 나누게 된다.

예외 상황을 먼저 찾는다

알고리즘을 적는 진짜 이유는 순서를 적기 위해서가 아니라 빠진 경우를 찾기 위해서다. 정상적인 흐름은 대개 쉽게 떠오른다. 문제는 그 바깥이다.

summarize 에서 찾아낸 예외 상황
예외 상황언제 생기는가다루지 않으면몇 줄에서 다루는가
빈 목록점수를 하나도 넣지 않았다26줄에서 0으로 나눈다 — 프로그램이 멈춘다23~24
전부 범위 밖−1, 200 만 넣었다. 걸러 내고 나면 빈 목록이 된다위와 같다23~24
첫 값 비교 기준최고·최저의 처음 값을 무엇으로 둘 것인가0으로 두면 음수만 있을 때 최고가 0으로 나온다14~16
모두 같은 점수80, 80, 80 을 넣었다문제없다. 최고와 최저가 같을 뿐이다따로 다룰 것 없음
숫자가 아닌 값"칠십오" 를 넣었다이 부품에서는 생기지 않는다 — read_scores 가 걸러 넘긴다다른 부품이 담당

마지막 두 줄이 중요하다. 예외를 찾았다고 전부 여기서 다뤄야 하는 것은 아니다. “모두 같은 점수”는 따져 보니 문제가 없었고, “숫자가 아닌 값”은 다른 부품의 책임이다. 3차시 설계서에서 read_scores의 「실패하면」 칸에 그렇게 적어 두었다.

예외 하나가 순서도를 어떻게 바꾸는가

23~24줄이 있고 없고의 차이를 그림으로 보면 분명해진다.

예외를 다루지 않은 절차반복이 끝난 뒤 곧바로 나눈다.평균 ← 합계 ÷ 인원결과를 돌려준다끝인원이 0이면 이 줄에서 멈춘다.예외를 다룬 절차나누기 전에 인원을 확인한다.인원 = 0 ?예아니오“없음” 을돌려준다평균 ← 합계 ÷ 인원결과를 돌려준다끝어느 길로 가든 끝난다.
같은 계산이지만 왼쪽은 인원이 0일 때 멈춘다. 판단 하나가 그 길을 막는다.자체 제작

책상 검사 — 손으로 따라가 본다

알고리즘을 적었으면 실행해 보기 전에 손으로 따라가 본다. 이것을 책상 검사라 한다. 변수마다 칸을 만들고 한 줄씩 짚어 가며 값을 적는다.

입력이 88, 92, −5 일 때 summarize를 따라가면 이렇게 된다.

단계 보는 점수 is_valid 인원 제외 합계 최고 최저
시작 (4~8줄) — — 0 0 0 아직 없음 아직 없음
1회 (11~21줄) 88 참 1 0 88 88 88
2회 92 참 2 0 180 92 88
3회 −5 거짓 2 1 180 92 88
끝 (23줄) — — 인원이 0이 아니므로 계속 진행
끝 (26줄) — — 평균 = 180 ÷ 2 = 90.0

돌려주는 값은 인원 2, 제외 1, 평균 90.0, 최고 92, 최저 88이다. 손으로 낸 이 값이 나중에 테스트의 기대 결과가 된다.

책상 검사는 특히 아래 입력으로 해 보면 좋다.

  • 평범한 입력 — 흐름이 맞는지 본다
  • 값이 하나뿐인 입력 — 첫 값 처리(14~16줄)가 맞는지 본다
  • 전부 걸러지는 입력 — 출구(23~24줄)로 빠지는지 본다

알고리즘을 다 적었는지 확인하는 법

  1. 설계서의 부품마다 알고리즘이 하나씩 있는가?
  2. 각 알고리즘의 첫 줄에 입력, 둘째 줄에 출력이 적혀 있는가?
  3. 나눗셈이 있는 곳마다 나누는 값이 0이 될 길을 막았는가?
  4. 되풀이하는 부분마다 무엇이 변해서 끝나는지 말할 수 있는가? (1단원 6·7차시)
  5. 설계서의 「실패하면」 칸에 적은 내용이 알고리즘에 실제로 들어가 있는가?

활동

프로젝트

핵심 기능 2개의 알고리즘을 의사 코드로 작성

약 45분

3차시 설계서에서 정한 부품 중 핵심 두 개를 골라 알고리즘을 적는다.

1단계 — 의사 코드로 적는다 (15분)

부품마다 아래 형식을 지킨다.

[부품 이름 — 한 줄 설명]
 1  입력: …
 2  출력: …
 3
 4  (여기서부터 절차)
  • 줄 번호를 붙인다. 나중에 “몇 줄에서 다룬다”고 가리킬 수 있어야 한다.
  • 들여쓰기로 조건과 반복의 범위를 나타낸다.
  • 저장은 ← 로 적는다.

2단계 — 예외를 찾는다 (10분)

네 가지 물음을 던지고 찾은 것을 표로 적는다.

예외 상황 언제 생기는가 다루지 않으면 몇 줄에서 다루는가

「다루지 않으면」 칸이 “문제없다”인 항목도 표에 남긴다. 따져 봤다는 기록이 되기 때문이다. 다른 부품이 담당하는 것도 그렇게 적는다.

찾은 예외 중 알고리즘에 빠진 것이 있으면 1단계로 돌아가 줄을 추가한다.

3단계 — 책상 검사 (15분)

세 가지 입력으로 손으로 따라간다. 계산기를 쓰지 않는다.

입력 왜 이 입력인가 손으로 낸 결과
평범한 경우
값이 하나뿐인 경우
전부 걸러지거나 비어 있는 경우

변수가 여럿이면 변수마다 칸을 만든 표로 한 줄씩 적는다.

4단계 — 짝과 바꿔 읽기 (5분)

짝의 의사 코드만 보고 적힌 그대로만 따라가 본다. 1단원 1차시 활동과 같은 규칙이다 — 적히지 않은 판단은 하지 않는다. 막히는 곳에 표시해 돌려준다.

3단계에서 손으로 낸 결과는 버리지 말고 보관한다. 7차시 테스트 사례에서 그대로 쓴다.

개념 확인 문제

보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.

설계서와 알고리즘이 각각 정하는 것을 바르게 짝지은 것은?프그03-02

최고점을 찾을 때 처음 값을 0으로 두지 않고 '첫 번째 쓸 수 있는 점수'로 두는 이유는?프그03-02

summarize 알고리즘에서 '인원 = 0 이면 없음을 돌려주고 끝낸다'는 줄을 빠뜨리면 생기는 일은?프그03-02

책상 검사(손으로 따라가기)를 하는 목적으로 가장 알맞은 것은?프그03-02

예외 상황을 찾는 물음으로 알맞지 않은 것은?프그03-02

예외를 정리한 표에서 '모두 같은 점수 → 문제없다'처럼 문제가 없는 항목도 표에 남기는 이유는?프그03-02

더 알아보기

심화한 번만 훑고 끝내기

위 알고리즘은 점수 목록을 한 번만 지나가면서 인원·합계·최고·최저를 모두 구한다. 나눠서 생각하면 “합계를 구하려고 한 번, 최고를 찾으려고 또 한 번” 훑고 싶어지는데, 그러면 목록을 네 번 지나가게 된다. 자료가 300개일 때는 차이를 못 느끼지만 30만 개가 되면 달라진다. 여러 값을 함께 구할 수 있으면 한 번에 구한다 — 1단원 6차시에서 다룬 효율의 실제 사례다. 다만 한 번에 너무 많은 일을 넣으면 읽기 어려워지므로, 읽기와 속도 사이에서 판단해야 한다.

실무예외를 어디서 다룰지 정하는 문제

“숫자가 아닌 값”을 read_scores에서 걸러 넘기기로 한 것은 판단이었다. summarize에서 다루게 할 수도 있었다. 어느 쪽이 나은가? 일반적으로 잘못된 값은 들어오는 문 앞에서 막는 편이 낫다. 안쪽 부품들이 “여기 오는 값은 이미 정수다”라고 믿고 만들어질 수 있기 때문이다. 반대로 문 앞에서 막지 않으면 모든 부품이 같은 검사를 되풀이해야 한다. 이 판단을 설계 단계에서 정해 문서에 적어 두는 것이 3차시의 「실패하면」 칸이다.

심화의사 코드는 언어가 아니다

의사 코드에는 정해진 문법이 없다. ← 대신 =를 써도 되고, 한국어 대신 영어로 적어도 된다. 중요한 것은 읽는 사람이 한 가지 뜻으로만 읽는가다. 그래서 팀 안에서 표기를 통일해 두면 좋다. 다만 의사 코드를 너무 코드처럼 적으면 특정 언어의 문법에 묶여, 다른 언어로 옮길 때 도움이 안 된다. Python으로도 C로도 옮길 수 있는 수준에서 멈추는 것이 알맞다. 이 단원의 알고리즘 하나가 5차시에서 두 언어로 갈라지는 것을 직접 보게 된다.

이어지는 학습

이 차시를 이해하려면 다음을 먼저 알아야 한다.

  • 1단원 7차시의 순서도와 의사 코드 — 프로그래밍 프그01-03

교과서에서 찾기

교과서해당 위치쪽수
성림출판(Python)프로그램 설계와 구현 › 01 프로그램 개발 과정 > 2 프로그램 설계212쪽
씨마스커뮤니케이션(Python)프로그램 설계와 구현 › 1 프로그램 설계와 절차202쪽
삼양미디어(Python)프로그램의 설계와 구현 › 01 프로그램 개발 과정172쪽
삼양미디어(C)프로그램의 설계와 구현 › 01 프로그램 개발 과정178쪽
씨마스(C)프로그래밍 설계와 구현 › 1 프로그래밍의 설계와 절차188쪽
웅보출판사(C)프로그램 설계와 구현 › Chapter 02 프로그램 설계208쪽