profile image

L o a d i n g . . .

27.6 심사문제: 특정 문자가 들어있는 단어 찾기

더보기

문제 : 문자열이 저장된 words.txt 파일이 주어집니다(문자열은 한 줄로 저장되어 있습니다). words.txt 파일에서 문자 c가 포함된 단어를 각 줄에 출력하는 프로그램을 만드세요. 단어를 출력할 때는 등장한 순서대로 출력해야 하며 ,(콤마)와 .(점)은 출력하지 않아야 합니다.

정답 :

with open('words.txt','r') as file:
    words = file.read()
    words = words.split()

    for word in words:
        if 'c' in word:
            print(word.strip(',.'))

open으로 words.txt 파일을 연 뒤 read로 파일의 내용을 읽어온다. 그다음에 split()으로 읽어온 문자열을 공백을 기준으로 분리하여 리스로 만든다.

마지막에 찾은 단어를 출력할 때는 ,(콤마)와 .(점)은 출력하지 않아야 하므로 strip(',.')를 사용하여 콤마와 점을 삭제한 뒤 print로 출력해야 한다.

 

 

 

28.4 심사문제: 파일에서 회문인 단어 출력하기

더보기

문제 : 문제 : 단어가 줄 단위로 저장된 words.txt 파일이 주어집니다. words.txt 파일에서 회문인 단어를 각 줄에 출력하는 프로그램을 만드세요. 단어를 출력할 때는 등장한 순서대로 출력해야 합니다. 그리고 파일에서 읽은 단어는 \n이 붙어있으므로 \n을 제외한 뒤 회문인지 판단해야 하며 단어를 출력할 때도 \n이 출력되면 안 됩니다(단어 사이에 줄바꿈이 두 번 일어나면 안 됨)

정답 : 

with open('words.txt', 'r') as file:
    lines = file.readlines()
    for line in lines:
    	line = line.strip('\n')
        if line == line[::-1]:
            print(line)

먼저 open으로 words.txt 파일을 읽기 모드 'r'로 연다. 그다음에 readlines로 파일의 내용을 한 줄씩 읽어서 리스트 형태로 가져온다.단어 리스트가 준비되었으면 for문으로 리스트를 반복하면서 단어가 회문인지 판단한다. 그런데 이때 파일에서 읽은 단어는 \n이 붙어있으므로 \n을 제외해야 한다.

그리고 시퀀스 뒤집기로 회문을 판단하여 회문일 경우만 단어를 출력하면 된다.

 

 

 

29.4 심사문제: 사칙 연산 함수 만들기

더보기

문제 : 표준 입력으로 숫자 두 개가 입력됩니다. 다음 소스 코드를 완성하여 두 숫자의 덧셈, 뺄셈, 곱셈, 나눗셈의 결과가 출력되게 만드세요. 이때 나눗셈의 결과는 실수라야 합니다.

정답 :

x, y = map(int, input().split())

def calc(a,b):
    return a+b,a-b,a*b,a/b

a, s, m, d = calc(x, y)
print('덧셈: {0}, 뺄셈: {1}, 곱셈: {2}, 나눗셈: {3}'.format(a, s, m, d))

return으로 값을 네 개 반환해야 하므로 각 반환값은 콤마로 구분해줘야 한다.

 

 

 

30.7 심사문제: 가장 낮은 점수, 높은 점수와 평균 점수를 구하는 함수 만들기

더보기

문제 : 표준 입력으로 국어, 영어, 수학, 과학 점수가 입력됩니다. 다음 소스 코드를 완성하여 가장 높은 점수, 가장 낮은 점수, 평균 점수가 출력되게 만드세요. 평균 점수는 실수로 출력되어야 합니다.

정답 :

korean, english, mathematics, science = map(int, input().split())

def get_min_max_score(*args):
    return min(args), max(args)

def get_average(**kwargs):
    return sum(kwargs.values())/len(kwargs)

min_score, max_score = get_min_max_score(korean, english, mathematics, science)
average_score = get_average(korean=korean, english=english,
                            mathematics=mathematics, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'
      .format(min_score, max_score, average_score))
 
min_score, max_score = get_min_max_score(english, science)
average_score = get_average(english=english, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'
      .format(min_score, max_score, average_score))

get_min_max_score 함수를 사용해서 가장 낮은 점수와 가장 높은 점수를 구하고, get_average 함수를 평균 점수를 구하고 있으므로 우선 함수를 두 개 만들어야 한다. 또 함수를 호출할 때마다 인수의 개수가 달라지고 있으므로 가변 인수 함수로 만들어야 한다.

get_average 함수는 인수를 키워드 인수로 넣고 있으므로 def get_average(**kwargs):와 같이 만들어준다.

함수 안에서는 평균을 구해야 하는데 먼저 sum(kwargs.values())처럼 values로 딕셔너리의 값만 가져온 뒤 sum으로 합계를 구한다.그리고 합계를 키의 개수로 나눠준 뒤 return으로 반환하면 된다.

 

 

 

31.5 심사문제: 재귀호출로 피보나치 수 구하기

더보기

문제 : 표준 입력으로 정수 한 개가 입력됩니다(입력 값의 범위는 10~30). 다음 소스 코드를 완성하여 입력된 정수에 해당하는 피보나치 수가 출력되게 만드세요. 피보나치 수는 0과 1로 시작하며, 다음 번 피보나치 수는 바로 앞의 두 피보나치 수의 합입니다.

정답 :

def fib(n):

    if n==0:
        return 0

    elif n==1:
        return 1
    

    else:
        return fib(n-1) + fib(n-2)

n = int(input())
print(fib(n))

피보나치 수를 재귀호출로 구하려면 트리 구조로 구해야 한다. 현재 n에서 바로 앞의 수(-1)과 그 앞의 수(-2)를 구해서 fib 함수에 넣는 식으로 수를 쪼개 나간다. n이 피보나치 수의 시작인 1이나 0이 되었을 때 재귀호출을 끝내고 n을 반환하면 된다.

즉, n이 1과 0이 될 때까지 반복하고 마침내 n이 1 또는 0이 되었을 때는 반환하면서 쪼개진 두 값을 더하고 위로 계속 더해가면서 반환하면 된다.

 

 

 

32.5 심사문제: 파일 이름을 한꺼번에 바꾸기

더보기

문제 : 표준 입력으로 숫자.확장자 형식으로 된 파일 이름 여러 개가 입력됩니다. 다음 소스 코드를 완성하여 파일 이름이 숫자 3개이면서 앞에 0이 들어가는 형식으로 출력되게 만드세요. 예를 들어 1.png 001.png, 99.docx 099.docx, 100.xlsx 100.xlsx처럼 출력되어야 합니다. 그리고 람다 표현식을 사용해야 하며 출력 결과는 리스트 형태라야 합니다. 람다 표현식에서 파일명을 처리할 때는 문자열 포매팅과 문자열 메서드를 활용하세요.

정답 : 

files = input().split()
 
print(list(map(lambda x:'{0:03d}.{1}'.format(int(x.split('.')[0]),x.split('.')[1]),files)))

먼저 람다 표현식을 작성할 때 매개변수로 받은 문자열을 조작해서 001.png, 099.docx, 100.xlsx 같은 형식이 되어야 한다.

따라서 문자열 포매팅을 '{0:03d}.{1}'와 같이 만들어준다. 먼저 {0:03d}는 파일 이름 부분이며 숫자 1은 001, 99는 099, 100은 100처럼 숫자 3개로 만들고 앞에 0이 들어간다. 그리고 {1}은 확장자 부분이며 문자열이 그대로 들어간다.

 

이제 '{0:03d}.{1}' format 메서드를 사용해서 내용을 채운다. 먼저 문자열은 split('.')처럼 '.'을 기준으로 분리해서 파일 이름과 확장자로 나눈다. 그리고 lambda에서 매개변수로 x를 지정했다면 int(x.split('.')[0])과 같이 파일 이름 부분을 얻는다. 또 거기에는 숫자가 들어가야 하므로 int를 사용해서 정수로 변환해준다.

확장자는 x.split('.')[1]처럼 문자열을 '.'으로 분리했을 때 두 번째 요소를 사용한다.

 

 

 

33.6 심사문제: 카운트다운 함수 만들기

더보기

문제 : 표준 입력으로 정수가 입력됩니다. 다음 소스 코드를 완성하여 함수 c를 호출할 때마다 숫자가 1씩 줄어들게 만드세요. 여기서는 함수를 클로저로 만들어야 합니다. 정답에 코드를 작성할 때는 def countdown(n):에 맞춰서 들여쓰기를 해주세요.

정답 : 

def countdown(n):

    count = n+1

    def closure():
        nonlocal count

        count -= 1

        return count
        
    return closure

n = int(input())
 
c = countdown(n)
for i in range(n):
    print(c(), end=' ')

함수 countdown을 호출해서 반환값을 c에 저장한 뒤에 c를 호출하고 있다. 그리고 c를 호출할 때마다 값이 계속 유지되게 하려면 함수를 클로저로 만들어야 한다.

그리고 우선 함수 countdown에 지역 변수를 만들고 매개변수 n에 1을 더해서 할당한다. 여기선 예를 들어 입력값이 10이면 10부터 숫자가 1씩 줄어들고 있으므로 처음 시작할 값은 11로 만들어야한다.

 

 

 

34.6 심사문제: 게임 캐릭터 클래스 만들기

더보기

문제 : 표준 입력으로 게임 캐릭터 능력치(체력, 마나, AP)가 입력됩니다. 다음 소스 코드에서 애니(Annie) 클래스를 작성하여 티버(tibbers) 스킬의 피해량이 출력되게 만드세요. 티버의 피해량은 AP * 0.65 + 400이며 AP(Ability Power, 주문력)는 마법 능력치를 뜻합니다.

정답 : 

class Annie:

    def __init__(self,health,mana,ability_power):
        self.health=health
        self.mana=mana
        self.ability_power=ability_power

    def tibbers(self):
        print('티버: 피해량 {0}'.format(self.ability_power*0.65+400))
    

health, mana, ability_power = map(float, input().split())
 
x = Annie(health=health, mana=mana, ability_power=ability_power)
x.tibbers()

 

 

 

35.6 심사문제: 시간 클래스 만들기

더보기

문제 : 표준 입력으로 시:분:초 형식의 시간이 입력됩니다. 다음 소스 코드에서 Time 클래스를 완성하여 시, 분, 초가 출력되게 만드세요. from_string은 문자열로 인스턴스를 만드는 메서드이며 is_time_valid는 문자열이 올바른 시간인지 검사하는 메서드입니다. 시간은 24시까지, 분은 59분까지, 초는 60초까지 있어야 합니다. 정답에 코드를 작성할 때는 class Time:에 맞춰서 들여쓰기를 해주세요.

정답 : 

class Time:
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second


    @classmethod
    def from_string(cls,time_string):
        hour, minute, second = map(int,time_string.split(':'))
        time = cls(hour, minute, second)
        return time
    
    @staticmethod
    def is_time_valid(time_string):
        a,b,c = map(int,time_string.split(':'))

        return a<=24 and b<=59 and c<=60
    
 
time_string = input()
 
if Time.is_time_valid(time_string):
    t = Time.from_string(time_string)
    print(t.hour, t.minute, t.second)
else:
    print('잘못된 시간 형식입니다.')

먼저 from_string 메서드를 사용하여 문자열로 인스턴스를 만들어야 한다.

from_string 메서드는 Time.from_string처럼 호출하고 있고, 현재 클래스로 인스턴스를 만들어야 하므로 클래스 메서드로 만든다. 메서드 안에서는 hour, minute, second = map(int, time_string.split(':'))와 같이 ':'로 문자열을 분리한 뒤 int로 변환해서 각 변수에 넣어준다. 그다음에는 time = cls(hour, minute, second)와 같이 클래스에 변수를 넣어서 인스턴스를 만든다. 그리고 인스턴스는 바깥에서 사용할 수 있도록 return으로 반환해준다.

 

그리고 is_time_valid 메서드도 Date.is_time_valid처럼 호출하고 있지만, 문자열이 올바른 시간인지 검사만 하면 되고, 클래스에 접근할 필요는 없습니다. 그러므로 정적 메서드로 만든다.

 

 

 

36.9 심사문제: 다중 상속 사용하기

더보기

문제 : 다음 소스 코드에서 동물 클래스 Animal과 날개 클래스 Wing을 상속받아 새 클래스 Bird를 작성하여 '먹다', '파닥거리다', '날다', True, True가 각 줄에 출력되게 만드세요.

정답 :

class Animal:
    def eat(self):
        print('먹다')
 
class Wing:
    def flap(self):
        print('파닥거리다')


class Bird(Animal,Wing):
    def fly(self):
        print('날다')


b = Bird()
b.eat()
b.flap()
b.fly()
print(issubclass(Bird, Animal))
print(issubclass(Bird, Wing))

 

 

 

37.3 심사문제: 두 점 사이의 거리 구하기

더보기

문제 : 표준 입력으로 x, y 좌표 4개가 입력되어 Point2D 클래스의 인스턴스 리스트에 저장됩니다. 여기서 점 4개는 첫 번째 점부터 마지막 점까지 순서대로 이어져 있습니다. 다음 소스 코드를 완성하여 첫 번째 점부터 마지막 점까지 연결된 선의 길이가 출력되게 만드세요.

정답 :

import math
 
class Point2D:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
 
length = 0.0
p = [Point2D(), Point2D(), Point2D(), Point2D()]
p[0].x, p[0].y, p[1].x, p[1].y, p[2].x, p[2].y, p[3].x, p[3].y = map(int, input().split())


for i in range(len(p) - 1):
    a = p[i+1].x - p[i].x
    b = p[i+1].y - p[i].y

    length += math.sqrt((a * a) + (b * b)) 

print(length)

두 점 사이의 거리를 구하려면 피타고라스의 정리를 이용하면 된다.

반복문으로 반복하면서 현재 점 p[i]와 다음 점 p[i + 1] 사이의 거리를 구한 뒤 length 변수에 계속 더해준다.

 

단, 마지막 점은 다음 점이 없으므로 반복문은 for i in range(len(p) - 1):과 같이 만들어서 마지막 요소의 바로 앞 요소까지만 반복한다.

복사했습니다!