Minwoo Dev.

<점프 투 파이썬> :: 파이썬 초보탈출 코딩 면허시험 20제 문제풀이 본문

Python

<점프 투 파이썬> :: 파이썬 초보탈출 코딩 면허시험 20제 문제풀이

itisminu 2023. 10. 19. 23:04
728x90
반응형
SMALL

Q1. 문자열 바꾸기

다음과 같은 문자열이 있다.

a:b:c:d

문자열의 split와 join 함수를 사용하여 위 문자열을 다음과 같이 고치시오.

a#b#c#d

 

 

정답)

a = "a:b:c:d"
split_a = a.split(":")

join_a = "#".join(split_a)
print(join_a)

 


 

Q2. 딕셔너리 값 추출하기

다음은 딕셔너리의 a에서 'C'라는 key에 해당하는 value를 출력하는 프로그램이다.

>>> a = {'A':90, 'B':80}
>>> a['C']
Traceback (most recent call last):
	File "<stdin>", line 1, in <module>
KeyError: 'C'

a 딕셔너리에는 'C'라는 key가 없으므로 위와 같은 오류가 발생한다. 'C'에 해당하는 key 값이 없을 경우 오류 대신 70을 얻을 수 있도록 수정하시오.

 

정답)

a = {'A':90, 'B':80}

if a.get('C')==None:
    a['C'] = 70

print(a['C'])

 


Q3. 리스트이 더하기와 extend 함수

다음과 같은 리스트 a가 있다.

>>> a = [1, 2, 3]

리스트 a에 [4,5]를 + 기호를 사용하여 더한 결과는 다음과 같다.

>>> a = [1, 2, 3]
>>> a = a + [4,5]
>>> a
[1, 2, 3, 4, 5]

리스트 a에 [4,5]를 extend를 사용하여 더한 결과는 다음과 같다.

>>> a = [1, 2, 3]
>>> a.extend([4,5])
>>> a
[1, 2, 3, 4, 5]

+ 기호를 사용하여 더한 것과 extend한 것의 차이점이 있을까? 있다면 그 차이점을 설명하시오.

 

 

정답)

>>> a = [1,2,3]
>>> id(a)
3163680967872

a 라는 리스트는 3163680967872이라는 주소에 저장되어 있다.

>>> a = [1,2,3]

>>> a = a + [4,5]
>>> print(a)

>>> id(a)
2238963858432

+ 기호를 사용하여 [4,5] 라는 리스트를 더했다. 그리고 주소 값을 확인해보니 2238963858432으로, 전의 주소값과 다른 것을 알 수 있다.

따라서, +를 사용하면 리스트 a의 값이 변하는 게 아니라 두 리스트가 더해진 새로운 리스트가 반환되는 것을 알 수 있다.

 

extend 함수와 비교해 보자.

>>> a = [1,2,3]

>>> a.extend([4,5])
>>> id(a)
3163680967872

+ 기호를 사용하여 더한 경우와는 달리 주소 값이 변하지 않고 그대로 유지되는 것을 확인할 수 있다.

 

 


Q4. 리스트 총합 구하기

다음은 A학급 학생의 점수를 나타내는 리스트이다. 다음 리스트에서 50점 이상 점수의 총합을 구하시오.

A = [20,55,67,82,45,33,90,87,100,25]

 

정답)

A = [20,55,67,82,45,33,90,87,100,25]

sum = 0

for a in A:
    if a>=50:
        sum+=a

print(sum)

 

 


Q5. 피보나치 함수

첫 번째 항의 값이 0이고 두 번째 항의 값이 1일 때, 이후에 이어지는 항은 이전의 두 항을 더한 값으로 이루어지는 수열을 피보나치 수열이라고 한다.

0, 1, 1, 2, 3, 4, 8, 13 ...

입력을 정수 n으로 받았을 때, n 이하까지의 피보나치 수열을 출력하는 함수를 작성해 보자.

 

정답)

n = input("숫자 입력 : ")
n = int(n)

pib = [0,1]
result = 0
if n==1:
    print(pib[0])
elif n>1:
    for i in range(1,n-1):
        pib.append(pib[i-1]+pib[i])

print(pib)

 

 


Q6. 숫자의 총합 구하기

사용자로부터 다음과 같은 숫자를 입력받아 입력받은 숫자의 총합을 구하는 프로그램을 작성하시오.

{단, 숫자는 콤마로 구분하여 입력한다.)

65,45,2,3,45,8

 

정답)

inputval = input("값을 입력하세요 : ")
a = map(int, inputval.split(','))

result = 0

for i in a:
    result += i

print(result)

 

 


Q7. 한 줄 구구단

사용자로부터 2~9의 숫자 중 하나를 입력받아 해당 숫자의 구구단을 한 줄로 출력하는 프로그램을 작성하시오.

실행 예)

구구단을 출력할 숫자를 입력하세요(2~9) : 2
2 4 6 8 10 12 14 16 18

 

정답)

a = input("구구단을 출력할 숫자를 입력하세요(2~9) : ")
a_num = int(a)

for i in range(1,10):
    print("%d"%(a_num*i),end=' ')

 

 


 

Q8. 역순 저장

다음과 같은 내용의 파일 abc.txt가 있다.

AAA
BBB
CCC
DDD
EEE

이 파일의 내용을 다음과 같이 역순으로 바꾸어 저장하시오.

EEE
DDD
CCC
BBB
AAA

 

정답)

f1 = open("abc.txt",'r')
f1lines = f1.readlines()
f1lines.reverse()


f2 = open("abc.txt",'w')
for i in range(0,len(f1lines)):
    f2.write(f1lines[i])
    

f1.close()
f2.close()

실행 전
실행 후

 

** abc.txt 파일에 아래와 같이 EEE 다음 줄을 띄워두지 않는다면 컴퓨터가 줄바꿈을 인식하지 못해 출력값이 다르게 나온다.

EEE다음 \n이 없을 경우

위와 같은 상태의 abc.txt 파일을 실행하면

EEE와 DDD가 붙어있는 걸 확인할 수 있다.

위처럼 EEE와 DDD가 붙게 된다.

그 이유를 알아보기 위해 f1lines 배열에 저장된 값을 확인해 보았다.

f1 = open("abc.txt",'r')
f1lines = f1.readlines()
f1lines.reverse()

print(f1lines)
    

f1.close()

위 코드로 확인해보니

EEE에만 줄바꿈 문자인 \n이 포함되지 않은 걸 확인할 수 있다. 그래서 abc.txt 파일에 마지막 문자인 EEE 다음에 엔터를 한번 입력해야한다!

 


Q9. 평균값 구하기

오른쪽 같이 총 10줄로 이루어진 sample.txt 파일이 있다. sample.txt  파일의 숫자 값을 모두 읽어 총합과 평균 값을 구한 후 평균 값을 result.txt 파일에 쓰는 프로그램을 작성하시오.

70    60    55    75    95    90    80    80    85    100

 

 

정답)

f = open("sample.txt",'r')
fresult = open("result.txt",'w')
flist = f.readlines()

result = 0

for i in flist:
    i = int(i)
    result += i

result = str(result)
fresult.write(result)

f.close()
fresult.close()

sample.txt
result.txt

 

 


Q10. 사칙연산 계산기

다음과 같이 동작하는 클래스 Calculator를 작성하시오.

>>> cal1 = Calculator([1,2,3,4,5])
>>> cal1.sum() # 합계
15
>>> cal1.avg() # 평균
3.0
>>> cal2 = Calculator([6,7,8,9,10])
>>> cal2.sum() # 합계
40
>>> cal2.avg() # 평균
8.0

 

 

정답)

class Calculator:
    def __init__(self, num):
        self.result = 0
        self.num = num
        self.len = len(num)


    def sum(self):
        for i in self.num:
            self.result += i
        return self.result

    def avg(self):
        for i in self.num:
            self.result += i
        self.result /= (self.len*2)
        return self.result
        

cal1 = Calculator([1,2,3,4,5])
print(cal1.sum())
print(cal1.avg())

cal2 = Calculator([6,7,8,9,10])
print(cal2.sum())
print(cal2.avg())

근데 avg 함수에서 self.len이 5가 나와야 하는데 5의 값이 나오지 않는지 *2를 해야 제 값이 출력됐다.

내 생각에 self.len이 원래의 값보다 2가 나눠진 값이 나오는 거 같다.

 

 


Q11. 모듈 사용 방법

C:\doit 디렉터리에 mymod.py 파이썬 모듈이 있다고 가정해 보자. 명령 프롬프트 창에서 차이썬 셸을 열어 이 모듈을 import 해서 사용할 수 있는 방법을 모두 기술하시오. 

>>> import mymod
>>>

 

정답)

 

1) sys 모듈 사용하기

다음과 같이 sys.path 에 C:\doit 이라는 디렉터리를 추가하면 C:\doit 이라는 디렉터리에 있는 mymod 모듈을 사용할 수 있게 된다.

>>> import sys
>>> sys.path.append("c:\doit")
>>> import mymod

 

2) PYTHONPATH 환경 변수 사용하기

다음처럼 PYTHONPATH 환경 변수에 C:\doit 디렉터리를 지정하면 C:\doit 디렉터리에 있는 mymod 모듈을 사용할 수 있게 된다.

C:\Users\home>set PYTHONPATH=c:\doit
C:\Users\home>python
>>> import mymod

 

3) 현재 디렉터리 사용하기

파이썬 셸을 mymod.py가 있는 위치로 이동하여 실행해도 mymod 모듈을 사용할 수 있게 된다. 왜냐하면 sys.path 에는 현재 디렉터리인 . 이 항상 포함되어 있기 때문이다.

C:\Users\home>cd c:\doit
C:\doit>python
>>> import mymod

 

 


Q12. 오류와 예외 처리

다음 코드의 실행 결과를 예측하고 그 이유에 대해 설명하시오.

result = 0
try:
    [1,2,3][3]
    "a"+1
    4 / 0
except TypeError:
    result += 1
except ZeroDivisionError:
    result += 2
except IndexError:
    result += 3
finally:
    result += 4

print(result)

 

정답)

7이 출력된다

 

1. result의 초깃값은 0이다.

2. try문 안의 [1,2,3][3] 이라는 문장 수행 시 IndexError 가 발생하여 except IndexError: 구문으로 이동하게 되어 result에 3이 더해져 3이 된다.

3. 최종적으로 finally 구문이 실행되어 result 에 4가 더해져 7이 된다.

4. print(result)가 수행되어 result 의 최종 값인 7이 출력된다.


Q13. DashInsert 함수

DashInsert 함수는 숫자로 구성된 문자열을 입력받은 뒤 문자열 안에서 홀수가 연속되면 두 수 사이에 - 를 추가하고, 짝수가 연속되며 * 를 추가하는 기능을 갖고 있다. DashInsert 함수를 완성하시오.

입력 예시 : 4546793
출력 예시 : 454*67-9-3

 

 

정답)

data = "4546793"

numbers = list(map(int,data))
result = []

for i, num in enumerate(numbers):
    result.append(str(num))
    if i<len(numbers)-1:
        is_odd = num%2==1
        is_next_odd = numbers[i+1]%2==1
        if is_odd and is_next_odd:
            result.append("-")
        elif not is_odd and not is_next_odd:
            result.append("*")

print("".join(result))

 


Q16. 모스 부호 해독

문자열 형식으로 입력받은 모스 부호(dot: . dash: -)를 해독하여 영어 문장으로 출력하는 프로그램을 작성하시오.

  • 글자와 글자 사이는 공백 1개, 단어와 단어 사이는 공백 2개로 구분한다.
  • 예를 들어 다음 모스 부호는 "HE SLEEPS EARLY" 로 
.... .  ... .-.. . . .--. ...  . .- .-. .-.. -.--

 

정답)

dic = {
    '.-':'A','-...':'B','-.-.':'C','-..':'D','.':'E','..-.':'F','--.':'G',
    '....':'H','..':'I','.---':'J','-.-':'K','.-..':'L',
    '--':'M','-.':'N','---':'O','.--.':'P','--.-':'Q','.-.':'R',
    '...':'S','-':'T','..-':'U','...-':'V','.--':'W','-..-':'X',
    '-.--':'Y','--..':'Z'
}

def morse(src):
    result = []
    for word in src.split("   "):
        for char in word.split(" "):
            result.append(dic[char])
        result.append(" ")
    return "".join(result)
    


print (morse('.... .  ... .-.. . . .--. ...  . .- .-. .-.. -.--'))

 

 


Q17. 기초 메타 문자

다음 중 정규식 a[.]{3,}b과 매치되는 문자열은 무엇일까?

1. acccb
2. a....b
3. aaab
4. a.cccb

 

정답)

import re

p = re.compile("a[.]{3,}b")

print(p.match("acccb"))
print(p.match("a....b"))
print(p.match("aaab"))
print(p.match("a.cccb"))

위 코드를 이용하여 확인해 보면 정답은 B인 것을 알 수 있다.

 


Q18. 문자열 검색

다음 코드의 결괏값은 무엇일까?

>>> import re
>>> p = re.compile("[a-z]+")
>>> m = p.search("5 python")
>>> m.start() + m.end()

 

정답)

import re

p = re.compile('[a-z]+')
m = p.search("5 python")
print(m.start() + m.end())

정규식 '[a-z]+' 은 소문자로 이루어진 단어를 뜻하므로 "5 python" 문자열에서 'python'과 매치될 것이다. 따라서 'python' 문자열의 시작 인덱스(m.start())는 2이고 마지막 인덱스(m.end())는 8이므로 10이 출력된다.

 

 


Q19. 그루핑

다음과 같은 문자열에서 휴대폰 번호 뒷자리인 숫자 4개를 ####로 바꾸는 프로그램을 정규식을 사용하여 작성하시오.

"""
park 010-9999-9998
kim 010-9909-7789
lee 010-8789-7768
"""

 

 

풀이)

전화번호 패턴은 다음과 같이 작성할 수 있다.

pat = re.compile("\d{3}[-]\d{4}[-]\d{4}")

이 전화번호 패턴 중 뒤의 숫자 4개를 변경할 것이므로 필요한 앞부분을 다음과 같이 그루핑한다.

pat = re.compile("(\d{3}[-]\d{4})[-]\d{4}")

컴파일된 객체 pat에 sub 함수를 사용하여 다음과 같이 문자열을 변경한다.

import re

s = """
park 010-9999-9998
kim 010-9909-7789
lee 010-8789-7768
"""

pat = re.compile("(\d{3}[-]\d{4})[-]\d{4}")
result = pat.sub("\g<1>-####",s)

print(result)

 

 


Q20. 전방 탐색

다음은 이메일 주소를 나타내는 정규식이다. 이 정규식은 park@naver.com, kim@daum.net, lee@myhome.co.kr 등과 매치된다. 긍정형 전방 탐색 기법을 사용하여 .com, .net이 아닌 이메일 주소는 제외시키는 정규식을 작성하시오.

.*[@].*[.].*$

 

풀이)

.com과 .net에 해당되는 이메일 주소만을 매치하기 위해서 이메일 주소의 도메인 부분에 다음과 같은 긍정형 전방탐색 패턴을 적용한다.

pat = re.compile(".*[@].*[.](?=com$|net$).*$")

다음은 위 패턴을 적용한 파이썬 코드이다.

import re

pat = re.compile(".*[@].*[.](?=com$|net$).*$")

print(pat.match("pahkey@gmail.com"))
print(pat.match("kim@daum.net"))
print(pat.match("lee@myhome.co.kr"))

 

 


 

정규식 부분은 깊게 들여다보지 않아서 문제들도 대부분 풀이 해설이다. 일단 이렇게 파이썬을 마무리하고, 다른 것들을 좀 보다가 다시 볼 때 정규식을 자세히 봐야겠다.

728x90
반응형
LIST