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

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

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

 

도전문제 3.1 (73p)
time = int(input("초를 입력하세요 : "))
hour = time // 3600
time = time % 3600

minute = time // 60
time = time % 60

print("입력한 시간은", hour, "시간", minute, "분", time, "초입니다.")

사실 time보다는 remain_sec이 더 정확하다.

 

 

도전문제 3.2 (77p)
gender = int(input('여성이면 1, 남성이면 0을 입력하세요: '))
height = int(input('당신의 키는 얼마입니까? '))
circumference = int(input('당신의 허리 둘레는 얼마입니까? '))
rfm = 64 - (20 * (height / circumference)) + 12 * gender 
print('당신의 RFM은', rfm)

공식대로 계산식을 구성하면 된다.

 

 

심화문제

 

(3.1)

print('a', '          ', 'n', '          ', 'a**n')

for i in range(5):
    print(i+2, '          ', 2, '          ', (i+2)**2)

간단한 반복 문제다.

뒤의 i+2를 괄호로 묶어줘서 우선순위를 확보해주자.

 

 

 

(3.2)

for i in range(9):
    print(i+2, '의 제곱근 = ', (i+2)**0.5)

이것도 간단하다. 3.1과 비슷하다.

 

만약 C에 더 익숙하다면, format 함수를 이용한 다음 코드를 제시할 수도 있을 것이다.

for i in range(9):
    print('{0}의 제곱근 = {1}'.format(i+2, (i+2)**0.5))

 

 

 

(3.3)

for i in range(10):
    print(2<<(i))

이것이 기본코드다. 근데 쥬피터에서는 줄바꿈이 일어나니 다음을 제안한다.

for i in range(10):
    print(2<<(i), end=' ')

 

 

 

(3.4)

n = int(input('정수를 입력하세요'))
print('입력된 정수는 0에서 100의 범위 안에 있는 짝수인가요?')
if n <=100 and n >= 0:
    print('Ture')
else:
    print('False')

물론, n> 100 or n<0을 False로 설정하고 나머지 경우 else를 Ture로 설정할 수도 있다.

 

n = int(input('정수를 입력하세요'))
print('입력된 정수는 0에서 100의 범위 안에 있는 짝수인가요?')
if n > 100 or n < 0:
    print('False')
else:
    print('Ture')

부등호만 바꿔서 n>100 and n<0을 해버린 경우, 두 개 다 만족하는 경우가 한 개도 없으므로, 모두 Ture가 나와버릴 것이다. (모두 거짓(0)의 값이 나옴)

 

 

 

(3.5)

print(bin(5), '&', bin(6), ' = ', bin(5 & 6))
print(bin(5), '|', bin(6), ' = ', bin(5 | 6))
print(bin(5), '^', bin(6), ' = ', bin(5 ^ 6))

이진수 계산은 bin안에서 해주면 된다. 논리곱 and는 &, 논리합 OR는 |, 베타적 논리합 XOR는 ^를 써준다.

논리곱은 둘 다 1이면 1이고 논리합은 둘 중 하나라도 1이면 1이다. 베타적 논리합은 서로 다를 때만 1이 나온다.

이를 각 자리수마다 적용시켜주면, 계산 결과가 나온다.

 

(3.6)

a = int(input('정수 a를 입력하시오 : '))
b = int(input('정수 b를 입력하시오 : '))

print('a / b의 몫 : ', a//b)
print('a / b의 나머지 : ', a%b)

몫은 a//b로, 나머지는 a%b로 구해주면 된다.

c언어 상에서는 int형일 때 a/b가 몫 연산이지만, 파이썬은 a/b가 실수형 나눗셈 연산이다.

 

 

(3.7)

a = int(input('세 자리 정수를 입력하시오 : '))

hundred = a // 100
ten = (a // 10) % 10
one = a % 10

print('백의 자리', hundred)
print('십의 자리', ten)
print('일의 자리', one)

개인 취향에 따라 여러가지로 구성할 수 있는 문제다.

 

a = int(input('세 자리 정수를 입력하시오 : '))

hundred = a // 100
ten = (a-hundred*100) // 10
one = (a-hundred*100) % 10

print('백의 자리', hundred)
print('십의 자리', ten)
print('일의 자리', one)

 

예를 들어, 이런 식으로도 가능하나 첫번째 것이 역시 단순하다. 코드는 단순함을 추구해야 한다. (가독성, 비용, 시간 상)

 

 

(3.8)

1)

a = int(input('세 자리 정수를 입력하시오 : '))

hundred = a // 100
ten = (a-hundred*100) // 10
one = (a-hundred*100-ten*10)

tmp = hundred
hundred = one
one = tmp

print(hundred)
print(ten)
print(one)

3.7과 연계하여 생각할 수 있는 문제다.

일단 백의 자리, 십의 자리, 일의 자리를 구하는 코드는 그대로 가져오고,

입력이 세 자리 정수가 전제이므로 ten은 그대로 놓고 hundred와 one만 교체하는 코드를 작성한다.

이 때, 무작정 hundred = one을 해버리면 기존 hundred의 값이 소멸되므로 hundred의 값을 tmp에 넣고 나서 진행한다.

이 경우 역시 문제에서 힌트를 준 것처럼, % 연산자를 사용하여 각 자리수를 구할 수도 있다. (스타일의 문제)

 

 

2)

2번은 따로따로 나오면 곤란하므로 다음을 제시할 수 있다. (print 부분만 수정)

print("{0}{1}{2}".format(hundred, ten, one))
print(f"{hundred}{ten}{one}")

f-string을 사용할 수도 있다 (좋은 방법)

 

end=''는 사용할 수 없나요?

end=''도 물론 사용 가능하다. 하지만 그럴러면 

print(hundred, end='')
print(ten, end='')
print(one)

와 같이 가독성이 떨어지는 것으로 작성해야 한다.

print(hundred, ten, one, end='')

로 작성하면 안되는가? 의문이 들 수도 있다. 그러나, 이 코드는 사실..

print(hundred)
print(ten)
print(one, end='')

와 다를 것이 없다. print함수를 호출하고 나면 공백이 자동으로 작성되는데, hundred 출력 후 공백, ten 출력 후 공백, one 출력후 공백없이 진행(end=''로 인해)이 되기 때문에 결국 456을 입력하면 6 5 4가 출력된다.

가장 위의 end=''사용 용법은 함수가 호출될때마다 end=''를 붙여주기 때문에 공백을 제거하여 654가 출력된다.

 

함수의 호출에 대한 이해를 하고, 구성할 줄 알아야 한다.

 

 

(3.9)

km = float(input("평균 시속(km/h)을 입력하세요 :"))
time = float(input("이동시간(h)을 입력하세요 : "))

hour = int(time // 1)
time_by_sec = (time-hour)*3600
min = int(time_by_sec // 60)
sec = int(time_by_sec % 60)

print(f"평균 시속 : {km} km/h")
print(f"이동 시간 : {hour}시간 {min}분 {sec}초")
print("이동 거리 : ", km*time, " km")

일단 hour는 time을 1로 나눈 몫으로 설정했고, time에서 hour를 뺀 나머지 시간은 초(sec)로 환산하여 min과 sec을 각각 몫 연산자, 나머지 연산자로 구할 수 있었다. km와 time을 float로 입력받았으므로 int형으로 형변환을 해줬다.

또 f-string도 활용된 것을 볼 수 있다. 

이 문제 역시 time 값을 어떻게 변환할지는 본인 자유이다.

 

(3.10)

우선, 두 점 사이의 거리는 다음과 같다.

출처 : 네이버 지식백과

import math

x1 = int(input("x1 좌표를 입력하시오: "))
y1 = int(input("y1 좌표를 입력하시오: "))
x2 = int(input("x2 좌표를 입력하시오: "))
y2 = int(input("y2 좌표를 입력하시오: "))

distance = math.sqrt((x1-x2)**2+((y1-y2)**2))

print("두점의 거리: ", distance)

math.sqrt는 루트 역할을 하는 함수다.

sqrt함수를 사용하기 위해 math 모듈(c언어에서의 라이브러리)를 임포트 해야 한다.

이외에는 단순하다.

 

만약, c언어에서 이 문제를 해결하려면, pow함수를 사용하거나 (x1-x2)같은 것을 X라고 두고 X*X로 설정해야 할 것이다.

 

 

 

(3.11)

빗변을 이루는 점의 좌표가 각각 (x1, y1), (x2, y2)이고, x2 > x1, y2 > y1이다.

즉 x2-x1이 밑변이고, y2-y1이 높이이다. 그리고 직각삼각형의 넓이를 구하는 공식은 밑변*높이*1/2이므로

x1 = int(input("x1 좌표를 입력하시오: "))
y1 = int(input("y1 좌표를 입력하시오: "))
x2 = int(input("x2 좌표를 입력하시오: "))
y2 = int(input("y2 좌표를 입력하시오: "))

domain = (x2-x1)*(y2-y1)*0.5

print("직각삼각형의 면적은 : ", domain)

3.10 문제에서 math 모듈을 삭제해주고 계산식만 변경해주자.

변수 이름도 domain으로 설정한다.

 

 

(3.12)

이건 전에 해왔던 문제와도 비슷하고, 노가다성 문제라 풀이에서 제외하겠다.

식만 올바르게 구성하고 값을 받아 계산하면 된다.

pi의 정의같은 경우는, pi = 3.14로 선언하고 계산하거나 7번에 나왔듯이, math 모듈을 불러오고 math.pi를 써도 된다.

(모듈을 불러와서 pi를 쓰는 것이 더 정확)

 

반응형