본문 바로가기
Python (파이썬)/따라하며 배우는 파이썬과 데이터과학 (구판)

따라하며 배우는 파이썬과 데이터과학 4장 도전문제와 심화문제

by EATSTAR 2024. 5. 24.
반응형
* 본문은 쥬피터 노트북 7.0.8 버전을 사용하였으므로 다른 버전의 쥬피터 노트북이나 파이썬 IDLE같은 작동 프로그램으로 작동할 경우 오류가 생길 수 있음을 양지해주세요.

 

도전문제 4.1 (95p)
speed = int(input("속도를 입력하세요 : "))

if speed >= 30:
    print("과속입니다. 속도를 줄이세요.")

조건에 해당할 때만 print 함수를 실행하도록 if 문을 구성하자.

 

도전문제 4.2 (96p)
speed = int(input("속도를 입력하세요 : "))

if speed >= 30:
    print("과속입니다. 속도를 줄이세요.")
else:
    print("안전운전하세요.")

4.1 문제에 else 문만 추가해서, if 문에 충족되지 않는 모든 경우에 나올 print 함수를 작성하자.

 

 

도전문제 4.3 (97p)

(1)

num = int(input("정수를 입력하세요 : "))

if num < 0:
    print("음수입니다.")
else:
    print("음수가 아닙니다.")

단순한 if-else 문이다.

 

 

(2)

game_score = int(input("게임 점수를 입력하세요 : "))

if game_score >= 10000:
    print("고수입니다.")
else:
    print("입문자입니다.")

단순한 if-else 문이다.

 

(3)

num1 = int(input("첫 번째 정수를 입력하세요 : "))
num2 = int(input("두 번째 정수를 입력하세요 : "))

if num1 == num2:
    print("두 값이 일치합니다.")
else:
    print("두 값이 일치하지 않습니다.")

두 값이 일치하는지 확인할 때는 == 연산자를 사용하자.

 

 

도전문제 4.4 (99p)
import turtle 
t = turtle.Turtle()
t.shape("turtle")

t.penup()
t.goto(100, 100)
t.write("두 수 모두 양수")
t.goto(-100, 100)
t.write("첫 번째 수만 양수")
t.goto(-100, -100)
t.write("두 수 모두 음수")
t.goto(100, -100)
t.write("두 번째 수만 음수")

t.goto(0,0)
t.pendown()

x = int(turtle.textinput("", "첫 번째 숫자를 입력하시오: "))
y = int(turtle.textinput("", "두 번째 숫자를 입력하시오: "))

if x > 0:
    if y > 0:
        t.goto(100, 100)
    else:
        t.goto(100, -100)
if x < 0:
    if y > 0:
        t.goto(-100, 100)
    else:
        t.goto(-100, -100)

turtle.done()

갑자기 간단하던 도전문제가 복잡해졌다!

그러나 원리 자체는 저저번 장에서 학습한 내용과 98-99p의 예시가 제시해주는 범위 안에 있으므로 어렵지는 않다.

가장 앞 3개의 코드는 기본적 모듈, 판과 거북이를 생성하는 것이고 그 다음은 펜을 들고(이동경로를 기록하지 않고)

원하는 좌표에 텍스트를 넣는 것이다.

원점으로 돌아간 후, pendown() 함수로 다시 펜을 내려놓아 이동경로를 기록한다.

이 상황에서 두 수를 받아 각각 양수인지, 음수인지를 판단하는 if문을 작성하여 거북이가 그 좌표까지 이동하며 선을 그리게 하면 성공이다. 

 

예시: x가 1, y가 1이 입력되었을 때의 출력값

 

도전문제 4.5 (99p)
import turtle 
t = turtle.Turtle()
t.shape("turtle")

t.penup()
t.goto(100, 0)
t.write("x가 y보다 큼")
t.goto(-100, 0)
t.write("y가 x보다 큼")
t.goto(0, 100)
t.write("두 값이 같음")

t.goto(0,0)
t.pendown()

x = int(turtle.textinput("", "첫 번째 숫자를 입력하시오: "))
y = int(turtle.textinput("", "두 번째 숫자를 입력하시오: "))

if x > y:
    t.goto(100, 0)
if x < y:
    t.goto(-100, 0)
else:
    t.goto(0, 100)

turtle.done()

4.4와 원리 자체는 같은 문제다. 형식은 매우 유사하므로 설명은 생략할 수 있을 것 같다.

코드야 길지만.. 생각보다 Turtle이 어렵지 않다고 생각되지 않는가?

 

도전문제 4.6 (100p)

1)

age = int(input("나이를 입력하시오: "))
if age >= 15:
    print("본 영화를 보실 수 있습니다.")
    print("영화의 가격은 10000원입니다.")
else:
    print("본 영화를 보실 수 없습니다.")
    print("다른 영화를 보시겠어요?")

간단한 print 함수만 추가하면 된다.

 

 

2)

card = input("카드의 종류를 입력하세요.")
if card == "청소년":
    print("청소년입니다.")
else:
    print("승인되었습니다.")

일반적인 if-else 문이다. 

else로 뭉뚱그려 코드를 구성했지만 (a같은 아무 문자를 입력해도 승인되었습니다가 뜰 것임)

애초에 카드가 2가지 밖에 없다는 전제이므로 편의상 else로만 설정하자. 

 

도전문제 4.7 (102p)
import turtle

t = turtle.Turtle()
t.shape("turtle")
t.width(3)
t.shapesize(3, 3)

while True:
    command = input("명령을 입력하시오: ")
    if command == "f":
        t.forward(100)
    if command == "h":
        t.shapesize(10, 10)
    if command == 'n':
        t.shapesize(3, 3)
    if command == '1':
        t.shapesize(1, 1)
    if command == '2':
        t.shapesize(2, 2)
    if command == '3':
        t.shapesize(3, 3)
    if command == '4':
        t.shapesize(4, 4)
    if command == '5':
        t.shapesize(5, 5)
    if command == '6':
        t.shapesize(6, 6)
    if command == '7':
        t.shapesize(7, 7)
    if command == '8':
        t.shapesize(8, 8)
    if command == '9':
        t.shapesize(9, 9)
        
turtle.done()

원래 코드에서 조금만 수정해서 만들면 된다. (command='l'일때와 'r'일 때는 이미 예시 코드에 있으므로 일부러 제외) t.shapesize는 거북이의 크기를 늘이고 줄이는 함수다.

1~9배에서 커지도록 하는 3)번의 문제에 뭔가 꼼수가 있을 것 같지만.. 노가다였다.

 

9를 누르고 나서 f를 2번 누른 상태.

 

도전문제 4.8 (102p)
import random
import turtle 

# 기본 세팅
t = turtle.Turtle()
t.shape("turtle")

for i in range(10):
    num = random.randrange(2)
    if num == 0:
        t.right(90)
        t.forward(50)
    else:
        t.left(90)
        t.forward(50)

turtle.done()

왜 10개의 난수를 만들라고 한지는 모르겠다. (아마 2개의 난수의 오타인 듯)

일단 기본 세팅을 해주고(전에 쓴 코드를 가져오자.), 난수를 생성하기 위해 random 모듈을 불러오고 random.range로 0,1 둘 중 하나의 값이 반환되게 한다.

num 값이 0이면 오른쪽으로 50만큼 이동하고, num 값이 1이면 왼쪽으로 50만큼 이동한다.

 

첫 번째 실행결과.
두 번째 실행결과. 실행시마다 다르게 출력된다.

 

도전문제 4.9 (105p)
import random

player1 = input("player1의 이름 : ")
player2 = input("player2의 이름 : ")

print("......주사위를 굴립니다......")
num1 = random.randint(1,6)
num2 = random.randint(1,6)
print(player1, "의 주사위 번호는", num1)
print(player2, "의 주사위 번호는", num2)

if num1 > num2:
    print(player1, "이 이겼습니다.")
elif num1 < num2:
    print(player2, "이 이겼습니다.")
else:
    print("비겼습니다.")

어려워보이지만 간단하다. 사용자의 이름을 받고, rand.randint를 이용해 1부터 6까지의 난수를 받는다.

그리고 그 수를 비교하여 누가 이겼는지, 또는 비겼는지를 판단해준다.

난수를 출력하기 때문에 출력할 때마다 결과는 다르다.

 

 

도전문제 4.10 (106p)
import math

x, y = map(float, input("점의 좌표 x, y를 입력하시오 : ").split())
# 원의 중심은 (3,4)
distance = math.sqrt((x-3)**2+(y-4)**2)

if distance > 10:
    print("원의 외부에 있음")
elif distance < 10:
    print("원의 내부에 있음")
else: # distance == 10인 경우
    print("원 위에 있음")

map 함수를 사용하여 받을 형식을 지정하고, 특정 문자(또는 공백)를 기준으로 여러 변수를 한번에 입력받아보자.

예제처럼 math 모듈과 sqrt 함수를 쓰지 않는 방법도 있지만 오히려 복잡하므로 이처럼 사용해보자.

원의 중심이 원점이 아닌, (3,4)로 변경되었으므로 distance를 구하는 공식을 수정하고, 

반지름의 거리를 참조해 원의 외부, 내부에 있는 것을 판단하자.

 

 

도전문제 4.11 (109p)

 

id = "ilovepython"
password = "mypass1234"

s = input("아이디를 입력하시오: ")
if s == id:
    s = input("패스워드를 입력하시오: ")
    if s == password:
        print("환영합니다.")
    else:
        print("비밀번호가 틀렸습니다.")
else:
    print("아이디를 찾을 수 없습니다.")

id와 password를 설정하고 사용자로부터 입력받은 s와 각각 비교해보자.

이 때, id부터 잘못되었다면, password 입력으로 넘어가지 않는다.

 

 

심화문제 (113p~114p)

(4.1)

다음 두 가지 방식을 제시할 수 있다.

text = input("알파벳을 입력하세요: ")

if text == 'a' or text == 'e' or text == 'i' or text == 'o' or text == 'u':
    print(text, "(은)는 모음입니다.")
else:
    print(text, "(은)는 자음입니다.")
text = input("알파벳을 입력하세요: ")

if text in ['a', 'e', 'i', 'o', 'u']:
    print(text, "(은)는 모음입니다.")
else:
    print(text, "(은)는 자음입니다.")

후자가 좀 더 간단한 코드이다. (4장의 수준에서는 전자가 맞다)

 

잘못된 코드

이때, 전자의 코드 사이에

if text == 'a' or 'e' or 'i' or 'o' or 'u':

로 작성한다면 실제로는 text == 'a'와 'e', 'i', 'o', 'u'에 대한 OR 연산이 일어나게 된다.

0이 아닌 모든 문자는 true값을 가지므로, 위의 if문은 언제나 true를 나타내어 자음을 입력해도 모음이라고 출력한다.

 

(4.2)

x, y, z = map(int, input("세 정수를 입력하시오: ").split())

# 가장 큰 값을 찾기
if x >= y and x >= z:
    max_value = x
    if y >= z:
        middle_value = y
        min_value = z
    else:
        middle_value = z
        min_value = y
elif y >= x and y >= z:
    max_value = y
    if x >= z:
        middle_value = x
        min_value = z
    else:
        middle_value = z
        min_value = x
else:
    max_value = z
    if x >= y:
        middle_value = x
        min_value = y
    else:
        middle_value = y
        min_value = x

print("내림차순 정렬 결과:", max_value, middle_value, min_value)

if 문을 써서 풀려니 정말 복잡하다. 일단 and를 이용해서 x가 가장 큰 경우, y가 가장 큰 경우, z가 가장 큰 경우로 나눈다.

그리고 나머지 수끼리 비교해서 중간 수, 최소를 구한다. 사실 이것은 간소화시킬 수 있다.

 

x, y, z = map(int, input("세 정수를 입력하시오: ").split())

min_value = min(x, y, z)
max_value = max(x, y, z)
middle_value = x + y + z - min_value - max_value

print("오름차순 정렬 결과:", max_value, middle_value, min_value)

이렇게 최소, 최대를 구하고 전체에서 최소 최대를 뺀 것을 중간 수로 설정하면 얼마나 편리한가? min 함수나 max 함수가 어려운 것도 아니다.

 

x, y, z = map(int, input("세 정수를 입력하시오: ").split())

sorted_numbers = sorted([x, y, z], reverse=True)

print("내림차순 정렬 결과:", sorted_numbers)

조금 더 나아가 이런식으로도 할 수 있을텐데, 이 정도 수준은 4장에서 거론할 것은 아니다.

 

 

(4.3)

age = int(input("나이를 입력하시오 : "))

if age >= 20:
    print("Adult")
elif age < 10:
    print("Kid")
else:
    print("Youth")

조건이 가장 까다로운 것을 else에 배치하자.

 

 

(4.4)

num = int(input("정수를 입력하시오 : "))

if num % 2 == 0:
    print(num, "는(은) 2로 나누어집니다")
else:
    print(num, "는(은) 2로 나누어지지 않습니다.")

if num % 3 == 0:
    print(num, "는(은) 3로 나누어집니다")
else:
    print(num, "는(은) 3로 나누어지지 않습니다.")

if num % 3 == 0 and num % 2 == 0:
    print(num, "는(은) 2와(과) 3 모두로 나누어집니다.")
else:
    print(num, "는(은) 2와(과) 3 모두로 나누어지지 않습니다")

 

2와 3으로 각각 나누어 떨어지는지 살펴보고, 둘 다 나누어 떨어지는지에 대해서도 출력해보자.

 

 

(4.5)

import random

x = random.randint(0,9)
y = random.randint(0,9)
z = random.randint(0,9)

x2, y2, z2 = map(int, input("세 복권번호를 입력하시오 : ").split())
print(x, y, z)
i = 0

if x == x2 or x == y2 or x == z2:
    i += 1
if y == x2 or y == y2 or y == z2:
    i += 1
if z == x2 or z == y2 or z == z2:
    i += 1

if i == 0:
    print("다음 기회에...")
elif i == 1:
    print("1만원")
elif i == 2:
    print("1천만원")
else:
    print("1억원")

i를 이용해서 얼마나 복권번호가 일치하는지 살펴보자. (자리는 신경쓰지 않고, 해당 숫자가 나왔는지에만 관심이 있다.)

랜덤으로 주어지는 복권번호 간의 중복은 제한이 없기 때문에, 만약 3 3 3으로 복권번호가 나왔는데 입력이 1 2 3이었다면, 1억원 상금이 출력될 것이다.

 

중복의 허점에 대한 예시

 

(4.6)

print("우리식당에 오신것을 환영합니다. 메뉴는 다음과 같습니다.")
print("- 햄버거(입력 b)")
print("- 치킨(입력 c)")
print("- 피자(입력 p)")

menu = input("메뉴를 선택하세요(알파벳 b, c, p 입력) : ")
if menu == 'b':
    print("버거을 선택하셨습니다.")
elif menu == 'c':
    print("치킨을 선택하셨습니다.")
elif menu == 'p':
    print("피자를 선택하셨습니다.")
else:
    print("선택하신 메뉴는 없습니다.")

간단한 if문 문제다. else:로 b, c, p 외의 문자를 입력했을 때의 출력도 고려했다.

 

 

(4.7)

import random

x = random.randint(1,100)
y = random.randint(1,100)

print(x, " + ", y, " = ")
num = int(input())

if num == x+y:
    print("잘했어요!!")
else:
    print(f"정답은 {x+y}입니다")

 

생각보다 간단한 코드다. f-string도 활용해보자.

 

 

(4.8)

print("1)덧셈 2)뺄셈 3)곱셈 4)나눗셈")
num = int(input("어떤 연산을 원하는지 번호를 입력하세요"))
x, y = map(int, input("연산을 원하는 숫자 두개를 입력하세요: ").split())

if num == 1:
    print(f"{x} + {y} = {x+y}")
if num == 2:
    print(f"{x} - {y} = {x-y}")
if num == 3:
    print(f"{x} * {y} = {x*y}")
if num == 4:
    print(f"{x} / {y} = {x/y}")
else:
    print("num의 값이 잘못되었습니다.")

f-string을 쓰니 간단하다. 어떤 연산을 할지 정하는 num을 참조해 계산해보자.

 

 

(4.9)는 생략.

반응형