본문으로 건너뛰기

단원 연습 문제

파이썬 목차수와 글자문제 12개

2단원 '수와 글자'의 네 레슨에서 9문제를 내고, 1단원 '첫 프로그램'에서 3문제를 섞었습니다. 1단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 출력을 쓰는 문제는 빈칸과 줄바꿈까지 종이에 끝까지 쓴 뒤 정답을 펼치세요. 막히면 정답 앞의 힌트를 먼저 펼칩니다. 점수는 매기지 않습니다.

한 번에 다 풀 필요는 없습니다. 문제 1~10은 폰으로도 풀 수 있고(약 30분), 끝의 만들어 보기 둘은 컴퓨터에서 직접 돌려 봅니다. 이 단원을 건너뛰어도 되는지 보려면 문제 1 · 3 · 6 · 9 넷을 먼저 풀어 보세요(약 10분). 건너뛸지 볼 때는 힌트를 펴지 않고 풉니다. 힌트를 펴고 맞힌 문제나 짐작으로 고른 문제는 틀린 것으로 치고 그 레슨을 봅니다. 모두 맞으면 이 단원 레슨은 건너뛰고, 틀린 문제가 있으면 그 정답 끝의 레슨만 봅니다. 끝의 만들어 보기 둘은 골라서 풉니다.

끝의 두 문제는 프로그램을 직접 만들어 봅니다. 컴퓨터가 있으면 저장해 돌려 맞춰 보고, 폰으로만 본다면 문제에 적힌 값으로 내 코드를 한 줄씩 따라가 나와야 할 화면과 맞춰 봅니다. 실행 결과는 모두 파이썬 3.15로 돌린 것입니다.

문제 1

축구 선수의 등번호와 넣은 골 수를 찍습니다. 무엇이 찍힐까요? 세 줄을 글자 그대로 쓰세요.

back = '7'
goals = 7
print(back * 3)
print(goals * 3)
print(back + '번', goals + 1)
힌트

두 이름이 붙은 값의 종류부터 가르세요.

정답
실행 결과
777
21
7번 8
  • 1·2번 줄: back은 글자 '7'에, goals는 정수 7에 붙습니다.
  • 3번 줄: 글자에 * 3을 하면 세 번 이어 붙여 777입니다.
  • 4번 줄: 수에 * 3을 하면 곱해서 21입니다.
  • 5번 줄: 글자 '7'과 '번'을 이어 '7번'을 만들고, 7 + 1로 8을 만듭니다. 쉼표 자리에는 빈칸 하나가 들어갑니다.

흔한 오답은 첫 줄의 21입니다. 따옴표 안의 7도 수라고 본 것입니다(문자열과 수를 가리지 않는 생각). 셋째 줄을 7 번 8로 쓰면 +가 빈칸을 넣는다고 본 것입니다. +는 쓴 글자만 잇습니다.

다시 볼 레슨: 수와 글자 · 문자열 잇기와 되풀이

문제 2

음료 크기와 잔 수를 찍으려 합니다. 이 코드를 실행하면 어떻게 될까요? 알맞은 것을 고르세요.

size = 'L'
cups = 2
print(size, cups)
print(size + cups)
print('주문 끝')
  • ① 아무것도 찍지 않고 TypeError로 멈춘다
  • ② L 2를 찍은 뒤 4번 줄에서 TypeError로 멈춘다
  • ③ L 2·L2·주문 끝을 차례로 찍는다
  • ④ L 2를 찍고 4번 줄은 건너뛰어 주문 끝을 찍는다
힌트

4번 줄의 + 양쪽에 오는 값의 종류를 보세요.

정답

② — 실행 결과는 이렇습니다.

실행 결과
L 2Traceback (most recent call last):  File "main.py", line 4, in <module>    print(size + cups)          ~~~~~^~~~~~TypeError: can only concatenate str (not "int") to str

3번 줄은 쉼표로 넘긴 두 값 사이에 빈칸을 넣어 L 2를 찍습니다. 4번 줄은 글자 'L'에 수 2를 +로 이으려다 TypeError로 멈춥니다. 실행 중 오류라 앞에서 찍은 L 2는 남고, 5번 줄은 실행되지 않습니다.

  • ① 실행 중 오류를 문법 오류처럼 봤습니다. 값의 종류가 맞지 않는다는 것은 그 줄을 실행할 때 알게 되므로, 3번 줄까지는 실행됩니다.
  • ③ +가 종류를 알아서 맞춰 준다고 봤습니다(문자열과 수를 가리지 않는 생각). 파이썬은 글자와 수 사이에서 종류를 저절로 맞춰 주지 않습니다.
  • ④ 오류가 난 줄만 건너뛴다고 봤습니다. 실행은 오류가 난 그 줄에서 멈춥니다(규칙 1).

다시 볼 레슨: 수와 글자 · 오류 메시지 읽기

문제 3

친구 셋이 카페에서 나온 27000원을 똑같이 나눠 냅니다. 무엇이 찍힐까요? 세 줄을 글자 그대로 쓰세요.

bill = 27000
people = 3
each = bill / people
print(each)
print(each * people)
print(bill // people)
힌트

3번 줄과 6번 줄의 나누기 기호를 견주어 보세요.

정답
실행 결과
9000.0
27000.0
9000
  • 3·4번 줄: /는 나누어떨어져도 실수를 내므로 each는 9000.0에 붙고, 4번 줄이 그 값을 찍습니다.
  • 5번 줄: 실수 9000.0에 3을 곱해도 실수라 27000.0입니다.
  • 6번 줄: //는 몫을 내고, 정수끼리라 정수 9000입니다.

흔한 오답은 첫 줄의 9000입니다. /가 몫을 내거나, 나누어떨어지면 정수가 나온다고 본 것입니다(/가 몫이라는 생각). 둘째 줄을 27000으로 쓰면 곱하면 정수로 돌아온다고 본 것입니다. 사칙 계산에서는 한 번 실수가 된 값이 다른 수와 계산해도 실수로 남습니다.

다시 볼 레슨: 사칙 계산과 몫·나머지

문제 4

나누어 내려는데 한 명이 더 와서 넷이 되었습니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.

bill = 27000
people = 3
each = bill // people
people = 4
print(each)
print(bill // people)
힌트

each가 몇 번 줄에서 어떤 값에 붙는지 줄마다 따라가 보세요.

정답
실행 결과
9000
6750
  • 3번 줄: 그때 people은 3이라 27000 // 3을 계산한 값 9000에 each가 붙습니다.
  • 4번 줄: people만 새 값 4에 다시 붙습니다. each는 다시 계산되지 않습니다.
  • 5번 줄: each가 붙은 9000을 찍습니다.
  • 6번 줄: 이제 people이 4라 27000 // 4는 6750입니다.

흔한 오답은 첫 줄의 6750입니다. 3번 줄이 bill // people이라는 식을 each에 저장해 두었다가 찍을 때 다시 계산한다고 본 것입니다(식이 저장된다는 생각). 오른쪽은 대입하는 그때 한 번 계산하고, 이름은 그 값에 붙습니다(규칙 2).

다시 볼 레슨: 변수: 값에 이름 붙이기

문제 5

사과 50개를 12개들이 상자에 담습니다. 줄 ㉠~㉥ 가운데 다섯 줄을 위에서 아래로 놓아 아래 결과가 나오게 하세요. 한 줄은 쓰지 않습니다. 놓은 차례를 ㉠~㉥로 쓰세요.

상자 4
남는 사과 2
  • ㉠ print('상자', boxes)
  • ㉡ boxes = apples / 12
  • ㉢ apples = 50
  • ㉣ left = apples % 12
  • ㉤ boxes = apples // 12
  • ㉥ print('남는 사과', left)
힌트

값 두기 → 계산하기 → 찍기 차례입니다. 상자 수는 몫, 남는 사과는 나머지입니다.

놓은 뒤 물음

쓰지 않는 한 줄을 빼는 까닭은 무엇일까요?

  • ① 50이 12로 나누어떨어지지 않아서다. 48개였다면 그 줄도 상자 4를 찍는다
  • ② 까닭은 없다. 두 줄 다 상자 수 4를 내므로 어느 쪽을 써도 결과가 같다
  • ③ 그 줄의 /는 소수점 아래까지 나눠, 상자 수가 실수로 찍히기 때문
정답

㉢ ㉤ ㉣ ㉠ ㉥ 차례이고, 까닭은 ③입니다.

apples = 50
boxes = apples // 12
left = apples % 12
print('상자', boxes)
print('남는 사과', left)
실행 결과
상자 4
남는 사과 2
  • 바꿔도 되는 줄: ㉤과 ㉣은 서로 바꿔도 되고, ㉠을 ㉤ 바로 뒤에 두어도 됩니다(㉢ ㉤ ㉠ ㉣ ㉥). 이름을 읽는 줄이 실행될 때 그 이름이 이미 값에 붙어 있고(규칙 1·2), 찍는 줄이 결과의 차례대로면 맞습니다.

쓰지 않는 줄은 /로 나누는 ㉡입니다. ㉤ 자리에 ㉡을 쓰면 첫 줄이 상자 4.166666666666667로 찍힙니다.

  • ① 나누어떨어지면 정수가 나온다고 봤습니다. 사과가 48개여도 ㉡을 쓰면 상자 4.0이 찍힙니다.
  • ② /가 몫을 낸다고 봤습니다(/가 몫이라는 생각). 몫은 //이고, /는 소수점 아래까지 나눠 늘 실수를 냅니다.

다시 볼 레슨: 사칙 계산과 몫·나머지

문제 6

메시지 끝에 웃음 표시를 붙입니다. 무엇이 찍힐까요? 세 줄을 글자 그대로 쓰세요.

word = '하'
laugh = word * 3 + '!'
print(laugh)
print(len(laugh))
print(len(word + ' ' + word))
힌트

4번 줄의 len()이 무엇을 세는지 보세요.

정답
실행 결과
하하하!
4
3
  • 2·3번 줄: 수의 계산처럼 *를 +보다 먼저 해 '하하하'를 만들고, 뒤에 '!'를 이은 '하하하!'에 laugh가 붙습니다. 3번 줄이 그 값을 찍습니다.
  • 4번 줄: 한글 셋과 느낌표 하나라 4글자입니다.
  • 5번 줄: '하'와 빈칸과 '하'를 이은 '하 하'는 3글자입니다.

흔한 오답은 둘째 줄의 7입니다. 한글 한 자를 두 글자로 센 것입니다. 셋째 줄을 2로 쓰면 빈칸을 글자로 세지 않은 것입니다. 첫 줄을 하 하 하!로 쓰면 되풀이가 빈칸을 넣는다고 본 것입니다.

다시 볼 레슨: 문자열 잇기와 되풀이

문제 7

카페 화면에 띄울 인사말을 고칩니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.

msg = '안녕하세요'
msg = '어서 오세요'
msg = msg + '!'
print(msg)
print(len(msg))
힌트

줄마다 이름 msg가 어느 값에 붙는지 다시 그려 보세요.

정답
실행 결과
어서 오세요!
7
  • 1번 줄: msg가 '안녕하세요'에 붙습니다.
  • 2번 줄: msg를 '어서 오세요'에 다시 붙입니다. '안녕하세요'와의 연결은 끊깁니다.
  • 3·4번 줄: 지금 붙은 '어서 오세요' 뒤에 '!'를 이은 새 값을 만들고, msg를 그 값에 다시 붙입니다. 4번 줄이 그 값을 찍습니다.
  • 5번 줄: 한글 다섯, 빈칸 하나, 느낌표 하나라 7글자입니다.

흔한 오답은 첫 줄의 안녕하세요어서 오세요!입니다. msg를 값이 쌓이는 상자로 봐서 옛 값이 남는다고 본 것입니다(상자 생각). 다시 붙이면 옛 연결은 끊기고, 이름은 마지막에 붙은 값 하나만 가리킵니다(규칙 3).

다시 볼 레슨: 이름표 다시 붙이기

문제 8

하고 싶은 일마다 쓸 이름(함수 이름이나 기호)을 하나씩 쓰세요. 넷 다 쓴 뒤 정답을 펼치세요.

  • (가) 값이 정수인지 문자열인지 알아본다
  • (나) 문자열의 글자 수를 센다
  • (다) 수 4500으로 글자 '4500'을 만든다
  • (라) 나눗셈의 나머지를 구한다
힌트

넷 가운데 셋은 이름 뒤에 괄호를 붙여 부르는 함수이고, 하나는 계산 기호입니다.

정답

받는 답: (가) type · (나) len · (다) str · (라) %

  • 같은 답으로 치는 꼴: 괄호까지 붙여 쓴 type()·len()·str(), 값까지 넣어 쓴 str(4500).
  • 틀리는 꼴 print — (가)에: 값을 화면에 찍을 뿐 종류는 알려 주지 않습니다. 글자 '3'과 수 3은 똑같이 3으로 찍힙니다.
  • 틀리는 꼴 int — (다)에: 거꾸로, 글자로 수를 만드는 이름입니다.
  • 틀리는 꼴 // — (라)에: 몫을 구하는 기호입니다. /는 소수점 아래까지 나눕니다.

다시 볼 레슨: 수와 글자 · 문자열 잇기와 되풀이 · 사칙 계산과 몫·나머지

문제 9

오늘 달린 거리를 물어 두 배를 찍습니다. 2.5를 넣었습니다. 무엇이 찍힐까요? 넣은 값이 보이는 줄까지 세 줄을 글자 그대로 쓰세요.

distance = input('달린 거리: ')
print(distance * 2)
print(float(distance) * 2)넣는 값2.5
힌트

input()이 돌려주는 값의 종류부터 정하세요.

정답
실행 결과
달린 거리: 2.5
2.52.5
5.0
  • 1번 줄: 프롬프트 뒤에 친 2.5가 보이고, 친 글자로 문자열 '2.5'가 만들어져 이름 distance가 그 값에 붙습니다.
  • 2번 줄: 글자에 * 2를 하면 두 번 이어 붙여 2.52.5입니다.
  • 3번 줄: float()가 글자 '2.5'로 실수 2.5를 만들고, 2를 곱해 5.0입니다.

흔한 오답은 둘째 줄의 5.0입니다. 수를 넣으면 수가 들어온다고 본 것입니다(문자열과 수를 가리지 않는 생각). 셋째 줄을 5로 쓰면 실수를 곱한 결과도 실수라는 것을 놓친 것입니다.

다시 볼 레슨: 입력은 늘 글자

문제 10

모은 스탬프 수를 묻고, 이번 주문으로 하나 더한 수를 찍으려 합니다. 8을 넣으면 9가 찍혀야 하는데 아래처럼 멈췄습니다. 몇 번 줄의 무엇을 고쳐야 할까요? 고친 줄을 쓰세요.

text = input('스탬프: ')
stamps = text
print(stamps + 1)넣는 값8
실행 결과
스탬프: 8Traceback (most recent call last):  File "main.py", line 3, in <module>    print(stamps + 1)          ~~~~~~~^~~TypeError: can only concatenate str (not "int") to str
힌트

오류가 난 줄에 쓰인 이름 stamps가 몇 번 줄에서 어떤 값에 붙었는지 봅니다.

정답

2번 줄을 stamps = int(text)로 고칩니다. 8을 넣으면 이렇게 찍힙니다.

text = input('스탬프: ')
stamps = int(text)
print(stamps + 1)넣는 값8
실행 결과
스탬프: 8
9

오류는 3번 줄에서 났지만 까닭은 2번 줄에 있습니다. 1번 줄에서 받은 글자 '8'로 2번 줄이 수를 만들지 않아, stamps가 그 글자에 그대로 붙었습니다. 그래서 3번 줄의 +가 글자와 수를 잇게 되었습니다. 입력 받아 계산하는 네 걸음 가운데 '2. 수로 바꾸기'가 빠진 것입니다.

  • 다르게 고쳐도 되는 곳: 1번 줄에서 int(input(…))처럼 받는 자리에서 바로 수를 만들어도 9가 찍힙니다. 3번 줄을 print(int(stamps) + 1)⁠로 고쳐도 9가 찍히는 맞는 답입니다. 다만 stamps는 여전히 글자에 붙어 있어, 다른 줄에서 계산할 때마다 또 수를 만들어야 합니다.
  • float(text)로 고치면 9가 아니라 9.0이 찍혀 맞지 않습니다.

흔한 오답은 오류를 없애려고 3번 줄의 1을 글자로 바꾸는 것입니다. 오류는 사라지지만 글자끼리 이어 81이 찍힙니다(문자열과 수를 가리지 않는 생각).

text = input('스탬프: ')
stamps = text
print(stamps + '1')넣는 값8
실행 결과
스탬프: 8
81

다시 볼 레슨: 입력은 늘 글자 · 오류 메시지 읽기

문제 11 (만들어 보기)

계산대에서 쓸 거스름돈 계산기를 만들어 봅니다. 값과 낸 돈을 물어 거스름돈을 찍고, 그 거스름돈을 천 원짜리 몇 장과 백 원짜리 몇 개로 나눠 찍습니다. 물을 때 쓰는 글은 '값: '과 '낸 돈: '입니다. 값에 7300, 낸 돈에 10000을 넣으면 이렇게 나와야 합니다.

값: 7300
낸 돈: 10000
거스름돈 2700
천 원 2
백 원 7

값에 4500, 낸 돈에 5000을 넣으면 이렇게 나와야 합니다.

값: 4500
낸 돈: 5000
거스름돈 500
천 원 0
백 원 5

아래 뼈대의 주석 넷 아래를 채우세요. 다 쓰면 둘째 값으로도 따라가 봅니다.

# 1. 입력 받기
# 2. 수로 바꾸기
# 3. 계산하기
# 4. 찍기넣는 값730010000

처음 펼 때 약 6MB를 받습니다.

힌트

거스름돈은 낸 돈에서 값을 뺀 것입니다. 천 원짜리는 거스름돈을 1000으로 나눈 몫이고, 백 원짜리는 그 나머지를 100으로 나눈 몫입니다.

정답

모범 답입니다. 7300과 10000을 넣은 결과입니다.

# 1. 입력 받기
cost = input('값: ')
paid = input('낸 돈: ')
# 2. 수로 바꾸기
cost = int(cost)
paid = int(paid)
# 3. 계산하기
change = paid - cost
bills = change // 1000
rest = change % 1000
coins = rest // 100
# 4. 찍기
print('거스름돈', change)
print('천 원', bills)
print('백 원', coins)넣는 값730010000
실행 결과
값: 7300
낸 돈: 10000
거스름돈 2700
천 원 2
백 원 7

4500과 5000을 넣으면 change는 500, bills는 500 // 1000으로 0, rest는 500, coins는 5입니다.

  • 다르게 써도 되는 곳: 이름은 달라도 됩니다. '2. 수로 바꾸기'에서 만든 수에 새 이름을 붙여도 되고(price = int(cost)), '1. 입력 받기'에서 int(input(…))로 바로 수를 만들면 '2. 수로 바꾸기' 아래는 비어도 됩니다. 백 원짜리를 rest 없이 한 줄로 구해도 됩니다.
  • 찍은 화면이 위와 같고 둘째 시험 값(4500·5000)도 맞으면 맞습니다.
  • 흔한 오답은 수를 만드는 일을 어디서도 하지 않는 것입니다. 그러면 paid - cost가 글자끼리 빼기가 되어 '3. 계산하기'의 첫 줄에서 TypeError로 멈춥니다. 글자끼리는 빼기를 할 수 없습니다(문자열과 수를 가리지 않는 생각).

다시 볼 레슨: 입력은 늘 글자 · 사칙 계산과 몫·나머지

문제 12 (만들어 보기)

이번에는 빈 데서 씁니다. 커피 두 잔(한 잔 4000원)과 케이크 한 조각(5000원)을 산 카페 영수증 세 줄을 찍는 프로그램을 쓰세요. 값마다 이름을 붙이고, 합계는 파이썬이 계산하게 합니다. 이렇게 나와야 합니다.

커피: 8000
케이크: 5000
합계: 13000

내 코드에서 잔 수가 적힌 한 곳만 3으로 바꾸면 이렇게 나와야 합니다.

커피: 12000
케이크: 5000
합계: 17000

다 쓰면 둘째 값으로도 따라가 봅니다.

힌트

하위 목표 셋의 주석(1. 값 두기 · 2. 계산하기 · 3. 찍기)을 먼저 쓰고, 그 아래를 채웁니다.

정답

모범 답입니다.

# 1. 값 두기
coffee = 4000
cups = 2
cake = 5000
# 2. 계산하기
drinks = coffee * cups
total = drinks + cake
# 3. 찍기
print('커피:', drinks)
print('케이크:', cake)
print('합계:', total)
실행 결과
커피: 8000
케이크: 5000
합계: 13000

cups를 3으로 바꾸면 drinks가 12000, total이 17000이 됩니다.

  • 다르게 써도 되는 곳: '1. 값 두기'의 세 줄은 차례를 바꿔도 됩니다. drinks 없이 coffee * cups를 찍는 줄과 합계 줄에 바로 써도 같습니다. print('커피', drinks, sep=': ')⁠와 print('커피: ' + str(drinks))⁠도 같은 줄을 찍습니다.
  • 찍은 화면이 위와 같고 잔 수를 3으로 바꾼 결과도 맞으면 맞습니다. 잔 수를 3으로 바꿔도 결과가 그대로라면, 8000처럼 손으로 계산한 값을 적은 것입니다. 계산은 파이썬에게 맡깁니다.
  • 흔한 오답 하나는 콜론 뒤 빈칸입니다. print('커피: ', drinks)⁠는 쉼표 자리에 빈칸이 하나 더 들어가 빈칸 둘이 되고, '커피:' + str(drinks)는 +가 빈칸을 넣지 않아 붙어 버립니다.
drinks = 8000
print('커피: ', drinks)
print('커피:' + str(drinks))
실행 결과
커피:  8000
커피:8000
  • 다른 흔한 오답은 합계 줄을 '1. 값 두기'보다 위에 쓰는 것입니다. 그러면 아직 값에 붙지 않은 이름을 읽어 NameError로 멈춥니다. 이름은 값에 붙인 뒤에야 읽을 수 있습니다(규칙 1·2).

다시 볼 레슨: 변수: 값에 이름 붙이기 · print로 출력하기 · 사칙 계산과 몫·나머지

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로