9/21 오늘의 시간표
09:00 ~ 10:00 [원격] 자료구조와 알고리즘
10:00 ~ 11:00 [원격] 자료구조와 알고리즘
11:00 ~ 12:00 [원격] 자료구조와 알고리즘
12:00 ~ 13:00 [원격] 자료구조와 알고리즘
13:00 ~ 14:00 점심식사
14:00 ~ 15:00 [원격] 자료구조와 알고리즘
15:00 ~ 16:00 [원격] 자료구조와 알고리즘
16:00 ~ 17:00 [원격] 자료구조와 알고리즘
17:00 ~ 18:00 [원격] 자료구조와 알고리즘
18:00 ~ 19:00 저녁식사
19:00 ~ 20:00 [실습] 실무적용 알고리즘 실습
20:00 ~ 21:00 [실습] 실무적용 알고리즘 실습
자료구조와 알고리즘 시간표 편성 마지막날이다. 오늘이 지나면 이제 팀도 바뀌고 새롭게 장고에 대해 배우는 시간을 갖게 되기 때문에 사실상 오늘이 파이썬 문법을 공부하는 마지막날이 되는 것이다. 지금의 나는 파이썬 문법에 대해 충분히 이해하고 따라갈 수 있지만 막상 스스로 해야하는 상황이오면 아직은 헤메이는 부분이 있는 것 같다. 물론 거북이반 수업을 들으며 많이 나아진 편이지만 솔직히 혼자 해보라고 한다면 아직은 조금 무섭다. 경험이 부족해 겁을 많이 먹고 있어 그런 것도 있겠지만 역시 일단은 오늘까지 확실하게 복습하며 다시 한번 확실히 짚고가는 수 밖에는 없으니 복습을 제대로 해봐야겠다.
자료구조와 알고리즘 원격강의
-> 파이썬 문법 복습
오늘도 과감하게 알고리즘 원격강의보다 파이썬에 시간을 투자하는 방향으로 결정했고 오늘은 역시 지금까지 배운 것을 최종적으로 되짚는 시간이 필요하다고 생각했다.
ex)
print(len("abcde")) # 5
print(len("Hello, Sparta!")) # 14
print(len("안녕하세요.")) # 6
ex)
a = [1, 5, 2]
print(len(a)) # 3
b = [1, 3, [2, 0], 1]
print(len(b)) # 4
ex)
a = [1, 2, [2, 3], 0]
print(a[2]) # [2, 3]
print(a[2][0]) # 2
ex)
person = {"name":"Bob", "age": 21}
print(person["name"])
ex)
person = {"name":"Bob", "age": 21}
person["name"] = "Robert"
print(person) # {'name': 'Robert', 'age': 21}
person["height"] = 174.8
print(person) # {'name': 'Robert', 'age': 21, 'height': 174.8}
ex)
person = {"name":"Alice", "age": 16, "scores": {"math": 81, "science": 92, "Korean": 84}}
print(person["scores"]) # {'math': 81, 'science': 92, 'Korean': 84}
print(person["scores"]["science"]) # 92
ex)
age = 27
if age < 20:
print("청소년입니다.")
elif age < 65:
print("성인입니다.")
else:
print("무료로 이용하세요!")
for문
fruits = ['사과', '배', '감', '귤']
for fruit in fruits:
print(fruit) # 사과,배,감,귤
함수선언 : def 함수명(매개변수):
<수행할 문장1>
<수행할 문장2>
def check_gender(pin):
num = int(pin.split('-')[1][0])
if num % 2 == 0:
print('여성')
else:
print('남성')
my_pin = "200101-3012345"
check_gender(my_pin)
결과값 : 남성
ex)
scores = [
{'name':'영수','score':70},
{'name':'영희','score':65},
{'name':'기찬','score':75},
{'name':'희수','score':23},
{'name':'서경','score':99},
{'name':'미주','score':100},
{'name':'병태','score':32}
]
for s in scores:
name = s['name']
score = str(s['score'])
print(f'{name}은 {score}점입니다')
ex)
a_list = [1, 3, 2, 5, 1, 2]
b_list = []
for a in a_list:
b_list.append(a*2)
print(b_list)
a_list = [1, 3, 2, 5, 1, 2]
b_list = [a*2 for a in a_list]
print(b_list)
ex)
def check_adult(person):
if person['age'] > 20:
return '성인'
else:
return '청소년'
result = map(check_adult, people)
print(list(result))
def check_adult(person):
return '성인' if person['age'] > 20 else '청소년'
result = map(check_adult, people)
print(list(result))
result = map(lambda x: ('성인' if x['age'] > 20 else '청소년'), people)
print(list(result))
ex)
filter :
result = filter(lambda x: x['age'] > 20, people)
print(list(result))
get_kwargs(name='bob')
get_kwargs(name='john', age='27')
ex)
class Monster():
hp = 100
alive = True
def damage(self, attack):
self.hp = self.hp - attack
if self.hp < 0:
self.alive = False
def status_check(self):
if self.alive:
print('살아있다')
else:
print('죽었다')
>
m = Monster()
m.damage(120)
m2 = Monster()
m2.damage(90)
m.status_check()
m2.status_check()
코드 컨벤션이란 코드를 개발하다보면 타인이 작성한 코드를 알아 볼 수 없는 경우가 빈번하게 발생하기 때문에 이를 방지하기 위해 스타일을 통일하는 '약속' 같은 것이다. 코드 컨벤션은 개발하는 언어에 따라서 다르기 때문에 본인이 개발에 사용하는 언어에 따라 코드 컨벤션의 스타일도 바뀌는 것에 유의해야 한다.
파이썬에서는 네이밍 컨벤션으로 변수 / 함수를 네이밍할 때는 Snake 표기법을, Class를 네이밍할 때는 Pascal 표기법을 사용한다.
Pascal 표기법은 각 단어를 대문자로 구분하는 표기법이고(PythonIsVeryGood)
Snake 표기법은 각 단어를 언더바(_)로 구분하는 표기법이다.(python_is_very_good)
선언할 변수 명 = 변수에 넣고 싶은 값
과 같은 형태로 변수를 선언할 수 있습니다.description = “변수를 선언 하는 방법입니다.”
a, b, c = 1, 2, 3
list_ = [1,2,3,4]
number = 10
과 같이 사용되며, 정수 자료형이기 때문에 소수점은 지원하지 않습니다.number = 10.3
과 같이 사용되며, 소수점을 지원합니다.hello = "world!!"
와 같이 사용되며, 변수에 문자를 저장할 수 있습니다.numbers = [1, 2, 3, 4, 5]
와 같이 사용되며 1개 이상의 값을 한 변수에 담아 사용할 수 있습니다.numbers = (1, 2, 3 ,4, 5)
와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.numbers = {1, 2, 3, 4, 5}
와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.members = {”1”: “lee”, “2”: “park”, “3”: “kim”}
과 같이 사용되며 {key: value} 쌍으로 이루어져 있습니다.flag = True
와 같이 사용되며 True 혹은 False 두 값만 사용할 수 있습니다.사칙연산
# num에 정수를 할당하고, 할당된 값에 1을 더하고 싶을 때
# case 1
num = 10
num = num + 1
# result: 11
# case 2
num = 10
num += 1
# result: 11
# case 1, 2 모두 동일한 동작을 하고 동일한 결과를 내는 수식이다.
# 이와 같은 축약식은 + 이외에 다른 수식에서도 사용할 수 있다.
num -= 3 # num = num - 3
num *= 3 # num = num * 3
num **= 3 # num = num ** 3
num /= 3 # num = num / 3
num //= 3 # num = num // 3
num %= 3 # num = num % 3
string
list
tuple
set
dictionary(중요!!)
def 함수명():
과 같은 형태로 선언할 수 있다.class란?
- 인스턴스(instance) : class를 사용해 생성된 객체
- 메소드(method) : 메소드란 클래스 내에 선언된 함수이며, 클래스 함수라고도 한다.
- self : 메소드를 선언할 때에는 항상 첫번째 인자로 self를 넣어줘야 한다.
클래스 안에 있는 변수나 함수 정보를 담고 있다.
class CookieFrame(): # CookieFrame이라는 이름의 class 선언
def set_cookie_name(self, name):
self.name = name
cookie1 = CookieFrame()
cookie2 = CookieFrame()
cookie1.set_cookie_name("cookie1") # 메소드의 첫 번째 인자 self는 무시된다.
cookie2.set_cookie_name("cookie2")
print(cookie1.name) # cookie1
print(cookie2.name) # cookie2
__init__
함수# class에 __init__메소드를 사용할 경우 인스턴스 생성 시 해당 메소드가 실행된다.
class CookieFrame():
def __init__(self, name):
print(f"생성 된 과자의 이름은 {name} 입니다!")
self.name = name
cookie1 = CookieFrame("cookie1") # 생성 된 과자의 이름은 cookie1 입니다!
cookie2 = CookieFrame("cookie2") # 생성 된 과자의 이름은 cookie2 입니다!
muteble은 값이 변한다는 의미이며, immutable은 값이 변하지 않는다는 의미이다.
int, str, list 등 자료형은 각각 muteble 혹은 immuteble한 속성을 가지고 있다.
a = 10
b = a
b += 5
와 같은 코드가 있을 때 a에 담긴 자료형이 muteble 속성인지 immuteble 속성인지에 따라
출력했을 때 결과가 달라지게 된다.
immutable = "String is immutable!!"
mutable = ["list is mutable!!"]
string = immutable
list_ = mutable
string += " immutable string!!"
list_.append("mutable list!!")
print(immutable)
print(mutable)
print(string)
print(list_)
# result print
"""
String is immutable!!
['list is mutable!!', 'mutable list!!']
String is immutable!! immutable string!!
['list is mutable!!', 'mutable list!!']
"""
number = "num"
try: # try 구문 안에서 에러가 발생할 경우 except로 넘어감
number = int(number) # "num"을 숫자로 바꾸는 과정에서 에러 발생
except: # 에러가 발생했을 때 처리
print(f"{number}은(는) 숫자가 아닙니다.")
number = input()
try:
int(number)
10 / number
except ValueError: # int로 변환하는 과정에서 에러가 발생했을 떄
print(f"{number}은(는) 숫자가 아닙니다.")
except ZeroDivisionError: # 0으로 나누면서 에러가 발생했을 때
print("0으로는 나눌수 없습니다.")
except Exception as e: # 위에서 정의하지 않은 에러가 발생했을 때(권장하지 않음)
print(f"예상하지 못한 에러가 발생했습니다. error : {e}")
# except 문법 또한 if / elif와 같이 연달아서 작성할 수 있습니다.
stacktrace는 python 뿐만이 아닌 대부분의 개발 언어에서 사용되는 개념이다.
에러가 발생했을 때 에러가 발생 한 위치를 찾아내기 위해 호출 된 함수의 목록을 보여주고 개발자는 stacktrace를 따라가며 에러가 발생한 위치를 추적할 수 있다.
def 집까지_걸어가기():
print(error) # 선언되지 않은 변수를 호출했기 때문에 에러 발생
def 버스_탑승():
집까지_걸어가기()
def 환승():
버스_탑승()
def 지하철_탑승():
환승()
def 퇴근하기():
지하철_탑승()
퇴근하기()
"""
Traceback (most recent call last):
File "sample.py", line 17, in <module>
퇴근하기()
File "sample.py", line 15, in 퇴근하기
지하철_탑승()
File "sample.py", line 12, in 지하철_탑승
환승()
File "sample.py", line 9, in 환승
버스_탑승()
File "sample.py", line 5, in 버스_탑승
집까지_걸어가기()
File "sample.py", line 2, in 집까지_걸어가기
print(error)
NameError: name 'error' is not defined. Did you mean: 'OSError'?
"""
축약식은 긴 코드를 간략하게 줄일수 있다는 장점이 있지만, 남용할 경우 가독성이
떨어지고 추후 코드 관리가 힘들수 있기 때문에 필요할 때만 사용하는 것을 권장합니다.
list, set, tuple, dict 자료형이 축약식을 지원합니다.
기본적인 구조는 똑같으며, 어떤 괄호 기호를 사용하는지 / 어떤 형태로 사용하는지에
따라 저장되는 자료형이 달라집니다.
축약식은 모두 동일한 구조를 가지고 있기 때문에 한 가지 자료형에 익숙해지면 다른
자료형에도 적용해서 사용할 수 있습니다.
# 기본적인 활용 방법
# [list에 담길 값 for 요소 in 리스트]
numbers = [x for x in range(5)] # [0, 1, 2, 3, 4]
# 조건문은 축약식 뒷부분에 작성하며, 축약식이 True인 경우 list에 값이 담긴다.
even_numbers = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# 아래와 같이 활용할 수도 있다.
people = [
("lee", 32),
("kim", 23),
("park", 27),
("hong", 29),
("kang", 26)
]
average_age = sum([x[1] for x in people]) / len(people)
print(average_age) # 27.4
#list 축약식의 []를 ()혹은 {}로 바꿔주면 tuple, set 축약식을 사용하실수 있습니다.
# dictionary 축약식의 구조는 list와 동일하지만, key / value 형태로 지정해야 합니다.
people = [
("lee", 32, "man"),
("kim", 23, "man"),
("park", 27, "woman"),
("hong", 29, "man"),
("kang", 26, "woman")
]
people = {name: {"age": age, "gender": gender} for name, age, gender in people}
print(people)
# result print
"""
{
'lee': {'age': 32,
'gender': 'man'},
'kim': {'age': 23,
'gender': 'man'},
'park': {'age': 27,
'gender': 'woman'},
'hong': {'age': 29,
'gender': 'man'},
'kang': {'age': 26,
'gender': 'woman'}
}
"""
python에서 lambda 함수는 다른 말로 익명 함수(anonymous function)라고도 불립니다.
lambda 함수는 주로 map / filter / sort 함수와 함께 사용됩니다.
# map은 함수와 리스트를 인자로 받아 리스트의 요소들로 함수를 호출해줍니다.
string_numbers = ["1", "2", "3"]
integer_numbers = list(map(int, string_numbers))
print(integer_numbers) # [1, 2, 3]
# map 함수를 사용하지 않는 경우 아래와 같이 구현할 수 있습니다.
string_numbers = ["1", "2", "3"]
integer_numbers = []
for i in string_numbers:
integer_numbers.append(int(i))
print(integer_numbers) # [1, 2, 3]
# list 축약식으로도 동일한 기능을 구현할 수 있습니다.
# map과 list 축약식 중 어떤걸 써야 할지 고민된다면 [이 글](https://stackoverflow.com/questions/1247486/list-comprehension-vs-map?answertab=scoredesc#tab-top)을 읽어보시는것을 추천합니다.
string_numbers = ["1", "2", "3"]
integer_numbers = [int(x) for x in string_numbers]
print(integer_numbers) # [1, 2, 3]
# map 함수와 lambda 함수를 함께 사용하면 더 다채로운 기능을 구현할 수 있습니다.
numbers = [1, 2, 3, 4]
double_numbers = list(map(lambda x: x*2, numbers))
print(double_numbers) # [2, 4, 6, 8]
# filter 함수는 map과 유사한 구조를 가지고 있으며, 조건이 참인 경우 저장합니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = list(filter(lambda x: x%2 == 0, numbers))
print(even_numbers) # [2, 4, 6, 8]
# filter 함수 또한 list 축약식으로 동일한 기능을 구현할 수 있습니다.
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
even_numbers = [x for x in numbers if x%2 == 0]
print(even_numbers) # [2, 4, 6, 8]
# sort 함수를 사용하면 list를 순서대로 정렬할 수 있습니다.
numbers = [5, 3, 2, 4, 6, 1]
numbers.sort()
print(numbers) # [1, 2, 3, 4, 5, 6]
# sort와 lambda 함수를 같이 사용하면 복잡한 구조의 list도 정렬할 수 있습니다.
people = [
("lee", 32),
("kim", 23),
("park", 27),
("hong", 29),
("kang", 26)
]
# 나이 순으로 정렬하기
people.sort(key=lambda x: x[1])
print(people)
# result print
"""
[
("kim", 23),
("kang", 26),
("park", 27),
("hong", 29),
("lee", 32)
]
# 함수를 선언할 때 인자에 기본값을 지정해줄 수 있다.
EXPRESSION = {
0: lambda x, y: x + y ,
1: lambda x, y: x - y ,
2: lambda x, y: x * y ,
3: lambda x, y: x / y
}
def calc(num1, num2, option=None): # 인자로 option이 들어오지 않는 경우 기본값 할당
"""
option
- 0: 더하기
- 1: 빼기
- 2: 곱하기
- 3: 나누기
"""
return EXPRESSION[option](num1, num2) if option in EXPRESSION.keys() else False
print(calc(10, 20)) # False
print(calc(10, 20, 0)) # 30
print(calc(10, 20, 1)) # -10
print(calc(10, 20, 2)) # 200
print(calc(10, 20, 3)) # 0.5
args(arguments)와 keyword arguments(kwargs)는 함수에서 인자로 받을 값들의 갯수가
불규칙하거나 많을 때 주로 사용된다.
인자로 받을 값이 정해져있지 않기 때문에 함수를 더 동적으로 사용할 수 있다.
함수를 선언할 때 args는 앞에 *를 붙여 명시하고, kwargs는 앞에 **를 붙여 명시한다.
def add(*args):
# args = (1, 2, 3, 4)
result = 0
for i in args:
result += i
return result
print(add()) # 0
print(add(1, 2, 3)) # 6
print(add(1, 2, 3, 4)) # 10
def set_profile(**kwargs):
"""
kwargs = {
name: "lee",
gender: "man",
age: 32,
birthday: "01/01",
email: "python@sparta.com"
}
"""
profile = {}
profile["name"] = kwargs.get("name", "-")
profile["gender"] = kwargs.get("gender", "-")
profile["birthday"] = kwargs.get("birthday", "-")
profile["age"] = kwargs.get("age", "-")
profile["phone"] = kwargs.get("phone", "-")
profile["email"] = kwargs.get("email", "-")
return profile
profile = set_profile(
name="lee",
gender="man",
age=32,
birthday="01/01",
email="python@sparta.com",
)
print(profile)
# result print
"""
{
'name': 'lee',
'gender': 'man',
'birthday': '01/01',
'age': 32,
'phone': '-',
'email': 'python@sparta.com'
}
"""
def print_arguments(a, b, *args, **kwargs):
print(a)
print(b)
print(args)
print(kwargs)
print_arguments(
1, # a
2, # b
3, 4, 5, 6, # args
hello="world", keyword="argument" # kwargs
)
# result print
"""
1
2
(3, 4, 5, 6)
{'hello': 'hello', 'world': 'world'}
"""
패킹(packing)과 언패킹(unpacking)은 단어의 뜻 그대로 요소들을 묶어주거나 풀어주는
것을 의미한다.
list 혹은 dictionary의 값을 함수에 입력할 때 주로 사용된다.
def add(*args):
result = 0
for i in args:
result += i
return result
numbers = [1, 2, 3, 4]
print(add(*numbers)) # 10
"""아래 코드와 동일
print(add(1, 2, 3, 4))
"""
def set_profile(**kwargs):
profile = {}
profile["name"] = kwargs.get("name", "-")
profile["gender"] = kwargs.get("gender", "-")
profile["birthday"] = kwargs.get("birthday", "-")
profile["age"] = kwargs.get("age", "-")
profile["phone"] = kwargs.get("phone", "-")
profile["email"] = kwargs.get("email", "-")
return profile
user_profile = {
"name": "lee",
"gender": "man",
"age": 32,
"birthday": "01/01",
"email": "python@sparta.com",
}
print(set_profile(**user_profile))
""" 아래 코드와 동일
profile = set_profile(
name="lee",
gender="man",
age=32,
birthday="01/01",
email="python@sparta.com",
)
"""
# result print
"""
{
'name': 'lee',
'gender': 'man',
'birthday': '01/01',
'age': 32,
'phone': '-',
'email': 'python@sparta.com'
}
"""
객체지향이란 객체를 모델링하는 방향으로 코드를 작성하는 것을 의미한다.
영어로는 Object-Oriented Programming이라고 하며 앞자를 따 OOP라고 불린다.
파이썬 뿐만이 아닌, 다양한 언어들에서 프로젝트를 개발하며 사용되는
개발 방식 중 하나다.
import re
# 숫자, 알파벳으로 시작하고 중간에 - 혹은 _가 포함될 수 있으며 숫자, 알파벳으로 끝나야 한다.
# @
# 알파벳, 숫자로 시작해야 하며 . 뒤에 2자의 알파벳이 와야 한다.
email_regex = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
class Attendance:
count = 0
def attendance(self):
self.count += 1
@property
def attendance_count(self):
return self.count
class Profile(Attendance):
def __init__(self, name, age, email):
self.__name = name # __를 붙여주면 class 내부에서만 사용하겠다는 뜻
self.__age = age
self.__email = email
@property # 읽기 전용 속성
def name(self):
return self.__name
@name.setter # 쓰기 전용 속성
def name(self, name):
if isinstance(name, str) and len(name) >= 2:
print("이름은 2자 이상 문자만 입력 가능합니다.")
else:
self.__name = name
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if isinstance(age, int):
self.__age = age
else:
print("나이에는 숫자만 입력 가능합니다.")
@property
def email(self):
return self.__email
@email.setter
def email(self, email):
if re.fullmatch(email_regex, email):
self.__email = email
else:
print("유효하지 않은 이메일입니다.")
def attendance(self): # override
super().attendance() # 부모 메소드 사용하기
self.count += 1
def __str__(self):
return f"{self.__name} / {self.__age}"
def __repr__(self):
return f"{self.__name}"
그동안 들었던 모든 파이썬 원격&실시간 강의의 요약본들을 모아보았다. 이렇게 잔뜩 적어두었지만 막상 공부할 때는 한번씩 읽고 이런 내용이었지 하고 넘어가서 금방 끝나는 시간이었지만 알찬 시간이었고 이렇게 한번에 요약해 둔걸로 나중에 찾아볼 일이 있으면 여기서 한번에 볼 수 있으니 편하고 좋은 것 같다.
그러고 나서는 오늘 거북이반에서 배울 내용과 어제 수업에서 튜터님이 내주신 과제풀이에 힘썼다.
먼저 오늘의 과제는 원의 넓이를 구하는 클래스 함수를 만드는 것이었다.
class Circle:
pi = 3.14
def __init__(self, radius):
self.radius = radius
def getArea(self):
return self.radius * self.radius * self.pi
def getCircumference(self):
return self.radius * self.pi * 2
c = Circle(5)
print("반지름은 : ", c.radius)
print("넓이는 : ", c.getArea())
print("둘레는 : ", c.getCircumference())
# getArea라는 메소드를 클래스 안에서 만들고, 6번줄은 지워주세요
# 6번줄의 기능을 getArea라는 메소드에서 할수있게끔 로직을 만들어주시고
# 15번줄도 수정해서 getArea라는 메소드를 통해서 넓이를 print 할 수 있게 수정해주세요!
Circle이라는 클래스 안에 3개의 메소드를 만들고 각각 반지름을 등록, 원의 넓이, 원의 둘레를 구하도록 했다.
거북이반
오늘 거북이반은 클래스 강의를 마무리하는 시간을 가졌다.
오늘 할 일을 마치며
좋던 싫던 오늘이 파이썬 문법을 졸업하게 되는 날이다. 정말 열심히 공부했지만 공부를 아무리 해도 부족한 느낌이라 걱정이 앞선다. 내일부터 시작될 장고는 내가 앞으로 취업하게될 경우 사용하게 될 주 무기이기 때문에 학습의 중요도는 더 올라갈 것이다. 빨리 장고를 배우고싶은 마음 반 두려움 반이라서 앞으로가 어떻게 될지 알 수 없는 것이 매우 재미있다.