스크롤하여 페이지 넘기기
Computer Science Principles · AP Computer Science Principles
협업, 설계, 디버깅
프로그램은 한 번에 쓰이지 않습니다. 조사하고, 설계하고, 대략 만들고, 테스트하고, 다시 살펴보기를 사용자에게 필요한 일을 해낼 때까지 몇 바퀴고 되풀이합니다.
그림은 흔한 개발 과정 하나를 실행합니다. 조사하고 되돌아봄, designing, prototyping and testing입니다. 빨간 공이 지금 하고 있는 작업이며, 각 단계에서 팀을 앞선 단계로 돌려보낼 수 있습니다. 한 바퀴를 돌 때마다 프로그램(파랑)이 더 완성됩니다. 3바퀴를 돌면 버전 3이 됩니다.
과정은 계획한 단계를 따르는 정돈되고 의도적인 방식일 수도 있고, 아이디어를 시도해 보며 잘되는 것을 남기는 탐색적인 방식일 수도 있습니다. 과정은 여러 가지이며, 이 네 단계는 대부분에 공통됩니다.
이 단원은 AP Computer Science Principles의 빅 아이디어 1인 창의적 개발로, 객관식 시험의 10–13%입니다. 함께 일하기(1.1), 프로그램이 무엇을 하며 어떤 입력과 출력을 쓰는지(1.2), 프로그램을 어떻게 설계하고 만들고 문서화하는지(1.3), 오류를 어떻게 찾아 고치는지(1.4)를 다룹니다. 이 단원의 마지막 쪽인 Create 수행 과제의 작업이기도 합니다.
그리고 이를 개선하는 관점들
컴퓨팅 혁신은 기능에서 프로그램을 필수적인 부분으로 포함합니다.
자율 주행 자동차처럼 물리적일 수도 있고, 사진 편집 소프트웨어처럼 비물리적 컴퓨팅 소프트웨어일 수도 있으며, 전자 상거래처럼 비물리적 컴퓨팅 개념일 수도 있습니다.
혁신은 협업을 통해 개선됩니다. 효과적인 협업은 혁신을 설계한 사람들의 다양한 재능과 관점을 반영하는 결과를 낳으며, 다양한 관점은 편향을 피하는 데 도움이 됩니다. 구성원이 모두 같은 경험을 공유하는 팀은 그 경험에 맞춰 만들기 쉽기 때문입니다.
그림은 앱이 처리해야 할 경우를 나열하는 가상의 팀입니다. 개발자 A 혼자서는 12개 중 5개를 생각해 냅니다. 개발자 셋이 함께하면 10개를 생각해 냅니다. 나머지는 사용자에게 의견을 구해서 나옵니다. 12개 중 12개입니다.
그래서 사용자와의 상담과 소통이 중요합니다. 잠재 사용자에게서 얻은 정보는 개발자가 프로그램의 목적을 다양한 관점에서 이해하고, 이를 온전히 반영한 프로그램을 만드는 데 도움이 됩니다.
짝 프로그래밍, 온라인 도구, 대인 관계 기술
집단은 공통된 협업 모형으로 혁신을 개발합니다. 그중 하나가 짝 프로그래밍입니다.
프로그래머 두 명이 컴퓨터 한 대를 함께 씁니다. 운전자(빨강)는 코드를 입력하고, 길잡이(파랑)는 쓰이는 대로 각 줄을 검토하며 실수를 잡고 앞을 내다봅니다. 그림의 중간에서 둘은 역할을 바꿉니다. 역할은 사람이 아니라 키보드를 따라갑니다. 이들이 쓰는 프로그램은 다음 쪽의 것입니다.
온라인 도구는 프로그래머가 같은 방에서 일하든 아니든 아이디어와 문서를 공유하고 그것에 피드백을 줄 수 있게 해 협업을 돕습니다.
효과적인 팀은 다음을 포함한 대인 관계 기술을 익힙니다.
프로그램이 무엇을 하는지, 그리고 어떻게
프로그램은 컴퓨터가 실행할 때 특정한 작업을 수행하는 프로그램 문장의 모음입니다. 프로그램을 흔히 소프트웨어라고도 합니다.
total ← 0 REPEAT 3 TIMES { n ← INPUT() total ← total + n } DISPLAY(total / 3) 코드 조각은 프로그램의 일부인 프로그램 문장의 모음입니다. 여기서는 2–6번째 줄의 반복문(그림의 파랑)입니다.
프로그램은 무엇을 하는지로 대략 설명할 수 있습니다. “사용자가 입력한 수 세 개의 평균을 표시한다.” 또는 무엇을 하는지와 문장들이 그것을 어떻게 하는지로 더 자세히 설명할 수 있습니다. “total을 0으로 하고, 세 번 수를 읽어 n에 넣고 total에 더한 다음, total / 3을 표시한다.”
프로그램은 여러 입력과 상황에서 작동해야 합니다. 그림은 이를 두 번 실행합니다.
| 입력 | 반복 후 total | 표시 |
|---|---|---|
| 4, 8, 9 | 21 | 7 |
| −2, 0, 5 | 3 | 1 |
프로그램의 동작은 실행하는 동안 어떻게 기능하는지로, 흔히 사용자가 어떻게 상호작용하는지로 설명합니다. 사용자가 수 세 개를 입력하면 수 하나가 나타납니다.
모든 혁신에는 목적이 있습니다. 문제를 해결하거나, 창의적 표현으로 관심사를 추구하는 것입니다. 목적을 이해하는 개발자가 프로그램을 더 잘 개발할 수 있습니다.
데이터가 들어가고 나오며, 여러 형태로
프로그램 입력은 프로그램이 처리하도록 컴퓨터에 보내는 데이터입니다. 프로그램 출력은 프로그램이 장치로 보내는 모든 데이터입니다.
둘 다 여러 형태로 나타납니다. 촉각(터치, 진동), 청각(말, 소리), 시각(카메라 이미지, 화면), 텍스트입니다. 그림은 각 형태의 입력을 하나씩 차례로 프로그램에 보내고, 각 형태의 출력을 하나씩 내보냅니다.
입력은 사용자나 다른 프로그램에서 올 수 있습니다. 오른쪽 아래의 텍스트 출력은 다른 프로그램으로 가며, 그 프로그램에는 입력입니다.
입력은 대개 프로그램이 내는 출력에 영향을 줍니다. 그리고 출력은 대개 프로그램의 입력 또는 이전 상태, 즉 저장해 둔 값을 바탕으로 합니다. 이 프로그램은 받은 입력의 개수(파랑)를 기억하므로, 화면을 같은 방식으로 터치해도 두 번째에는 다른 출력이 나올 수 있습니다.
지난 쪽의 평균 프로그램에서는 INPUT()을 세 번 호출한 것이 입력이었고, DISPLAY가 화면으로 출력을 보냈습니다.
문장이 촉발될 때 실행됨
이벤트는 어떤 동작과 연결되어 프로그램에 입력 데이터를 제공합니다.
이벤트는 키를 누르거나, 마우스를 클릭하거나, 프로그램을 시작하거나, 실행 흐름에 영향을 주는 그 밖의 정해진 동작이 일어날 때 생성됩니다.
이벤트 기반 프로그래밍에서는 프로그램 문장이 순차적인 제어 흐름이 아니라 촉발될 때 실행됩니다. 위에서부터 한 줄씩 실행되는 것이 아니라, 이벤트마다 그것을 처리하는 프로시저가 실행되고 프로그램은 다음 이벤트를 기다립니다.
PROCEDURE onStart() { count ← 0 DISPLAY(count) } PROCEDURE onClick() { count ← count + 1 DISPLAY(count) } PROCEDURE onKeyPress() { count ← count - 1 DISPLAY(count) } 시험 참고 자료에는 이벤트 구문이 없으므로, 여기서는 각 핸들러를 프로시저로 쓰고 가상의 환경이 이벤트가 일어날 때 그것을 호출합니다. 그림에서는 프로그램이 시작되고, 버튼이 세 번 클릭되고, 키가 한 번 눌린 뒤, 버튼이 한 번 더 클릭됩니다. 표시되는 값은 0, 1, 2, 3, 2, 3입니다.
count는 프로그램 전체에 속하므로 클릭마다 출력은 그 앞의 이벤트에 따라 달라집니다.
반복적과 점진적
개발 과정은 정돈되고 의도적일 수도, 탐색적일 수도 있습니다. 과정은 여러 가지이며, 대부분 조사하고 되돌아보기, 설계, 시제품 제작, 테스트 단계를 씁니다.
반복적인 과정은 과정 내내 피드백, 테스트, 되돌아봄을 바탕으로 다듬고 고쳐야 합니다. 앞선 단계로 돌아가야 할 수도 있습니다. 아래 줄에서는 프로그램 전체가 처음부터 대략적으로 있고, 피드백(빨강)을 받을 때마다 되돌려 보내져 모든 부분이 더 완성됩니다.
점진적인 과정은 문제를 더 작은 조각으로 나누고, 각 조각이 작동하는지 확인한 뒤에 전체에 더합니다. 위 줄에서는 조각을 한 번에 하나씩 만들고 테스트하며, 테스트를 통과해야 전체에 합류합니다.
둘은 반대가 아닙니다. 대부분의 팀은 둘 다 합니다. 조각별로 만들고, 피드백이 오는 대로 각 조각과 전체를 고칩니다.
요구 사항, 명세, 스토리보드, 모듈
프로그램의 설계는 요구 사항을 정하기 위한 조사에서 시작합니다.
조사는 프로그램의 제약과 이를 쓸 사람들의 우려와 관심사를 파악합니다. surveys, 사용자 테스트, interviews and 직접 관찰으로 할 수 있습니다.
프로그램 요구 사항은 프로그램이 어떻게 기능하는지를 설명하며, 프로그램이 제공해야 할 사용자 상호작용에 대한 설명을 포함할 수 있습니다. 프로그램의 명세는 그 요구 사항을 정의합니다. 도서관 스터디룸을 예약하는 가상의 앱을 예로 들면 (1) 사용자가 날짜를 고릅니다; (2) 사용자가 그날 비어 있는 방을 봅니다; (3) 사용자가 하나를 예약하고 코드를 받습니다입니다.
설계 단계는 명세를 어떻게 이룰지 개략적으로 정합니다. 다음이 포함될 수 있습니다.
그림은 그중 둘을 그립니다. 단계마다 화면 하나씩, 사용자의 탭으로 화면에서 화면으로 넘어가는 인터페이스의 스토리보드와, 요구 사항마다 하나씩 모듈로 나눈 프로그램입니다.
그리고 다른 사람의 코드 밝히기
프로그램 문서화는 코드 조각, 이벤트, 프로시저, 프로그램의 기능과 그것을 어떻게 개발했는지를 글로 설명한 것입니다.
주석은 사람이 읽도록 프로그램에 써 넣는 문서화의 한 형태이며, 프로그램의 실행 방식에는 영향을 주지 않습니다. 모든 프로그래밍 환경이 주석을 지원하는 것은 아니고 시험 참고 자료에도 주석이 없으므로, 그림에서는 각 프로시저의 문서화를 그 옆에 둡니다.
PROCEDURE average(numList) { total ← 0 FOR EACH num IN numList { total ← total + num } RETURN(total / LENGTH(numList)) } PROCEDURE isEven(n) { RETURN(n MOD 2 = 0) } average([6, 9, 3, 10])은 7을 반환합니다. 문서화는 개발 내내 작성하므로, average의 카드는 코드와 함께 늘어납니다. 다음 읽는 사람(나중의 자신일 때가 많습니다)이 각 부분이 무엇을 위한 것인지 알 수 있으므로, 혼자서든 팀으로든 올바른 프로그램을 개발하고 유지하는 데 도움이 됩니다.
공동으로 개발했거나 다른 출처에서 가져온 코드 조각은 반드시 밝혀야 합니다. 밝히는 글은 프로그램 문서화에 넣을 수 있으며, 출처 또는 원저자의 이름이 들어가야 합니다. 그림에서 isEven(파랑)은 다른 출처에서 온 것이며, 카드에 그렇게 적혀 있습니다.
각각 언제 드러나는가
프로그램 세 개가 있고, 각각 [90, 75, 82]의 모든 점수를 표시하려는 것이지만 각각 오류가 하나씩 있습니다.
구문 오류는 프로그래밍 언어의 규칙을 따르지 않은 프로그램의 실수입니다. 첫 번째 프로그램은 5번째 줄에 닫는 괄호가 빠져 있습니다. 프로그램이 전혀 실행되지 않습니다. 어떤 줄도 실행되지 않고 아무것도 표시되지 않습니다.
런타임 오류는 프로그램이 실행되는 중에 일어나는 실수입니다. 프로그래밍 언어마다 자신의 런타임 오류를 정의합니다. 두 번째 프로그램은 표시하기 전에 i에 1을 더하므로 75 and 82을(를) 표시한 다음 scores[4]을 요청합니다. 참조 시트에서 1보다 작거나 리스트의 길이보다 큰 인덱스는 오류이며, 프로그램은 종료됩니다.
논리 오류는 알고리즘이나 프로그램이 잘못되거나 예상치 못하게 동작하게 만드는 실수입니다. 세 번째 프로그램은 한 번 덜 반복합니다. 멈추게 하는 것은 아무것도 없습니다. 끝까지 실행되지만 점수 3개 중 2개만 표시합니다. 출력을 기대한 출력과 비교해야만 오류가 드러납니다.
scores ← [90, 75, 82] i ← 1 REPEAT LENGTH(scores) - 1 TIMES { DISPLAY(scores[i]) i ← i + 1 } 고치면 3번째 줄은 REPEAT LENGTH(scores) TIMES입니다.
범위를 벗어난 수
오버플로 오류는 컴퓨터가 정해진 값의 범위를 벗어난 수를 다루려 할 때 일어납니다.
많은 프로그래밍 언어는 정수를 정해진 비트 수로 저장하며, 그래서 값의 범위가 제한됩니다. 정수를 4비트로 저장하는 가상의 언어를 생각해 봅시다. 담을 수 있는 가장 큰 수는 1111이며, 이는 15입니다.
그림은 12부터 하나씩 셉니다. 한 단계마다 바뀌는 비트가 뒤집힙니다. 15에서 1을 더하면 다섯 번째 비트가 필요한데(16은 10000입니다), 저장 공간에는 4개뿐이므로 오버플로가 됩니다. 그다음에 어떻게 되는지는 언어에 따라 다릅니다. 어떤 언어는 오류와 함께 멈추고, 어떤 언어는 들어가는 비트만 남기고 틀린 값으로 계속합니다(여기서는 0).
실제 언어는 더 많은 비트를 쓰므로 한계가 훨씬 크지만, 그래도 한계입니다. 시험 참고 자료의 언어는 다릅니다. 거기서는 정수의 크기가 컴퓨터의 메모리로만 제한됩니다.
정해진 입력과 예상 출력
테스트는 정해진 입력을 사용해 알고리즘이나 프로그램이 기대한 결과를 내는지 확인하는 일입니다. 프로그래머는 그 결과를 바탕으로 프로그램을 수정합니다.
가상의 극장의 요구 사항은 이렇습니다. 13세 미만이거나 65세 이상이면 표 값은 $8이고, 나머지 사람은 $12입니다. 테스터가 어떤 입력을 시도하고 각 입력에서 무엇을 기대해야 하는지는 요구 사항이 알려 줍니다.
PROCEDURE price(age) { IF(age < 13 OR age ≥ 64) { RETURN(8) } RETURN(12) } 좋은 테스트 입력은 서로 다른 기대 결과를 보여 주고, 실수가 몰리는 입력 데이터의 극단값(최솟값과 최댓값) 또는 그 바로 바깥에 놓입니다. 여기서는 한쪽 경계의 양옆인 12와 13, 다른 쪽 경계의 양옆인 64과 65, 그리고 가장 작은 나이인 0입니다.
| age (입력) | 예상 | 실제 | |
|---|---|---|---|
| 0 | $8 | $8 | pass |
| 12 | $8 | $8 | pass |
| 13 | $12 | $12 | pass |
| 40 | $12 | $12 | pass |
| 64 | $12 | $8 | 실패 |
| 65 | $8 | $8 | pass |
64에서의 테스트가 실패합니다. 코드에는 age ≥ 64라고 되어 있는데 요구 사항은 age ≥ 65를 뜻하며, 이는 논리 오류입니다. 40세처럼 흔한 나이로 테스트했다면 이 오류를 결코 찾지 못했을 것입니다.
추적, 시각화, 디버깅, 출력
오류를 찾아 고치는 효과적인 방법은 테스트 케이스, 손으로 추적하기, 시각화, 디버거, 출력문 추가하기입니다.
findMax는 리스트에서 가장 큰 수를 반환해야 합니다. [-3, -7, -2]로 테스트하면 −2이 아니라 0을 반환합니다. 이유를 보려고 프로그래머가 반복문 안에 DISPLAY(max)(파란색)를 추가합니다. 출력문을 하나 더 넣은 것입니다.
PROCEDURE findMax(numList) { max ← 0 FOR EACH num IN numList { IF(num > max) { max ← num } DISPLAY(max) } RETURN(max) } 요소마다 한 행씩 손으로 추적해 봅니다.
| num | num > max? | 이후의 max | DISPLAY가 보여 주는 것 |
|---|---|---|---|
| −3 | false | 0 | 0 |
| −7 | false | 0 | 0 |
| −2 | false | 0 | 0 |
max는 변하지 않습니다. 0보다 큰 요소가 없기 때문입니다. 디버거도 프로그램을 멈추고 변수를 보여 주어 같은 것을 알려 줍니다(그림의 칸들은 프로그램 상태의 시각화입니다). 오류는 3번째 줄에 있습니다. max가 0에서 시작하는데, 이 값은 모두 음수인 리스트의 어떤 요소보다도 큽니다.
고치는 방법은 max ← numList[1]입니다. 리스트의 한 요소에서 시작하는 것입니다. 다시 실행하면 추가한 출력이 −3, −3, −2을 보여 주고, 반환값은 −2입니다. 그런 다음 추가했던 DISPLAY를 지웁니다.
나만의 프로그램과 그에 관한 질문
Create 수행 과제는 이 장에서 배운 것을 실제로 적용하는 과제입니다. 직접 고른 프로그램을 1.1~1.4의 과정, 문서화, 테스트를 거쳐 개발합니다.
AP Digital Portfolio에 세 가지를 제출합니다. 프로그램 코드, 실행 모습을 담은 동영상, 개인 프로젝트 참고 자료(PPR)입니다. 이 과제를 위해 수업 시간이 최소 9시간 주어집니다. 프로그램에는 리스트와 프로시저 같은 특정 요소가 들어 있어야 합니다.
시험 날에는 서술형 답안을 씁니다. 60분 동안 자신의 PPR에 있는 코드에 관한 2개 문항에 답하며, 답하는 동안 PPR을 볼 수 있습니다.
과제와 서술형 답안을 합치면 AP 점수의 30%이고, 객관식 시험(120분 동안 70문항)이 나머지 70%입니다.
그래서 이 장의 질문은 자신의 프로그램에 관한 질문으로 다시 나옵니다. 프로그램의 목적과 기능은 무엇인지, 입력과 출력은 무엇인지, 어떤 입력으로 무엇을 테스트했는지, 어떤 오류를 찾아 고쳤는지입니다.