■ JITHub 개발일지(TIL : Today I Learned) 10일차
□ TIL ::
파이썬 주요 문법, 클래스(계산기, 도형넓이, 프로필), mutable/immutable, 숫자야구
1. 클래스 기본 개념
- 클래스를 선언하는것은 과자 틀을 만드는 것
: 선언된 과자틀(class)로 과자(instance)를 만드는 것으로 자주 비유되기도 한다.
- 클래스는 인스턴스를 생성하여 사용한다. (*함수의 경우 선언 후 바로 사용)
- class 내부에 선언되는 메소드는 기본적으로 self라는 인자를 갖고 있으며 self는 전역변수의 속성을 가지고 있다.
*용어
- 인스턴스(instance) : class를 사용해 생성된 객체을 말한다.
- 메소드(method) : 메소드란 클래스 내에 선언된 함수이며, 클래스 함수라고도 한다.
- self : 메소드를 선언할 때에는 항상 첫번째 인자로 self를 넣어줘야 한다.
2. 클래스를 사용한 도형 넓이 계산기 (Area calculator)
# 도형 넓이 계산기
import math
class Area:
def __init__(self, a, b):
print("**도형 넓이 계산기**")
self.a = a
self.b = b
def square(self):
area = self.a * self.b
return area
def triangle(self):
area = self.a * self.b / 2
return area
def circle(self):
area = math.pi *(self.a**2)
return area
area = Area(10, 20)
print(area.square()) # 사각형의 넓이
print(area.triangle()) # 삼각형의 넓이
print(area.circle()) # 원의 넓이
3. 클래스를 사용한 계산기 (Calculator)
# 계산기 만들어보기(with class)
class Calc:
# def __init__(self, a, b):
# self.a = a
# self.b = b
def set_number(self, a, b):
self.a = a
self.b = b
def plus(self):
sum = self.a + self.b
return sum
def minus(self):
dif = self.a - self.b
return dif
def multiple(self):
mul = self.a * self.b
return mul
def divide(self):
div = self.a / self.b
return div
calc = Calc()
calc.set_number(20, 10)
print(calc.plus()) # 더한 값
print(calc.minus()) # 뺀 값
print(calc.multiple()) # 곱한 값
print(calc.divide()) # 나눈 값
4. 클래스를 사용한 프로필 관리 기능 만들기 (User profile)
# 프로필 관리 기능 만들어보기
class Profile():
def __init__(self):
self.profile = {
"name": "-",
"gender": "-",
"birthday": "-",
"age": "-",
"phone": "-",
"email": "-",
}
def set_profile(self, profile):
self.profile = profile
def get_profile(self):
return self.profile
def get_name(self):
return self.profile["name"]
def get_gender(self):
return self.profile["gender"]
def get_birthday(self):
return self.profile["birthday"]
def get_age(self):
return self.profile["age"]
def get_phone(self):
return self.profile["phone"]
def email(self):
return self.profile["email"]
profile = Profile()
profile.set_profile({
"name": "lee",
"gender": "man",
"birthday": "01/01",
"age": 32,
"phone": "01012341234",
"email": "python@sparta.com",
})
print(profile.get_name()) # 이름 출력
print(profile.get_gender()) # 성별 출력
print(profile.get_birthday()) # 생일 출력
print(profile.get_age()) # 나이 출력
print(profile.get_phone()) # 핸드폰번호 출력
print(profile.email()) # 이메일 출력
5. mutable, immutable
- mutable은 값이 변한다는 의미이며, immutable은 값이 변하지 않는다는 의미를 갖고 있다.
- int, str, list 등 자료형은 각각 mutable 혹은 immutable한 속성을 가지고 있다.
(1) immutable 속성을 가진 자료형 : int, float, str, tuple
(2) mutable 속성을 가진 자료형 : list, dict
※ 아래 코드를 통해 mutable과 immutable의 차이를 비교해볼 수 있다.
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!!']
"""
- 변수 mutable와 list_는 리스트 자료형으로써 mutable한 속성을 갖고 있고, 할당하는 메모리의 주소를 참조하기 때문에 이후에 list_가 8번째 줄의 list_.append("mutable list!!")로 인해 변경되면서 주소에 할당된 값이 바뀌고, 같은 주소를 바라보고 있는 변수 mutable의 값도 같이 변경된다.
- 위와 같은 경우를 피하고 값만 복사하고 싶을 경우 deepcopy 또는 인덱스를 가져와 새로운 리스트를 만들어주는 방법을 사용할 수 있다.
from copy import deepcopy
mutable = ["hello"]
# 아래 세 가지의 차이
list_ = mutable # 1번방법
list_.append("mutable test!")
# 이때 list_와 mutable은 mutable 속성으로 위의 식으로 인해 값이 둘 다 변화된다
# 값만 할당하며, mutable의 값은 바뀌지 않는다.
list_ = deepcopy(mutable) # 2번방법
list = mutable[::] # 3번방법
6. 숫자야구 만들기에서 사용된 주요 문법
- random 모듈과 random.shuffle()을 활용한 리스트 섞기
# 난수 생성, 임의의 번호 생성 등 랜덤한 동작이 필요할 때 사용된다.
import random
numbers = [1, 2, 3, 4, 5, 6, 7, 8]
random.shuffle(numbers) # numbers를 무작위하게 섞기
print(numbers) # [2, 8, 6, 4, 3, 7, 1, 5]
- 리스트 축약식(for문) 사용
# 리스트 컴플레이션, 축약식
number_list = [x for x in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- pop은 괄호 안에 아무것도 없다면 기본적으로 가장 마지막 값을 빼고, 숫자를 지정하면 원하는 인덱스의 값을 추출하고 할당할 수 있다.
# 리스트 컴플레이션, 축약식
number_list = [x for x in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random_number = number_list.pop(5) # pop을 통해 5번 인덱스의 값을 뺀다.
print(number_list)
print(random_number)
- pop을 사용해서 5가지 랜덤한 숫자 리스트 생성하기 다른 방법
# 리스트 컴플레이션, 축약식
length = 5
number_list = [x for x in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random_number = []
for _ in range(length):
random_number.append(number_list.pop(random.randrange(0, len(number_list))))
print(number_list)
print(random_numbers)
length = 5
random_numbers = set() # set타입으로 random_numbers를 하나 만들기
while len(random_numbers) < length:
random_numbers.add(random.randint(0, 9))
※ randrange와 randint의 차이점 : randrange는 마지막 숫자를 포함하지 않지만, randint는 마지막 숫자를 포함한다.
- set 자료형 만들때 주의할 점.
변수 정의할 때 중괄호'{}'만 사용하면 딕셔너리 자료형이 된다.
set자료형으로 만들기 위해서는 'set()'을 사용해야 한다.
dict_a = {}
set_a = set()
- set자료형은 작은 숫자(한 자리수)는 자동으로 정렬을 해주는 속성이 있지만, 두 자리 이상의 숫자부터는 정렬을 하지 않는 속성이 있음을 주의해야 한다.
length = 5
random_numbers = set() # set타입으로 random_numbers를 하나 만들기
while len(random_numbers) < length:
random_numbers.add(random.randint(0, 9))
random_numbers = list(random_numbers)
random.suffle(random_numbers)
print(random_numbers)
- 프로그램이 시작된 시간 기록하기 : time.time()
start_time = time.time()
- for문을 사용하여 인덱스와 리스트 출력하기, enumerate
import random
import time
import datetime
def main()
length = input("자릿수를 입력해주세요 :")
random_numbers = set() # set타입으로 random_numbers를 하나 만들기
while len(random_numbers) < int(length):
random_numbers.add(random.randint(0, 9))
random_numbers = list(random_numbers)
random.suffle(random_numbers)
start_time = time.time()
try_count = 0
while True:
input_number = int(input())
if input_number == "exit":
return
try_count += 1
out_count = 0
ball_count = 0
strike_count = 0
for i, v in enumerate(input_number):
v = int(v)
if v not in random_numbers: #포함되어있지 않은 경우
out_count += 1
else : # 포함되어 있는 경우
if random_numbers[i] == v:
strike_count += 1
else:
ball_count += 1
if strike_count == length:
print("####################################")
print("정답입니다!")
print(f"소요시간 : {time.time() = start_time:.2f}")
print(f"클리어 일자 : {date_time.now()}")
print(f"도전 횟수 : {try_count}")
print("####################################")
return
print(f"{ball_count}볼 {strike_count}스트라이크 {out_count}아웃")
main()
- 개발용일때와 릴리즈용일때 로그를 다르게 찍는 방법
릴리즈 할 때에는 DEBUG를 False라고 넣으면 [DEBUG]를 표현하지 않고 내용을 찍는다.
DEBUG = True
def log(message):
if DEBUG:
print(f"[DEBUG] {message}")
- 로그 레벨 5가지(DEBUG, VERBOSE, INFO, WARNING, ERROR)
LOG LEVEL
DEBUG
VERBOSE
INFO
WARNING
ERROR
■ TIT :: Today I thought
- 파이썬 클래스는 개념이 생소해서 익히기가 쉽지 않은 것 같다. 잊지 않도록 자주 사용해보고, 개념을 자주 보아서 익숙해지도록 해야겠다.
- mutable/immutable 속성 역시 메모리라는 개념이 새로 나와서 쉽지 않았다. 잊지 않도록 Check!
- 숫자야구 풀이는 이전에 내가 만들었던 풀이와 다른 부분이 꽤나 있었다. 두 코드를 잘 보고 어떤 부분을 다르게 표현했는지, 그리고 남이 짠 코드를 내가 똑같이 다시 작성해보는 것도 도움이 많이 될 것 같다.
'DEV > 파이썬 이론' 카테고리의 다른 글
파이썬 코딩 :: 파이썬 클래스, 함수, arg/kwarg, 패킹/언패킹, 객체지향, 유효성검사_TIL#12 (1) | 2022.09.16 |
---|---|
파이썬 코딩 :: 파이썬 클래스, 축약식, lambda, 계산기 만들기(2)_TIL#11 (0) | 2022.09.14 |
파이썬 웹 프로그래밍 :: 9월 둘째주 WIL #02 (0) | 2022.09.09 |
파이썬 코딩 :: 파이썬 문법(반복문, 모듈)_TIL#08 (0) | 2022.09.07 |
파이썬 코딩 :: 파이썬 숫자 야구 게임 만들기 (0) | 2022.09.07 |
댓글