첫 강의부터 과제라 잠이 확 깰 수 있어서 좋았다.
최대한 코드를 파이써닉하게 작성해보고 싶어서 시간이 생각보다 많이 걸렸다.
for문을 지양하고 map, regex, comprehension 등을 활용해서 풀어보았다.
def is_help_command(user_input):
"""
Input:
- user_input : 문자열값으로 사용자가 입력하는 문자
Output:
- 입력한 값이 대소문자 구분없이 "H" 또는 "HELP"일 경우 True,
그렇지 않을 경우 False를 반환함
Examples:
>>> import morsecode as mc
>>> mc.is_help_command("H")
True
>>> mc.is_help_command("Help")
True
>>> mc.is_help_command("Half")
False
>>> mc.is_help_command("HeLp")
True
>>> mc.is_help_command("HELLO")
False
>>> mc.is_help_command("E")
False
"""
result = user_input.lower() in ['h', 'help']
return result
저번 과제의 is_yes or is_no 와 동일한 로직이다.
def is_validated_english_sentence(user_input):
"""
Input:
- user_input : 문자열값으로 사용자가 입력하는 문자
Output:
- 입력한 값이 아래에 해당될 경우 False, 그렇지 않으면 True
1) 숫자가 포함되어 있거나,
2) _@#$%^&*()-+=[]{}"';:\|`~ 와 같은 특수문자가 포함되어 있거나
3) 문장부호(.,!?)를 제외하면 입력값이 없거나 빈칸만 입력했을 경우
Examples:
>>> import morsecode as mc
>>> mc.is_validated_english_sentence("Hello 123")
False
>>> mc.is_validated_english_sentence("Hi!")
True
>>> mc.is_validated_english_sentence(".!.")
False
>>> mc.is_validated_english_sentence("!.!")
False
>>> mc.is_validated_english_sentence("kkkkk... ^^;")
False
>>> mc.is_validated_english_sentence("This is Gachon University.")
True
"""
result = re.fullmatch('[ .,!?]*', user_input)
if result != None:
return False
result = re.fullmatch('[ .,!?a-zA-Z]+', user_input)
if result == None:
return False
return True
정규표현식의 fullmatch를 사용해서 풀었다.
처음 써보는 문법이였는데, 문자열이 해당 정규식에 전부 매칭되는지 확인할 수 있다.
매칭이 되면 매칭 결과를 반환해주고, 되지 않는다면 None을 반환한다.
처음엔 3번 조건의 4개의 문장 부호로만 이루어진 경우인지 체크했다.
'*'를 사용했기 때문에 빈 문자열도 찾는다.
(처음에 공백을 넣지 않아 많은 시간을 날렸다. 다음부터 주의하자)
매칭이 성공한다면 False를 반환한다.
그 후로는 1,2번 조건을 함께 비교했다.
매칭이 되지 않는다면, False를 반환한다.
def is_validated_morse_code(user_input):
"""
Input:
- user_input : 문자열값으로 사용자가 입력하는 문자
Output:
- 입력한 값이 아래에 해당될 경우 False, 그렇지 않으면 True
1) "-","."," "외 다른 글자가 포함되어 있는 경우
2) get_morse_code_dict 함수에 정의된 Morse Code 부호외 다른 코드가 입력된 경우 ex)......
Examples:
>>> import morsecode as mc
>>> mc.is_validated_morse_code("..")
True
>>> mc.is_validated_morse_code("..-")
True
>>> mc.is_validated_morse_code("..-..")
False
>>> mc.is_validated_morse_code(". . . .")
True
>>> mc.is_validated_morse_code("-- -- -- --")
True
>>> mc.is_validated_morse_code("!.1 abc --")
False
"""
morse_code = get_morse_code_dict()
result = list(map(lambda x : x in morse_code.values(), user_input.split()))
return all(result)
우선 morse_code에 제공된 dictionary를 받아왔다.
그리고 user_input을 공백으로 나누었다.
이 후 map과 lambda 함수를 활용하여 값들이 morse_code의 value에 들어있는지 확인해주었다.
모든 값들이 들어있으면 True를 반환하면 되기 때문에, all을 사용해주었다.
def get_cleaned_english_sentence(raw_english_sentence):
"""
Input:
- raw_english_sentence : 문자열값으로 Morse Code로 변환 가능한 영어 문장
Output:
- 입력된 영어문장에수 4개의 문장부호를 ".,!?" 삭제하고, 양쪽끝 여백을 제거한 문자열 값 반환
Examples:
>>> import morsecode as mc
>>> mc.get_cleaned_english_sentence("This is Gachon!!")
'This is Gachon'
>>> mc.get_cleaned_english_sentence("Is this Gachon?")
'Is this Gachon'
>>> mc.get_cleaned_english_sentence("How are you?")
'How are you'
>>> mc.get_cleaned_english_sentence("Fine, Thank you. and you?")
'Fine Thank you and you'
"""
result = raw_english_sentence.strip()
result = re.sub('[.,!?]', '', result)
result = re.sub(' +', ' ', result)
return result
처음으로 좌우의 공백을 제거해준다.
그리고 정규표현식을 사용하여 문장 부호들을 삭제해준다.
마지막으로 2개 이상의 공백들을 공백 하나로 바꿔준다.
def decoding_character(morse_character):
"""
Input:
- morse_character : 문자열값으로 get_morse_code_dict 함수로 알파벳으로 치환이 가능한 값의 입력이 보장됨
Output:
- Morse Code를 알파벳으로 치환함 값
Examples:
>>> import morsecode as mc
>>> mc.decoding_character("-")
'T'
>>> mc.decoding_character(".")
'E'
>>> mc.decoding_character(".-")
'A'
>>> mc.decoding_character("...")
'S'
>>> mc.decoding_character("....")
'H'
>>> mc.decoding_character("-.-")
'K'
"""
inv_morse_code_dict = { v : k for k, v in get_morse_code_dict().items() }
inv_morse_code_dict["DS"] = " "
result = inv_morse_code_dict[morse_character]
return result
제공된 morse_code_dict의 key, value값을 바꾸어서 inv 상태로 만들어주었다.
그리고, 공백 2개를 표현해놓은 DS를 공백으로 바꿔주었다.(하단 decoding_sentence 참고)
이 후, inv_morse_code_dict에서 key값으로 value를 반환해주면 된다.
def encoding_character(english_character):
"""
Input:
- english_character : 문자열값으로 알파벳 한 글자의 입력이 보장됨
Output:
- get_morse_code_dict 함수의 반환 값으로 인해 변환된 모스부호 문자열값
Examples:
>>> import morsecode as mc
>>> mc.encoding_character("G")
'--.'
>>> mc.encoding_character("A")
'.-'
>>> mc.encoding_character("C")
'-.-.'
>>> mc.encoding_character("H")
'....'
>>> mc.encoding_character("O")
'---'
>>> mc.encoding_character("N")
'-.'
"""
morse_code_dict = get_morse_code_dict()
morse_code_dict[" "] = ""
result = morse_code_dict[english_character.upper()]
return result
제공된 morse_code_dict를 저장했다.
그리고, ' '를 ''으로 바꿔주었다.(하단 encoding_sentence 참고)
이 후, morse_code_dict에서 key값으로 value를 반환해주면 된다.
def decoding_sentence(morse_sentence):
"""
Input:
- morse_sentence : 문자열 값으로 모스 부호를 표현하는 문자열
Output:
- 모스부호를 알파벳으로 변환한 문자열
Examples:
>>> import morsecode as mc
>>> mc.decoding_sentence("... --- ...")
'SOS'
>>> mc.decoding_sentence("--. .- -.-. .... --- -.")
'GACHON'
>>> mc.decoding_sentence(".. .-.. --- ...- . -.-- --- ..-")
'I LOVE YOU'
>>> mc.decoding_sentence("-.-- --- ..- .- .-. . ..-. ")
'YOU ARE F'
"""
conv_morse_sentence = re.sub(' ', ' DS ', morse_sentence)
result = list(map(decoding_character, conv_morse_sentence.split()))
return ''.join(result)
모스 부호가 들어오는데 split으로 구분을 해주기 위해서, 공백 2개는 따로 분류해야한다.
그래서 DS(Double Space)로 바꿔줘서 전처리 작업을 해주었다.
이 후에는 만들어 놓은 decoding_character 함수를 활용해서 각 문자열들을 알파벳 값으로 바꿔 주었다.
이것이 list 형태로 저장되는데, ''.join 구문을 이용해서 문자열로 반환해주었다.
def encoding_sentence(english_sentence):
"""
Input:
- english_sentence : 문자열 값으로 모스 부호로 변환이 가능한 영어문장
Output:
- 입력된 영어문장 문자열 값을 모스부호로 변환된 알파벳으로 변환한 문자열
단 양쪽 끝에 빈칸은 삭제한다.
Examples:
>>> import morsecode as mc
>>> mc.encoding_sentence("HI! Fine, Thank you.")
'.... .. ..-. .. -. . - .... .- -. -.- -.-- --- ..-'
>>> mc.encoding_sentence("Hello! This is CS fifty Class.")
'.... . .-.. .-.. --- - .... .. ... .. ... -.-. ... ..-. .. ..-. - -.-- -.-. .-.. .- ... ...'
>>> mc.encoding_sentence("We Are Gachon")
'.-- . .- .-. . --. .- -.-. .... --- -.'
>>> mc.encoding_sentence("Hi! Hi!")
'.... .. .... ..'
"""
cleaned_sentence = get_cleaned_english_sentence(english_sentence)
result = list(map(encoding_character, cleaned_sentence))
return ' '.join(result)
들어온 english_sentence를 get_cleaned_english_sentence를 사용하여 전처리를 했다.
만들어진 cleaned_sentece를 map을 사용하여 하나씩 encoding_character 해주었다.
완성된 list에 ' '.join을 하여 문자열로 반환해주었다.
상단에서, 공백은 빈 문자열로 바뀌게 설정을 해놓았다.
따라서, '' 왼쪽 오른쪽에 join으로 공백이 하나씩 들어와서
기존 공백 하나는 공백 두개로 대체될 수 있다.
def main():
print("Morse Code Program!!")
# ===Modify codes below=============
while True:
user_input = input("Input your message(H - Help, 0 - Exit): ")
if user_input == '0':
break
if is_help_command(user_input):
print(get_help_message())
continue
if is_validated_english_sentence(user_input):
print(encoding_sentence(user_input))
elif is_validated_morse_code(user_input):
print(decoding_sentence(user_input))
else:
print("Wrong Input")
while문에서 입력을 계속 받는다.
사용자가 0을 입력을 하면, 프로그램을 종료한다.
사용자가 H or Help를 입력하면 help message를 출력한다.
그리고 encoding or decoding이 가능한 문자열이라면 해당 작업을 해준다.
그렇지 않은 경우에는 Wrong Input을 출력한다.
첫날에 배웠듯이, 파이썬은 객체지향 프로그래밍이다.
OOP는 프로그래밍 언어를 배우는 데 있어서 매우 중요한 개념이다.
고난이도 프로그래밍을 위한 길로 생각하고 항상 생각하며 코딩하는 습관을 가지자.
마지막의 decorate는 공부가 많이 필요할 것 같다.
class SoccerPlayer(object): # class 기본 선언
함수의 정의와 거의 동일하다.
class 예약어 + class 이름 + (상속받는 객체명) :
변수와 Class명 함수명은 짓는 방식이 존재한다.
Attribute 추가는 __init__, self와 함께 사용한다.
여기서 init는 객체 초기화 예약 함수이다.
class SoccerPlayer(object):
def __init__(self, name, position, back_number):
self.name = name
self.position = position
self.back_number = back_number
def __str__(self): # print문 사용 가능
return f"Hello, {self.position} {self.name}."
SHM = SoccerPlayer('son', 'FW', 7) # instance 생성
print(SHM)
# Hello, FW son. 출력
⭐️ '__'의 의미
클래스 변수는 모든 인스턴스가 공유하는 변수이다.
class Person:
cnt = 0 # 클래스 변수
def __init__(self, name):
self.name = name # 인스턴스 변수
Person.cnt += 1
def __del__(self):
Person.cnt -= 1
>>> a = Person('kim')
>>> print(a.cnt, a.name)
1 kim
>>> b = Person('lee')
>>> print(b.cnt, b.name)
2 lee
>>> print(a.cnt, a.name)
2 kim
method 추가는 기존 함수와 같으나, 반드시 self를 추가해야 class 함수로 인정된다.
class SoccerPlayer(object):
def change_back_number(self, new_number):
self.back_number = new_number
⭐️ self는 생성된 인스턴스 자신을 의미한다.
부모클래스로부터 속성과 method를 물려받은 자식 클래스를 생성하는 것
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
class Korean(Person):
def __init__(self, name, age, location): # 부모객체를 사용할 수 있다.
super().__init__(name, age)
self.location = location
first_korean = Korean("Gyuho", 26, "Suwon")
print(first_korean.name)
# Gyuho 출력
class Animal:
def __init__(self, name):
self.name = name
def talk(self): # 다형성 예시 함수
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof!!'
객체의 정보를 볼 수 있는 레벨을 조절하는 것. 변수에 '__'을 앞에 붙여서 사용한다.
@property를 앞에 붙여 return 하면 함수명을 변수처럼 쓸 수 있다.
⭐️ Encapsulation
파이썬의 함수는 일급 함수이다.
def square(x):
return x * x
def formula(method, argument_list): # 이런 식으로도 사용 가능하다.
return [method(value) for value in argument_list]
>>> f = square # 이것을 의미
>>> f(5)
25
함수 내에 또 다른 함수가 존재하는 것이다.
def print_msg(msg):
def printer():
print(msg)
printer()
⭐️ closures : inner function을 return 값으로 반환
def print_msg(msg):
def printer():
print(msg)
return printer
⭐️ decorator function : 복잡한 클로져 함수를 간단하게 만들어준다.
def star(func):
def inner(*args, **kwargs):
print('*' * 30)
func(*args, **kwargs)
print('*' * 30)
return inner
@star # 이 함수가 start의 func에 들어간다.
def printer(msg):
print(msg)
printer('hello')
다양한 파이썬 패키지들을 사용해본 경험이 있지만
이렇게 이론적인 부분을 배운 것은 처음이였다.
무엇이든지 기본이 가장 중요한 것 같다.
배운 내용을 잘 학습해 완성도 있는 프로젝트를 만들자.
프로그램에서는 작은 프로그램 조각들을 의미한다.
모듈들을 모아서 하나의 큰 프로그램을 개발한다.
프로그램을 모듈화 시키면 다른 프로그램이 사용하기 쉽다.
파이썬에서의 모듈은 py 파일을 의미한다.
같은 폴더에 Mdodule에 해당하는 .py 파일과 사용하는 .py을 저장한다.
이 후 import 문을 사용해서 module을 호출할 수 있다.
# fah_converter.py (모듈화)
def convert_c_to_f(celcius_value):
return celcius_value * 9.0 / 5 + 32
# module_ex.py
>>> import fah_converter # 불러오기. 해당 py의 모든 코드가 메모리에 로딩된다.
>>>
>>> print(fah_converter.convert_c_to_f(5))
41
from queue import priorityqueue # namespace 예시
import numpy as np # Alias 예시
import random # 난수
print(random.randint(0, 100)) # 0~100 사이의 정수 난수 생성
print(random.random()) # 일반적인 난수 생성
import time # 시간
print(time.localtime()) # 현재 시간 출력
import urllib.request # 웹
response = urllib.request.urlopen('http://thetemlab.io')
print(response.read())
구글링으로 다양한 모듈들을 알아보자.
# sound/__init__.py
__all__ = ['echo', 'bgm']
from . import echo
from . import bgm
'.'는 현재 directory 기준, '..'은 부모 directory 기준을 의미한다.
(base) λ conda create -n my_project python=3.8 # 설치
(base) λ conda activate my_project # 호출
(my_project) λ conda install numpy # 모듈 설치
(my_project) λ conda deactivate # 해제