3단원 '문자열 다루기'의 세 레슨에서 9문제를 내고, 1·2단원에서 3문제를 섞었습니다. 앞 단원 문제가 어느 레슨인지는 정답을 펼치면 보입니다. 출력을 쓰는 문제는 빈칸과 줄바꿈까지 종이에 끝까지 쓴 뒤 정답을 펼치세요. 막히면 정답 앞의 힌트를 먼저 펼칩니다. 점수는 매기지 않습니다.
한 번에 다 풀 필요는 없습니다. 문제 1~10은 폰으로도 풀 수 있고(약 30분), 끝의 만들어 보기 둘은 컴퓨터에서 직접 돌려 봅니다. 이 단원을 건너뛰어도 되는지 보려면 문제 1 · 5 · 8 셋을 먼저 풀어 보세요(약 10분). 건너뛸지 볼 때는 힌트를 펴지 않고 풉니다. 힌트를 펴고 맞힌 문제나 짐작으로 고른 문제는 틀린 것으로 치고 그 레슨을 봅니다. 모두 맞으면 이 단원 레슨은 건너뛰고, 틀린 문제가 있으면 그 정답 끝의 레슨만 봅니다. 끝의 만들어 보기 둘은 골라서 풉니다.
끝의 두 문제는 프로그램을 직접 만들어 봅니다. 컴퓨터가 있으면 저장해 돌려 맞춰 보고, 폰으로만 본다면 문제에 적힌 값으로 내 코드를 한 줄씩 따라가 나와야 할 화면과 맞춰 봅니다. 실행 결과는 모두 파이썬 3.15로 돌린 것입니다.
문제 1
하프 마라톤 거리를 찍습니다. 무엇이 찍힐까요? 세 줄을 글자 그대로 쓰세요.
distance = 21.0975
print(f'{distance:.1f}km')
print('{distance}km')
print(int(distance))
힌트
줄마다 따옴표 앞에 무엇이 있는지, 중괄호 안 콜론 뒤에 무엇이 있는지 보세요.
정답
21.1km
{distance}km
21- 2번 줄:
.1f는 소수 첫째 자리까지 반올림한 모양으로 찍어 21.1입니다. distance가 붙은 값은 그대로 21.0975입니다. - 3번 줄: 따옴표 앞에 f가 없어 중괄호까지 쓴 글자 그대로 찍힙니다.
- 4번 줄:
int()는 소수점 아래를 버린 정수 21을 만듭니다.
흔한 오답은 첫 줄의 21.0km입니다. .1f가 소수 자리를 버린다고 본 것입니다. 둘째 줄을 21.0975km로 쓰면 f 없이도 중괄호 자리에 값이 들어간다고 본 것입니다. 셋째 줄을 21.1로 쓰면 int()도 반올림한다고 본 것입니다.
다시 볼 레슨: f-문자열로 출력 꾸미기 · 입력은 늘 글자
문제 2
카페 포인트를 물어 찍으려 합니다. 12000을 넣었습니다. 어떻게 될까요? 알맞은 것을 고르세요.
point = input('포인트: ')
print(f'{point}점')
print(f'{point:,}')넣는 값12000
- ①
포인트: 12000·12000점을 찍고 3번 줄에서ValueError로 멈춘다 - ② 실행하자마자 포인트를 묻기도 전에
ValueError를 알리고 아무것도 찍지 않는다 - ③
포인트: 12000·12000점·12,000을 차례로 찍고 끝난다
힌트
1번 줄에서 point가 어떤 종류의 값에 붙는지 정한 뒤, 3번 줄의 콜론 뒤를 보세요.
정답
① — 실행 결과는 이렇습니다.
포인트: 1200012000점Traceback (most recent call last): File "main.py", line 3, in <module> print(f'{point:,}') ^^^^^^^^^ValueError: Cannot specify ',' with 's'.input()은 친 12000으로 문자열 '12000'을 만들고, point가 그 값에 붙습니다. 2번 줄은 그 글자를 그대로 넣어 12000점을 찍습니다. 3번 줄의 ,는 수에만 쓰는 모양이라, 글자에 쓰면 그 줄을 실행할 때 ValueError로 멈춥니다. 맨 아래 줄의 's'는 문자열 모양이라는 뜻입니다.
- ② 실행 중 오류를 문법 오류처럼 봤습니다. 모양이 값에 맞지 않는다는 것은 그 줄을 실행할 때 알게 되므로, 2번 줄까지는 실행됩니다.
- ③ 넣은 12000이 수로 들어온다고 봤습니다(문자열과 수를 가리지 않는 생각).
int()로 수를 만든 뒤에:,를 씁니다.
다시 볼 레슨: f-문자열로 출력 꾸미기 · 입력은 늘 글자 · 오류 메시지 읽기
문제 3
카페 모임 값 25000원을 넷이 나눕니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
total = 25000
people = 4
print(f'{total / people}원')
print(f'{total // people:,}원')
힌트
3번 줄과 4번 줄의 나누기 기호가 만드는 값의 종류를 먼저 정하세요.
정답
6250.0원
6,250원- 3번 줄:
/는 나누어떨어져도 실수 6250.0을 만들어, 소수점 아래.0까지6250.0원으로 찍습니다. - 4번 줄:
//는 몫인 정수 6250을 만들고,:,가 세 자리마다 쉼표를 넣어6,250원으로 찍습니다.
흔한 오답은 첫 줄의 6250원입니다. /가 몫을 낸다고 본 것입니다(/가 몫이라는 생각). 몫은 //이고, /는 나누어떨어져도 실수를 냅니다.
다시 볼 레슨: 사칙 계산과 몫·나머지 · f-문자열로 출력 꾸미기
문제 4
메뉴판 문구를 만든 뒤 커피 값이 올랐습니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
price = 4000
label = f'커피 {price}원'
price = 4500
print(label)
print(f'커피 {price}원')
힌트
2번 줄이 실행되는 그때 price가 어느 값에 붙어 있는지 보세요.
정답
커피 4000원
커피 4500원- 2번 줄: 그때 price가 4000에 붙어 있어 f-문자열이 문자열 '커피 4000원' 하나가 되고, label이 그 값에 붙습니다.
- 3번 줄: price만 새 값 4500에 다시 붙습니다. label은 다시 만들어지지 않습니다.
- 5번 줄: 이 줄을 실행하는 그때 price가 4500이라, '커피 4500원'을 새로 만들어 찍습니다.
흔한 오답은 첫 줄의 커피 4500원입니다. label이 f-문자열을 저장해 두었다가 찍을 때 다시 만든다고 본 것입니다(식이 저장된다는 생각). f-문자열도 오른쪽을 그때 한 번 계산해 값 하나를 만듭니다(규칙 2).
다시 볼 레슨: 변수: 값에 이름 붙이기 · f-문자열로 출력 꾸미기
문제 5
카페 주문표의 글자를 잘라 찍습니다. 무엇이 찍힐까요? 마지막 줄까지 글자 그대로 쓰세요. 오류가 난다고 보면 찍히는 줄 다음에 오류 이름을 쓰세요.
ticket = 'HOT-AMR-12'
print(ticket[:3])
print(ticket[4:7])
print(ticket[-2:])
print(ticket[8:20])
힌트
열 글자에 0부터 번호를 적어 보세요.
정답
모두 4줄입니다.
HOT
AMR
12
12- 2번 줄:
[:3]은 0~2번 'HOT'입니다. - 3번 줄:
[4:7]은 4·5·6번 'AMR'입니다. 7번 자리의 '-'는 들어가지 않습니다. - 4번 줄:
[-2:]는 뒤에서 두 글자 '12'입니다. - 5번 줄: 번호는 0~9뿐이지만, 자르기는 있는 글자까지만 꺼내 8·9번 '12'를 찍습니다.
흔한 오답은 둘째 줄의 AMR-입니다. 끝 번호의 글자도 든다고 본 것입니다(끝도 든다는 생각). 넷째 줄에서 IndexError로 멈춘다고 보면, 자르기도 없는 자리면 오류라고 본 것입니다. 오류는 ticket[20]처럼 글자 하나를 꺼낼 때만 납니다.
다시 볼 레슨: 인덱스와 자르기
문제 6
택배 송장 번호의 끝 네 자리만 찍으려 합니다. 번호의 길이가 달라도 끝 네 자리를 찍도록 빈칸에 들어갈 자르기 번호를 쓰세요.
num = '6012-3345-7788'
print(num[____])
num이 '6012-3345-7788'이면 7788, '1234-5678-9012-3456'이면 3456이 찍혀야 합니다.
힌트
두 번호의 길이가 다릅니다. 앞에서 센 번호와 뒤에서 센 번호 가운데 어느 쪽이 둘 다에 맞을지 보세요.
정답
-4:입니다.
num = '6012-3345-7788'
print(num[-4:])7788[-4:]는 뒤에서 넷째 글자부터 끝까지라, 번호의 길이가 달라도 끝 네 자리를 꺼냅니다. 긴 번호로 바꿔도 맞고, 앞에서 센 10:은 갈립니다.
num = '1234-5678-9012-3456'
print(num[-4:])
print(num[10:])3456
9012-3456- 다르게 써도 되는 곳:
len(num) - 4:도 두 번호 모두 맞습니다. 끝 번호까지 쓰려면-4:len(num)처럼 길이를 씁니다.-4:100처럼 끝 번호를 번호 길이보다 큰 수로 써도 자르기는 있는 글자까지만 꺼내 맞지만, 끝까지라면 비워 두는 쪽이 길이를 따지지 않아도 됩니다. - 흔한 오답은
10:입니다. 첫 번호에서는7788이 맞지만, '1234-5678-9012-3456'에서는 10번부터라9012-3456이 찍힙니다. 앞에서 센 번호는 길이가 바뀌면 가리키는 글자가 바뀝니다. 끝 번호를-4:14처럼 첫 번호의 길이로 쓰면 첫 번호에서는 맞지만, 더 긴 둘째 번호에서는 빈 줄이 찍힙니다.
다시 볼 레슨: 인덱스와 자르기
문제 7
태어난 해를 물어 '○○년생'과 올해(2026년) 나이를 찍으려 합니다. 2005를 넣었습니다. 무엇이 찍힐까요? 넣은 값이 보이는 줄부터 마지막 줄까지 쓰고, 오류가 나면 찍힌 줄 다음에 오류 이름만 쓰세요.
year = input('태어난 해: ')
short = year[2:]
print(short + '년생')
print(2026 - year)넣는 값2005
힌트
1번 줄에서 year가 어떤 종류의 값에 붙는지 정하세요.
정답
넣은 값이 보이는 줄과 05년생을 찍은 뒤 4번 줄에서 TypeError로 멈춥니다.
태어난 해: 200505년생Traceback (most recent call last): File "main.py", line 4, in <module> print(2026 - year) ~~~~~^~~~~~TypeError: unsupported operand type(s) for -: 'int' and 'str'- 1번 줄: 친 2005로 문자열 '2005'가 만들어지고, year가 그 값에 붙습니다.
- 2·3번 줄:
[2:]는 2번 자리부터 끝까지라 '05'이고, 글자끼리 이어05년생을 찍습니다. 글자라서 앞의 0이 남습니다. - 4번 줄: 수 2026에서 글자 '2005'를 빼려다
TypeError로 멈춥니다. 맨 아래 줄은 '-는 int와 str 사이에 쓸 수 없다'는 뜻입니다.
흔한 오답은 마지막 줄에 21을 쓰는 것입니다. 넣은 2005가 수로 들어온다고 본 것입니다(문자열과 수를 가리지 않는 생각). 나이를 구하려면 2026 - int(year)처럼 수를 만든 뒤 뺍니다. 둘째 줄을 5년생으로 쓰면 자른 값도 수라고 본 것입니다.
문제 8
카페 와이파이 비밀번호를 만들려고 낱말의 글자를 바꿔 봅니다. 무엇이 찍힐까요? 두 줄을 글자 그대로 쓰세요.
word = 'goodbook'
word.replace('o', '0')
safe = word.replace('oo', '0')
print(word)
print(safe)
힌트
2번 줄 뒤에 word가 어느 값에 붙어 있는지, 3번 줄이 'oo'를 몇 군데에서 찾는지 보세요.
정답
goodbook
g0db0k- 2번 줄: 'g00db00k'를 새로 만들지만 아무 이름도 붙지 않아 버려집니다. word는 그대로 'goodbook'에 붙어 있습니다.
- 3번 줄: 'oo'를 찾는 곳마다 '0' 하나로 바꾼 'g0db0k'를 만들고, safe가 그 값에 붙습니다.
흔한 오답은 첫 줄의 g00db00k입니다. 메서드를 부르기만 하면 그 문자열이 바뀐다고 본 것입니다. 새 값에 이름을 붙여야 남습니다(규칙 3). 둘째 줄을 g0dbook으로 쓰면 replace()가 처음 찾은 하나만 바꾼다고 본 것입니다.
다시 볼 레슨: 문자열 메서드
문제 9
하고 싶은 일마다 쓸 이름이나 기호를 하나씩 쓰세요. 넷 다 쓴 뒤 정답을 펼치세요.
- (가) 문자열의 맨 앞과 맨 뒤 빈칸을 뗀 새 문자열을 만든다
- (나) 문자열을 모두 대문자로 적은 새 문자열을 만든다
- (다) 대괄호에 넣어 문자열의 마지막 글자를 꺼내는 번호
- (라) f-문자열 중괄호 안에서 천 단위 쉼표를 넣는 모양
힌트
둘은 점을 찍고 부르는 메서드, 하나는 대괄호에 넣는 번호, 하나는 중괄호 안 콜론 뒤에 쓰는 모양입니다.
정답
받는 답: (가) strip · (나) upper · (다) -1 · (라) :,
- 같은 답으로 치는 꼴: 괄호까지 쓴
strip()·upper(), 대괄호까지 쓴[-1], 앞에서 센 마지막 번호len(s) - 1, 쉼표만 쓴,. - 틀리는 꼴
replace— (가)에: 찾은 글자를 모두 바꾸는 메서드라, 빈칸을 지우게 쓰면 가운데 빈칸까지 지웁니다. - 틀리는 꼴
lower— (나)에: 거꾸로 소문자로 적은 새 문자열을 만듭니다. - 틀리는 꼴
len(s)— (다)에: 글자 수라 마지막 번호보다 하나 큽니다. 그 번호로 꺼내면IndexError입니다. - 틀리는 꼴
.1f— (라)에: 소수 첫째 자리까지 찍는 모양입니다.
다시 볼 레슨: 문자열 메서드 · 인덱스와 자르기 · f-문자열로 출력 꾸미기
문제 10
메뉴 이름의 첫 글자와 마지막 글자를 찍으려 했더니 아래처럼 멈췄습니다. 메뉴 이름이 바뀌어도 맞게 고쳐야 합니다 — menu가 'cappuccino'여도 c o가 찍혀야 합니다. 몇 번 줄의 무엇을 고쳐야 할까요? 고친 줄을 쓰세요.
menu = 'mocha'
end = len(menu)
print(menu[0], menu[end])
Traceback (most recent call last): File "main.py", line 3, in <module> print(menu[0], menu[end]) ~~~~^^^^^IndexError: string index out of range힌트
오류가 난 줄에 쓰인 이름 end가 몇 번 줄에서 어떤 값에 붙었는지 봅니다.
정답
2번 줄을 end = len(menu) - 1로 고칩니다.
menu = 'mocha'
end = len(menu) - 1
print(menu[0], menu[end])m a'mocha'는 다섯 글자라 번호가 0~4입니다. 2번 줄이 end를 글자 수 5에 붙여, 3번 줄이 없는 5번 자리를 꺼내다 멈췄습니다. 오류는 3번 줄에서 났지만 까닭은 번호를 만든 2번 줄에 있습니다. 앞에서 센 마지막 번호는 늘 len(menu) - 1입니다.
- 다르게 고쳐도 되는 곳: 2번 줄을 뒤에서 센 마지막 번호
end = -1로 고쳐도 맞고, 3번 줄을menu[end - 1]이나menu[-1]로 고쳐도 맞습니다. 모두 'cappuccino'여도c o가 찍힙니다. - 흔한 오답 하나는
menu[4]처럼 번호를 바로 쓰는 것입니다. 'mocha'에서는 맞지만 'cappuccino'에서는 마지막이 아닌 글자를 꺼냅니다.
menu = 'cappuccino'
end = len(menu) - 1
print(menu[0], menu[end])
print(menu[0], menu[4])c o
c u- 다른 흔한 오답은 오류만 없애려고 3번 줄을
menu[end:]로 바꾸는 것입니다. 자르기라 오류는 사라지지만 빈 문자열이 찍혀 마지막 글자가 나오지 않습니다.
문제 11 (만들어 보기)
카페 이벤트 당첨자를 이름 가운데만 가려 발표하는 프로그램을 만들어 봅니다. 이름을 물어 첫 글자와 마지막 글자만 남기고, 가운데 글자 수만큼 별(*)을 찍습니다. 물을 때 쓰는 글은 '이름: '입니다. 김민지를 넣으면 이렇게 나와야 합니다.
이름: 김민지
당첨 김*지님
남궁민수를 넣으면 이렇게 나와야 합니다.
이름: 남궁민수
당첨 남**수님
아래 뼈대의 주석 넷 아래를 채우세요. 다 쓰면 둘째 값으로도 따라가 봅니다.
# 1. 입력 받기
# 2. 앞뒤 글자 꺼내기
# 3. 별로 가려 잇기
# 4. 찍기넣는 값김민지
처음 펼 때 약 6MB를 받습니다.
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
견줄 시험 값
input()마다 위에서부터 한 줄씩 들어갑니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 넣은 값 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.
힌트
가운데 별의 수는 이름의 글자 수에서 앞뒤 두 글자를 뺀 수입니다.
정답
모범 답입니다. 김민지를 넣은 결과입니다.
# 1. 입력 받기
name = input('이름: ')
# 2. 앞뒤 글자 꺼내기
first = name[0]
last = name[-1]
# 3. 별로 가려 잇기
stars = '*' * (len(name) - 2)
masked = first + stars + last
# 4. 찍기
print(f'당첨 {masked}님')넣는 값김민지이름: 김민지
당첨 김*지님남궁민수를 넣으면 first는 '남', last는 '수'이고, 글자 수 4에서 2를 뺀 만큼 별을 이어 masked가 '남**수'에 붙습니다.
- 다르게 써도 되는 곳: 마지막 글자를
name[len(name) - 1]로 꺼내도 되고, 잇기를name[0] + stars + name[-1]처럼 한 줄로 써도 됩니다. - 찍은 화면이 위와 같고 남궁민수에서도
당첨 남**수님이 나오면 맞습니다. - 흔한 오답은 별을
'*' * len(name)으로 만드는 것입니다. 그러면 이름 글자 수만큼 별이 붙어당첨 김***지님이 됩니다. 마지막 글자를name[len(name)]으로 꺼내면IndexError로 멈춥니다.print('당첨', masked, '님')처럼 쉼표로 넘기면 '님' 앞에 빈칸이 들어가당첨 김*지 님이 됩니다.
다시 볼 레슨: 인덱스와 자르기 · 문자열 잇기와 되풀이 · f-문자열로 출력 꾸미기
문제 12 (만들어 보기)
이번에는 빈 데서 씁니다. 택시 요금과 사람 수를 물어, 똑같이 나눌 때 한 사람이 낼 돈(천 단위 쉼표)과 남는 돈을 찍는 프로그램을 쓰세요. 물을 때 쓰는 글은 '요금: '과 '사람 수: '입니다. 25000과 3을 넣으면 이렇게 나와야 합니다.
요금: 25000
사람 수: 3
한 사람 8,333원
남는 돈 1원
19000과 7을 넣으면 이렇게 나와야 합니다.
요금: 19000
사람 수: 7
한 사람 2,714원
남는 돈 2원
다 쓰면 둘째 값으로도 따라가 봅니다.
힌트
하위 목표 넷의 주석(1. 입력 받기 · 2. 수로 바꾸기 · 3. 계산하기 · 4. 찍기)을 먼저 쓰고, 그 아래를 채웁니다.
정답
모범 답입니다. 25000과 3을 넣은 결과입니다.
# 1. 입력 받기
fare = input('요금: ')
people = input('사람 수: ')
# 2. 수로 바꾸기
fare = int(fare)
people = int(people)
# 3. 계산하기
each = fare // people
rest = fare % people
# 4. 찍기
print(f'한 사람 {each:,}원')
print(f'남는 돈 {rest}원')넣는 값250003요금: 25000
사람 수: 3
한 사람 8,333원
남는 돈 1원19000과 7을 넣으면 each는 19000 // 7로 2714, rest는 19000 % 7로 2입니다.
- 다르게 써도 되는 곳: '1. 입력 받기'에서
int(input(…))로 바로 수를 만들어도 되고, 몫을 중괄호 안에 바로 써도 됩니다({fare // people:,}). 남는 돈을fare - each * people로 구해도 같습니다. - 찍은 화면이 위와 같고 19000과 7에서도 맞으면 맞습니다.
- 흔한 오답은 한 사람 몫을
/로 나누는 것입니다. 그러면한 사람 8,333.333333333334원처럼 소수점 아래가 길게 찍힙니다(/가 몫이라는 생각). 수를 만들지 않으면//에서TypeError로 멈추고(문자열과 수를 가리지 않는 생각), 쉼표 모양:,를 빠뜨리면한 사람 8333원입니다. 남는 돈을fare % 3처럼 첫 사람 수로 박아 두면 둘째 값에서남는 돈 1원이 찍힙니다.
다시 볼 레슨: 입력은 늘 글자 · 사칙 계산과 몫·나머지 · f-문자열로 출력 꾸미기