[멋사 AI 웹 서비스 스쿨 TIL] 24일차 회고

1. Python Built-in Types

# Python의 주석

# 1줄 주석은 # 으로 시작하면 그 이후는 주석으로 간주
# 여러줄 주석은 ''' ~ ''' 이렇게 처리해요!
# 일반적으로 여러줄 주석을 처리할 때는 block을 잡아서 ctrl + /로 주석처리해요!

'''
요 안에 들어있는 내용은
모두 주석으로 처리되요!
여러줄 주석은 이렇게 처리합니다.
'''
# 변수선언은 어떻게 하나요?

# ECMAScript는 변수선언 어떻게 하나요?
# var, let, const 키워드로 변수를 선언했어요!

# Python은 동적타입언어로 변수를 선언하는 keyword도 없어요!
# 해당 변수가 있으면 사용하고 없으면 만들어서 사용해요!
# 기본적인 console출력문은 print() 함수를 이용해요!

myData = 100
print(myData)

del myData
print(myData)  # Error name 'myData' is not defined
# Python의 데이터 타입부터 알아보아요!

# Python은 primitive data type이 없어요. 기본데이터 타입이 없어요!
# 모두 Reference Data Type, 다시말해서 모두 다 객체예요.
# 객체를 생성하기 위해서는 class를 사용해야 해요!

# Python은 다른언어와 다르게 데이터 타입과 자료구조를 구분하지 않아요!

# Python Built-in Types

# 1. Numeric
# 2. Sequence
# 3. Text Sequence
# 4. Mapping
# 5. Set
# 6. Bool

2. Numeric

# Python Built-in Types - Numeric Type

# 숫자형을 의미해요!
# 정수, 실수

a = 123                # 정수
b = 3.14159265352797   # 실수
c = 3.14E10            # 실수(지수형태)
d = 0xAB               # 16진수 정수(0x로 시작하면 16진수)

# 위에서 만든 변수에 들어가 있는 값 하나하나가 싹 다 객체
# 객체는 class부터 생성되요!
# type()이라는 함수가 있어요 이 함수를 이용하면 해당 객체의 class를
# 알아낼 수 있어요.
print(type(a))    # <class 'int'>
print(type(b))    # <class 'float'>

# 숫자형은 당연히 4칙연산을 수행할 수 있어요!

# 연산은 기본적으로 같은 데이터 타입끼리 수행되요!
# 그 연산의 결과도 같은 데이터 타입으로 나와요!

result = 3 / 4  
print(result)  # 0.75

3. Sequence

# Python Built-in Types - Sequence Type

# 왜 Sequence 라고 부르는 건가요?
# 순서가 있기 때문에 그래요!

# Sequence Type안에는 크게 3가지 class가 있어요!
# <class 'list'>
# <class 'tuple'>
# <class 'range'>

# list부터 알아보아요!
# python의 가장 기본이 되는 자료구조이자 Data Type
# 임의의 데이터를 순서대로 저장하는 집합형 자료구조
# literal => []  (대괄호를 이용해서 list를 생성할 수 있어요!)

a = list()   # 비어있는 list를 생성할 수 있어요!
a = []
a = [1, 2, 3, 4]  # ,를 이용해서 요소들을 순차적으로 구분해서 저장하게 되요!
print(a)   # [1, 2, 3, 4]
a = [1, 3.14, 'Hello', True, [1,2,3] ] # 이런식으로 서로 다른 형태가 리스트안에 저장이 가능!
# 일반적으로 Array라고 불리는 배열은 같은 데이터 타입만 저장이 가능한데 list는 그렇지 않아요!

print(type(a))  # <class 'list'>

# list안에 또 다른 list를 가질 수 있어요!
a = [[1,2,3], True, [4,5,6], 100]  # list안에 또 다른 list를 넣을 수 있어요!
# 중첩리스트 라는 표현을 써요. 하지만 이게 차원을 의미하는건 아니예요!

a = [1, 2, ["Show", "me", "the", "money"], 3.14, True ]
#    0  1               2                   3      4    <= index
#   -5 -4              -3                   -2    -1    <= 음수 index를 지원

# list에 대해서 indexing을 할 수 있어요!
# indexing의 첨자는 0부터 시작해요!
print(a[0]) # 1
print(a[3]) # 3.14
print(a[-1]) # python은 음수 인덱스를 사용할 수 있어요! => True
print(a[2][3]) # money

# list에 대해서 slicing을 할 수 있어요!
# slicing의 가장 큰 특징은 원본과 slicing한 결과가 같은 데이터 Type이예요!
print(a[0:2])   # slicing. 시작 index과 끝 index ":"을 기준으로 명시.
                # 시작은 inclusive(포함), 끝은 exclusive(불포함)
                # [1, 2]
print(a[0:1])   # [1]
print(a[0])     # 1

print(a[:3])    # : 이 나왔으니 slicing하는건데.. : 앞 뒤로 숫자가 없는 경우가 있어요!
                # : 앞에 숫자가 없으면 첫음부터, : 뒤에 숫자가 없으면 끝까지의 의미예요!
                # [1, 2, ['Show', 'me', 'the', 'money']]
print(a[:])     # list의 처음부터 끝까지를 지칭!

# list의 연산( + , * ) 연결의 의미를 가져요!
a = [1, 2, 3]
b = [4, 5, 6]

print(a + b) # python의 list에 대해서 + 연산을 수행하면 리스트를 연결해요!
             # [1, 2, 3, 4, 5, 6]

print(a * 3) #  a * 3 => a + a + a
             # [1, 2, 3, 1, 2, 3, 1, 2, 3]

a = [1, 2, 3]
# a[0] = 5   # [5, 2, 3]
# a[0] = [7, 8, 9]  # [[7, 8, 9], 2, 3]
# a[0:1] = [7, 8, 9]  # [7, 8, 9, 2, 3]
a[0:2] = [7, 8, 9] # [7, 8, 9, 3]
print(a)

# list에 값을 추가하는 대표적인 함수
# 함수를 사용할 때 처리된 결과가 원본에 영향을 미치는 함수가 있고
# 함수를 사용할 때 원본은 변함이 없고 영향을 미친 결과가 리턴되는 경우가 있어요!
a = [1, 2, 3]
result = a.append(5)   # [1, 2, 3, 5]
print(result) # None
print(a)  # [1, 2, 3, 5]
# Python Built-in Types - Sequence Type

# tuple
# list와 거의 유사해요!
# tuple은 read only로 사용해요!

# tuple의 literal => () 소괄호를 이용해요!
a = (1, 2, 3)
# print(a)
# print(type(a))  # <class 'tuple'>
a = tuple([1, 2, 3, 4])   # 이 함수는 list와 같은 집합 자료구조를 tuple로 변환시킬 때 사용
# print(a)  # (1, 2, 3, 4)

a = (1, 3.14, ['Hello', 'World'], True, 100)
# print(a)
# print(a[1]) # 3.14
# print(a[0:3]) # (1, 3.14, ['Hello', 'World'])

# a[0] = 1000  Error!!!
a[2][0] = 'Hi'
print(a)

# tuple 사용할 때 주의해야 할 점.
a = (1, 2, 3)   # tuple
# 요소가 1개인 tuple
a = (1)         # () 소괄호는 연산자 우선순위를 나타내는 기호  (3 + 4) * 5
print(type(a))  # <class 'int'>
a = (1,)         # 요소 1개짜리 tuple을 쓸때는 , 명시해서 사용해요!
print(type(a))  # <class 'tuple'>

# tuple의 일반적인 형태
a = (1, 2, 3)
# tuple은 소괄호를 생략해서 사용할 수 있어요! 일반적으로 생략을 많이 해요!
a = 1, 2, 3
print(type(a))  # <class 'tuple'>

a, b, c = (100, 200, 300)
# Python Built-in Types - Sequence Type

# range (범위)
# list와 tuple은 실제 데이터를 가지고 있는 데이터 타입(자료구조)
# 하지만 range는 숫자 범위에 대한 의미를 가지고 있는거지 실제 데이터를
# 메모리상에 가지고 있지는 않아요!
# 아주 큰 숫자의 범위를 표현할 때 사용.

# range는 실제 데이터를 가지고 있지 않기 때문에 literal로 표현할 수 없어요!
# my_ragne = range(시작, 끝, 증감)  # 시작과 증감은 생략이 가능! 시작 -> 0 증감 -> 1
my_range = range(10)   # 0부터 10까지(10은 포함하지 않음)의 정수집합을 나타내는 sequence type
print(my_range)  # range(0, 10)  => [0, 1, 2, 3, 4, 5, 6,... , 9]
print(my_range[3]) # 3
print(my_range[3:6]) # range(3, 6)

4. Text Sequence

# 문자열(Text Sequence Type)에 대해서 알아보아요!

a = "안녕하세요!"
b = '하이하이'

# 여러줄에 걸친 문자열을 만들려면
a = '이것은 \n소리없는 \n아우성!!'
print(a)

b = """이것은
소리없는
아우성!!"""

print(b)

################################################

a = '소리없는 아우성'
print(type(a))   # <class 'str'>

a = "소리없는"    # ['소','리','없','는']
b = '아우성'      # ['아','우','성']
print(a + b)  #  소리없는아우성

# 주의해야 해요!
num = 100  # int class의 객체 - 정수형 - Numeric
# print('num의 값은 : ' + num)  # 'num의 값은 : ' + '100' => num의 값은 : 100
                              # python은 숫자에서 문자로의 자동형변환을 지원하지 않아요!
print('num의 값은 : ' + str(num))   # str()을 이용해서 명시적으로 문자로 변경해야 해요!

# list의 특징을 가지고 있기 때문에 기본적인 
# indexing과 slicing을 지원해요!
a = 'this is a sample text!!'
print(a[3])  # s
print(a[-1]) # !
print(a[:4]) # this

# in, not in 연산
a = 'this is a sample text!!'

print('is' in a)  # True (소문자 true X)
print('is' not in a)  # False (소문자 false X)

##############################################

# 자주사용되는 문자열 formatting

num = 5

# 출력하고 싶은 형태 => '바나나가 5개 있어요!'
print('바나나가 ' + str(num) + '개 있어요!')  # 너무 불편해요!
print("바나나가 {}개 있어요!".format(num))
print(f"바나나가 {num}개 있어요!")  # 앞으로 이 형태로 문자열을 이용할꺼예요!

# Text Sequence Type(str)에 대한 기본 특징을 알아보았다면
# 그 다음에는 제공되는 함수에 대해서 알아보면 되요!

a = "cocacola"

# len()은 길이를 구하기 위한 python 내장 함수. str이 가지고 있는 함수는 아니예요!

print(len(a))  # 8

print(a.count('c'))  # 3 ('c'가 몇번 등장했는지)
print(a.index('a'))  # 3 ('a'가 처음 등장한 위치(index))

###################################

a = " "
b = "abcd"
# a,b,c,d  => 이렇게 만들고 싶어요!
print(a.join(b))  # a b c d

a = "이것은 소리없는 아우성!"
print(a.split())  # ['이것은', '소리없는', '아우성!']

a = '2024-08-04'
print(a.split("-")) # ['2024', '08', '04']

5. Mapping

# Python의 built-in data type 중
# Mapping Type 이 있어요!

# key와 value의 쌍으로 데이터를 저장하는 자료구조
# { "name": "홍길동" }
# 이런 데이터를 만들어내는 class는 dict
# 이런 자료구조를 dictionary라고 해요!
# literal => { } , 중괄호안에 key와 value의 쌍이 : 으로 표현되요!
# 주의해야 할 점 중에 하나는..
# key값은 숫자(Numeric), 문자열(Text Sequence), tuple(Sequence), bool(Bool)을 사용할 수 있어요!
# 대신 list, dict, set 이런것들은 key값으로 사용할 수 없어요!

a = { 100 : "안녕하세요"}
a = { "name" : "홍길동"}
a = { (100,) : "이런것도 되요!"}
a = { True : "이런것도 되요!"}

# a = { [1,2,3] : "이건 안되요!" }  # 이건 안되요!

##################################

a = { "name" : "홍길동", "age" : 20, ('address',) : '서울' }
print(a)       # {'name': '홍길동', 'age': 20}
print(type(a)) # <class 'dict'>

print(a['name'])  # 홍길동
print(a[('address',)]) # 서울

##################################

# 주요한 함수가 3개 있어요!
# keys(), values(), items() 3개의 함수가 있어요!

a = { "name" : "홍길동", "age" : 20, 'address' : '서울' }
print(a.keys()) # dict_keys(['name', 'age', 'address'])
                # 결과를 보면 마치 list처럼 생겼어요!
                # 실제 list는 아니예요! 단, list처럼 사용은 가능해요!
for key in a.keys():
    print(a[key])

print(a.values()) # dict_values(['홍길동', 20, '서울'])
print(a.items()) # dict_items([('name', '홍길동'), ('age', 20), ('address', '서울')])

6. Set

# Python built-in Types - set

# 주머니 같은 집합형 자료구조예요!
# 순서가 없어요. 데이터의 순서가 존재하지 않아요!
# 중복을 허용하지 않아요!(중복배제)
# literal은 {} 이걸로 표현해요!
# {} 중괄호는 dict의 literal아닌가요? 
# { key1 : value1, key2 : value2, ... }  => dict
# { value1, value2, value3, ... }  => set

s = {1, 2, 3}
print(s)   # {1, 2, 3}
print(type(s)) # <class 'set'>  

s = set([1,1,2,2,3,3,3])   # list안의 요소를 set으로 변경
print(s) # {1 , 2 , 3}

# set은 이름에서 의미하다시피.. 집합연산을 제공
a = {1,2,3,4,5}
b = {4,5,6,7,8}

print(a & b)  # 교집합 {4, 5}
print(a | b)  # 합집합 {1,2,3,4,5,6,7,8}
print(a - b)  # 차집합 {1,2,3}

7. Bool

# Python built-in Types - Bool

# 논리 type : True, False
# 사용하는 class => bool class

a = True
print(a)
print(type(a))  # <class 'bool'>

# Bool type은 숫자와 호환이 가능해요!
# True => 1
# False => 0

print(True + 3) # 4

# 기본적으로 False로 인식되는 값들이 있어요!
# 1. "" 공백 문자열
print(bool(""))  # False  공백문자열을 논리값으로 변경했을때 False값.
# 2. [] 빈 list
print(bool([]))  # False  빈 list도 논리값으로 변경했을때 False
# 3. () 빈 tuple
# 4. {} 빈 dictionary
# 5. 숫자 0도 역시 False로 인식, 0 이외의 숫자는 모두 True로 인식

# 연산자는 and, or, not을 이용해요!

a = True
b = False

```python
# <class 'bool'>

print(a and b) # False
print(a or b) # True
print(not b) # True

8. date, datetime

# 별도의 data type이 또 있나요?
# 있어요! 대표적인 data type은 날짜와 시간이예요!
# 이 데이터 타입을 사용할 때는 import를 해서 사용해야 해요!

from datetime import date, datetime

today = date.today()
print(type(today))  # class가 나와요.. 다른 package에 들어가 있으면 package가 명시되요!
                    # <class 'datetime.date'>
print(today)    # 2024-08-12

print(f'연도는 {today.year}, 월은 {today.month}, 일은 {today.day} 입니다.')

# 시간도 알아보아요!
my_datetime = datetime.today()
print(my_datetime) # 2024-08-12 02:32:28.425533
print(f'현재 시간은 : {my_datetime.hour}')  # ??? 11시인데 왜 2시라고 나오나요?
print(f'현재 분은 : {my_datetime.minute}')
print(f'현재 초는 : {my_datetime.second}')

# 앗..날짜는 표준시(UTC)가 기준이군요. 한국시간을 사용하려면 어떻게 해야 하나요
# 외부모듈을 이용해야 해요!
# pytz이라는 모듈을 이용해야 해요!

import pytz   # pip install pytz 설치를 해야 사용할 수 있어요!

utc_now = datetime.now(pytz.utc)
print(utc_now) # 2024-08-12 02:37:59.812377+00:00

kst = pytz.timezone('Asia/Seoul')

kst_now = utc_now.astimezone(kst)
print(kst_now) # 2024-08-12 11:40:12.211438+09:00

# 날짜연산은 어떻게 해야 하나요?
# 외부 모듈(package)를 이용하면 편하게 쉽게 구현할 수 있어요!

today = date.today()
print(today)  # 2024-08-12

from datetime import timedelta

days = timedelta(days=-1)
print(f'하루 전 날짜 : {today + days}')  # 하루 전 날짜 : 2024-08-11

days = timedelta(days=-20)
print(f'20일 전 날짜 : {today + days}')  # 20일 전 날짜 : 2024-07-23

# timedelta는 days만 사용할 수 있고 months, years는 사용할 수 없어요!
# days = timedelta(months=-1)
# print(f'한달 전 날짜 : {today + days}')  # 

# 다른 package가 편하게 사용할 수 있는 함수를 제공해 줘요!

# !pip install python-dateutil # 설치해야 되요. colab은 이미 설치가 되어 있어요!
# !pip install python-dateutil
from dateutil.relativedelta import relativedelta

months = relativedelta(months=-2)
print(f'2달 전 날짜 : {today + months}')  # 2달 전 날짜 : 2024-06-12

# 특정 날짜를 날짜 date type으로 변환하려면 어떻게 해야 하나요?

from dateutil.parser import parse
myDate = parse("2020-01-01")
print(f'날짜로 변경한 값은 : {myDate}') # 2020-01-01 00:00:00

myDate = datetime(2024,10,11)
print(f'날짜로 변경한 값은 : {myDate}') # 2024-10-11 00:00:00

9. print 구문 사용

# 마지막으로 print 함수에 대해서 조금 더 알아보아요!
a = 'Hello'

print('안녕하세요!!')
print(f'출력할 변수값 : {a}')

print("안녕하세요", "반갑습니다.") # 안녕하세요 반갑습니다.
print("안녕하세요" "반갑습니다.") # 안녕하세요반갑습니다.

# 기본적인 print 함수는 문자열 하나를 출력한 후 바로 줄바꿈을 해요!
for x in range(10):
    print(x, end=" ")  # end는 줄바꿈대신 end 뒤에 오는 값으로 줄바꿈을 대신해요!

10. 정리

# Python의 built-in Types

# 1. Numeric
#    - 정수 :  class int
#    - 실수 :  class float
# 2. Sequence
#    - list : [] , class list
#    - tuple : () , class tuple
#    - range : 없음 , class range
# 3. Text Sequence
#    - 문자열 : '', "", ''' ''' , class str
# 4. Mapping
#    - dictionary : { key : value } , class dict
# 5. Set
#    - set : { value1, value2, .. } , class set
# 6. Bool
#    - 논리 : True, False , class bool

# 많이 사용되는 날짜 타입을 추가적으로 알아보았어요!
# built-in 타입이 아니기 때문에 반드시 import해서 사용.
# 날짜 데이터 타입 사용
# timezone설정하는 방법
# 일, 월, 연을 기준으로 날짜 연산하기.(delta)  timedelta, relativedelta
# 특정날짜를 문자열형태에서 혹은 숫자형태에서 날짜 데이터로 변환

# print구문은 항상 사용하는 python 내장 함수예요!
# print함수에 대한 간단한 사용방법
# print는 출력한 후 기본적으로 줄바꿈을 수행하는데 다른것으로 변경할 수 있어요!