728x90

발생 Error

Git Bash에서 다음 명령어를 입력할 경우,

$ git pull origin main
remote: Enumerating objects: 247, done.
remote: Counting objects: 100% (247/247), done.
remote: Compressing objects: 100% (187/187), done.
remote: Total 247 (delta 73), reused 157 (delta 38), pack-reused 0
Receiving objects: 100% (247/247), 59.49 KiB | 378.00 KiB/s, done.
Resolving deltas: 100% (73/73), done.
From https://github.com/HJ0216/TIL
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> origin/main

fatal: refusing to merge unrelated histories

fatal: refusing to merge unrelated histories

Error 발생

 

 

Error 원인

pull 명령어는 fetch와 merge를 한 번에 처리하는 명령어인데, merge가 되지 않는 상황

(fetch: 원격 저장소 내용 가져오기, merge: 로컬 저장소의 내용과 원격 저장소의 내용 병합하기)

 

push 명령은 로컬 저장소의 commit log와 원격 저장소의 commit log를 보고, 원격 저장소의 마지막 commit id와 동일한 commit id를 가진 로컬 저장소의 commit 시점을 찾아낸 뒤, 원격 저장소의 마지막 commit과 연결

 

commit histories가 서로 관련이 없을 경우, 즉 공통된 commit 지점이 존재하지 않을 경우, merge할 수 없음

 

 

해결 방법

1. git clone 명령어를 통해 원격 저장소 복제

2. pull 명령어 + 옵션을 통해 merge 진행

$ git pull origin main --allow-unrelated-histories
From https://github.com/HJ0216/TIL
 * branch            main       -> FETCH_HEAD
Merge made by the 'ort' strategy.
 AI/ann_model.py                   |  65 +++++++++++++++++
 AI/dacon_seoul_ddarung.py         | 103 ++++++++++++++++++++++++++
 AI/data_shape.py                  |  90 +++++++++++++++++++++++
 AI/evaluate_and_predict.py        |  51 +++++++++++++
 AI/hyperParameter_Tuning.py       |  40 ++++++++++
 AI/indicator_with_california.py   |  61 ++++++++++++++++
 AI/mae_and_mse.py                 |  48 ++++++++++++
 AI/matplotlib_plot2.py            |  44 +++++++++++
 AI/matplotlib_scatter_and_plot.py |  81 +++++++++++++++++++++
 AI/missing_value_handling.py      | 149 ++++++++++++++++++++++++++++++++++++++
 AI/multiLayer_Perceptron.py       |  74 +++++++++++++++++++
 AI/r2_score.py                    |  64 ++++++++++++++++
 AI/rmse_def.py                    |  63 ++++++++++++++++
 AI/split_train_test1.py           |  51 +++++++++++++
 AI/split_train_test2.py           |  58 +++++++++++++++
 AI/split_train_test3.py           |  68 +++++++++++++++++
 AI/useful_method_from_numpy.py    |  18 +++++
 README.md                         |  68 +++++++++++++++++
 18 files changed, 1196 insertions(+)
 create mode 100644 AI/ann_model.py
 create mode 100644 AI/dacon_seoul_ddarung.py
 create mode 100644 AI/data_shape.py
 create mode 100644 AI/evaluate_and_predict.py
 create mode 100644 AI/hyperParameter_Tuning.py
 create mode 100644 AI/indicator_with_california.py
 create mode 100644 AI/mae_and_mse.py
 create mode 100644 AI/matplotlib_plot2.py
 create mode 100644 AI/matplotlib_scatter_and_plot.py
 create mode 100644 AI/missing_value_handling.py
 create mode 100644 AI/multiLayer_Perceptron.py
 create mode 100644 AI/r2_score.py
 create mode 100644 AI/rmse_def.py
 create mode 100644 AI/split_train_test1.py
 create mode 100644 AI/split_train_test2.py
 create mode 100644 AI/split_train_test3.py
 create mode 100644 AI/useful_method_from_numpy.py
 create mode 100644 README.md

➕ git pull 명령어

origin: remote repository의 URL short name

main: main branch의 remote repository

 

 

이후, push 재 진행

$ git push -u origin main
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 520 bytes | 520.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/HJ0216/TIL.git
   5376d70..1843ac3  main -> main
branch 'main' set up to track 'origin/main'.

 

필요없는 Branch 제거

$ git push origin --delete master
To https://github.com/HJ0216/TIL.git
 - [deleted]         master

 

 

 

참고 자료

📑 fetch, 원격 저장소의 데이터를 로컬에 가져오기만 하기

📑 git push, pull (fatal: refusing to merge unrelated histories) 에러

📑 git branch 삭제

📑 git pull, push와 origin의 의미

 

728x90
728x90

$ git push -u origin main
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 520 bytes | 520.00 KiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/HJ0216/TIL.git
   5376d70..1843ac3  main -> main
branch 'main' set up to track 'origin/main'.

1. Git 홈페이지에서 사양에 맞는 Git Download

 

2. 모든 내용을 Default로 진행하되,

"Select Destination Location"에서 경로에 한글이 포함되지 않게 유의

* 문제가 발생하진 않으나 향후 발생할 수 있는 문제를 예방하고자 함

 

3. Git 설치 후 정상 작동 확인을 위해 Git Bash에

$ git --version
git version 2.39.1.windows.1

입력 후, version 확인

 

4. user name 및 user email 설정

git config --global user.name "이름"
git config --global user.email "이메일"
# --global: 해당 PC에서 사용하는 모든 git 조작에 적용

git config user.name "이름"
git config user.email "이메일"
# 미지정(local): 해당 저장소에 한해서만 적용
# local이 global보다 우선 적용됨
# user 삭제
git config --unset --global user.name # global user 삭제
git config --unset --global user.email # global user 삭제
git config --unset user.name # local user 삭제
git config --unset user.email # local user 삭제

# user name 변경
git config --global user.name "변경할 이름"

# user 확인
git config --list

Github와 Git을 연동하기 위해서 Github에 등록된 이메일을 user.email에 설정

 

5. local PC에 git 저장소 설정

 5.1. 폴더 생성

 5.2. 해당 폴더 내에서 git bash 실행 후, 입력 및 응답 확인

git init
Initialized empty Git repository in C:/git_total/.git/

# local c 폴더의 git_total 폴더를 local 저장소로 지정

 

6. local PC에 생성한 git 저장소와 원격 저장소 연결

$ git remote add origin https://github.com/HJ0216/TIL.git

# TIL repository와 연동

 

7. 현재 git 상태 확인

$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

# Branch: master, Commit 대상: 없음

 

8. Test file Add(커밋할 대상으로 지정한 상태)

$ git add /c/git_total/test.txt

# local c 폴더 안의 git_total 폴더의 test.txt 파일 add

 

9. 현재 git 상태 확인

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   test.txt

# Branch: Master, Staging: test.txt(add한 파일)

 

10. commit 진행(변경 사항에 대한 기록을 저장한 상태)

$ git commit -m "Commit Message 입력"
[master (root-commit) 9549c78] using a git bash
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt

# "Commit Message"와 함께 commit 진행(Commit: 변경사항에 대한 기록 저장)

 

11. Push 진행(원격저장소에 변경된 내용을 올린 상태)

$ git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 229 bytes | 229.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
remote:
remote: Create a pull request for 'master' on GitHub by visiting:
remote:      https://github.com/HJ0216/TIL/pull/new/master
remote:
To https://github.com/HJ0216/TIL.git
 * [new branch]      master -> master
 
 # Branch: Master로 TIL repository에 text.txt 파일 저장

 

⚠️ 문제: [new branch] master -> master

Default Branch인 main Branch가 아닌 master Branch가 새로 생성됨

$ git branch -m master main

# master branch name을 main으로 변경

 

⚠️ 문제: 변경된 이름의 main branch로 push 진행 시 다음의 오류 발생

 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/HJ0216/TIL.git'

(참조: [해결 방법] error: failed to push some refs to 'https://github.com/')

 

기존 원격 저장소에 저장되어있는 버전과 원격 저장소와 연동시킨 로컬 저장소의 버전이 맞지 않을 경우, 발생하는 문제로 원격저장소 내용을 로컬 저장소에 pull을 진행시킨 후 push를 진행

 

 

필요없는 Branch 삭제

$ git push origin --delete master
To https://github.com/HJ0216/TIL.git
 - [deleted]         master

 

 

 

참고 자료

📑 git username 확인, 변경

📑 Git 최초 설정: 사용자 이름과 이메일 설정하는 방법

 

728x90
728x90

발생 Error

Git Bash에서 다음 명령어를 입력할 경우,

$ git push -u origin main
To https://github.com/HJ0216/TIL.git
 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'https://github.com/HJ0216/TIL.git'

! [rejected]        main -> main (fetch first)
⭐ error: failed to push some refs to 'https://github.com/HJ0216/TIL.git'

Error 발생

 

 

Error 원인

원격 저장소의 main branch에 저장되어있는 내용과 로컬 저장소의 내용이 일치하지 않아 발생

 

 

해결 방법

원격 저장소 내용을 로컬 저장소에 먼저 pull 시킴

$ git pull origin main
remote: Enumerating objects: 247, done.
remote: Counting objects: 100% (247/247), done.
remote: Compressing objects: 100% (187/187), done.
remote: Total 247 (delta 73), reused 157 (delta 38), pack-reused 0
Receiving objects: 100% (247/247), 59.49 KiB | 378.00 KiB/s, done.
Resolving deltas: 100% (73/73), done.
From https://github.com/HJ0216/TIL
 * branch            main       -> FETCH_HEAD
 * [new branch]      main       -> origin/main
fatal: refusing to merge unrelated histories

 

 

⚠️ 추가 문제: fatal: refusing to merge unrelated histories Error 발생

(참조: [해결 방법] fatal: refusing to merge unrelated histories)

 

 

 

참고 자료

📑[GitHub] Repository에 'main' branch로 push 하기

 

728x90
728x90

기본 환경: IDE: VS code, Language: Python

 

서울시 따릉이 대여량 예측 경진대회 자료를 통한 Pandas pkg 및 결측치(Missing Value) 처리 방법

# dacon_seoul_ddarung.py
# dacon_seoul_ddarung data: https://dacon.io/competitions/open/235576/data

import numpy as np
import pandas as pd

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error


# 1. Data
path = './_data/ddarung/'
# 동일한 경로의 파일을 여러번 당겨올 경우, 변수를 지정해서 사용
# ./ = 현재 폴더
# _data/ = _data 폴더
# ddarung/ = ddarung 폴더

train_csv = pd.read_csv(path+'train.csv', index_col=0)
# path + 'train.csv': ./_data/ddarung/train.csv
# index_col을 입력하지 않을 경우 idx도 데이터로 인식하게 됨 (0번째 column은 data가 아닌 idx임을 안내)
# print(train_csv) [1459 rows x 11 columns] -> [1459 rows x 10 columns]

test_csv = pd.read_csv(path+'test.csv', index_col=0)
submission = pd.read_csv(path+'submission.csv', index_col=0)

print(train_csv.columns) # sklearn.feature_names

print(train_csv.info())
# null 값 제외 출력
# Int64Index: 715 entries, 총 데이터 수
# 결측치: 총 데이터 수 - Non-Null (수집못한 데이터)
print(test_csv.info()) # info -> null이 아닌 값(Non-Null) 출력
print(train_csv.describe()) # sklearn.DESC

# 결측치 처리 - '결측 데이터 제거'
print(train_csv.isnull().sum()) # data_set의 결측치(Null) 값 총계 출력
train_csv = train_csv.dropna() # pandas.dropna(): null 값을 포함한 데이터 행 삭제

x = train_csv.drop(['count'], axis=1)
# count column 삭제
# axis=0: index, axis: columns
print(x.shape) # [1459 rows x 9 columns] -> dropna로 인한 변경

y = train_csv['count']
print(y.shape)


x_train, x_test, y_train, y_test = train_test_split(
    x, y,
    shuffle=True,
    train_size=0.7,
    random_state=1234
)

print(x_train.shape, x_test.shape) #(1021, 9) (438, 9)
print(y_train.shape, y_test.shape) #(1021, ) (438, )


# 2. model
model = Sequential()
model.add(Dense(64, input_dim=9)) # input_dim = 9
model.add(Dense(64))
model.add(Dense(32))
model.add(Dense(16))
model.add(Dense(1)) # output_dim = 1


# 3. compile and train
model.compile(loss='mse', optimizer='adam') # RMSE가 평가지표이므로 유사한 mse 사용
model.fit(x_train, y_train, epochs=128, batch_size=32)


# 4. evaluate and predict
loss = model.evaluate(x_test, y_test)
print("Loss: ", loss)

y_predict = model.predict(x_test)
# test는 y값이 없으므로 train의 test dataset 사용


def RMSE (y_test, y_predict):
    return np.sqrt(mean_squared_error(y_test, y_predict))

rmse = RMSE(y_test, y_predict)
print("RMSE: ", rmse)


# for submission
y_submit = model.predict(test_csv) # predict() return numpy
submission['count'] = y_submit
# pandas(submission['count'])에 numpy(y_submit)를 직접 대입시키면 numpy가 pandas가 됨

submission.to_csv(path+'submission_230121.csv')



'''
Result

'''

 

⭐ Python Pandas 관련 유용한 Method 정리
pandas.read_cvs(): cvs file read
pandas.columns: column name

pandas.info(): null이 아닌 값(Non-Null) 출력
pandas.describe(): data description
pandas.isnull(): null 값 출력
pandas.dropna(): null data delete
pandas.drop(): column delete

 

⭐ Data Missing Value(결측치) 처리 방법
1. 삭제

 1.1. 결측치 데이터의 행 삭제

 1.2. 결측치 데이터의 열 삭제

 

2. 대체

 2.1. 이전 행 값으로 대체

 2.2. 다음 행 값으로 대체

 2.3. 원하는 값으로 대체

 2.4. 보간법으로 대체

→ method와 limit_direction에 따라 다르게 나타남

Data 값을 선형에 비례하는 값으로 결측값을 보간함

 2.5. 해당 열의 결측치를 제외한 평균값으로 대체

 

Pandas Dataset을 활용한 결측치 처리 예제

# missing_value_handling.py

import pandas as pd

dataset = pd.DataFrame([
    {'id': 1, 'val': None, 'pw': 2},
    {'id': 2, 'val': 21, 'pw': 3},
    {'id': 3, 'val': 19, 'pw': 0},
    {'id': 4, 'val': 24, 'pw': 1},
    {'id': None, 'val': 15, 'pw': 2},
    {'id': 5, 'val': 9, 'pw': 2},
    {'id': 6, 'val': 33, 'pw': 1},
    {'id': None, 'val': 40, 'pw': 2}
])

print(dataset)
'''
    id   val  pw
0  1.0   NaN   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  NaN  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  NaN  40.0   2
'''


# 1.1. 행 삭제
dataset_rev1 = dataset.dropna()
print(dataset_rev1)
'''
    id   val  pw
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
5  5.0   9.0   2
6  6.0  33.0   1
'''

# 1.2. 열 삭제
dataset_rev2 = dataset.dropna(axis='columns')
print(dataset_rev2)
'''
   pw
0   2
1   3
2   0
3   1
4   2
5   2
6   1
7   2
'''

# 2.1. 이전 행 값으로 대체
dataset_rev3 = dataset.fillna(method='pad')
print(dataset_rev3)
'''
    id   val  pw
0  1.0   NaN   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  4.0  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  6.0  40.0   2

이전 값이 없는 0번째 행은 NaN값 유지
'''

# 2.2. 다음 행 값으로 대체
dataset_rev4 = dataset.fillna(method='bfill')
print(dataset_rev4)
'''
    id   val  pw
0  1.0  21.0   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  5.0  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  NaN  40.0   2

다음 값이 없는 7번째 행은 NaN값 유지
'''

# 2.3. 원하는 값으로 대체
dataset_rev5 = dataset.fillna(0) # 0으로 대체
print(dataset_rev5)
'''
    id   val  pw
0  1.0   0.0   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  0.0  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  0.0  40.0   2
'''

# 2.4. 보간법으로 대체
dataset_rev6 = dataset.interpolate(method='linear',limit_direction='forward')
# 선형 비례 방법을 위에서부터 아래로 적용하여 NaN 값 채우기(0번째 행 제외)
dataset_rev6 = dataset.interpolate(method='linear',limit_direction='backward')
# 선형 비례 방법을 위에서부터 아래로 적용하여 NaN 값 채우기(7번째 행 제외)
print(dataset_rev6)
'''
forward
    id   val  pw
0  1.0   NaN   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  4.5  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  6.0  40.0   2

backward
    id   val  pw
0  1.0  21.0   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  4.5  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  NaN  40.0   2
'''

# 2.5. 결측치 값으로 제외한 평균값으로 대체
dataset_rev7 = dataset.fillna(dataset.mean())
print(dataset_rev7)
'''
    id   val  pw
0  1.0  23.0   2
1  2.0  21.0   3
2  3.0  19.0   0
3  4.0  24.0   1
4  3.5  15.0   2
5  5.0   9.0   2
6  6.0  33.0   1
7  3.5  40.0   2
'''

 

 

 

 cvs 파일 관련 유용한 VS Code 확장자

: Excel Viewer, Rainbow CSV

 

소스 코드

🔗 HJ0216/TIL

 

참고 자료

📑 서울시 따릉이 대여량 예측 경진대회

📑 [pandas] 데이터 결측치 존재여부 확인 및 결측치 처리하기

📑 [Python pandas] 결측값 보간하기 (interpolation of missing values)

 

728x90

'Naver Clould with BitCamp > Aartificial Intelligence' 카테고리의 다른 글

Validation Data  (0) 2023.01.22
Activation Function  (0) 2023.01.22
Environment Settings for GPU usage  (0) 2023.01.21
Model Performance Indicator  (0) 2023.01.21
Matplotlib: Scatter and plot  (0) 2023.01.21
728x90

본 환경: IDE:VS code, Language:Python

 

GPU 사용을 위한 환경 설정

 

1. Google: Nvdia Driver DownLoad

 

2. Google: Cuba DownLoad(v.11.4.4)

 

3. Google: cuDNN DownLoad

login(Sign in required)

Archived relaesae

Version에 맞는 cuDNN Download

 

4. D drive 내 'program' 폴더 생성
program 폴더 내에 해당 파일(다운로드 받은 파일 3개) 복사
(Ncvidia Driver) 527.56-desktop-win10-win11-64bit-international-dch-whql
(cuda) cuda_11.4.4_472.50_windows
(cuDNN) cudnn-11.4-windows-x64-v8.2.4.15

D drive -> 프로그램 폴더 내
4.1. (Nvidia Driver) 527.56-desktop-win10-win11-64bit-international-dch-whql 실행
→ driver만 설치, 사용자 정의 설치, 전체 설치

4.2. (cuda) cuda_11.4.4_472.50_windows
→ 동의 및 계속, 사용자 정의 설치
⚠️ Cuda 내 VS Integration 설치 제외, samples 설치 제외, Documentation 제외
GeForce 설치 제외
Component * 2 설치 제외

4.3. (cuDNN)cudnn-11.4-windows-x64-v8.2.4.15.zip
D drive에 zip 파일 풀기

4.4. C Drive -> 보기: 파일 확장명, 숨김 항목 표시 클릭
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4
→ NVIDIA GPU Computing Toolkit\CUDA\v11.4 확인
⚠️ 가장 최신 버전의 CUDA가 아닌 가장 최근에 다운 받은 버전이 실행됨

4.5. D Drive에 담긴 프로그램 폴더 내 Cuda 폴더 내 파일 4개
(bin, include, lib, NVIDIA_SLA_cuDNN_Support.txt)를 
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4에 복사해서 덮어쓰기

 

⭐ 설치 확인
cmd
nvidia-smi: 그래픽 드라이버 설치 확인
nvcc -V or nvcc --version : cuda ver 확인

 

⭐ GPU를 활용한 가상환경 만들기
anaconda prompt
conda create -n tf274gpu python=3.9.15 anaconda
conda env list: 가상환경 리스트 조회(⚠️ Base에서 확인)
activate tf274gpu
pip install tensorflow-gpu==2.7.4

VS code

Interpreter: 가상 환경 설정 tf274gpu 선택 후 Source Code 실행

# gpu_test.py

import tensorflow as tf
print(tf.__version__) # 2.7.4

gpus = tf.config.experimental.list_physical_devices('GPU')
# experimental: experimental method
# list_physical_devices 물리적인 장치 리스트
print(gpus)
# [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
# Nvidia GPU만 출력됨(intel 내장형 GPU 출력 X)


if(gpus):
    print("GPU is running.")
else:
    print("GPU isn't running.")
# on GPU: GPU is running.
# on CPU: gpus=[], GPU isn't running.

gpus를 사용한 가상환경일 경우,

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

[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

print(len(gpus)) = 1

-> 1개의 element가 있는 list 

비어있지 않은 리스트이므로 true 반환

그러므로 "GPU is running." 출력

 

Python에서의 boolean 기준

Value Descirption Boolean
"" 빈 String False (공백이 아니고 비어있지 않은 문자열은 True)
" " 공백만 있는 String False (공백이 아니고 비어있지 않은 문자열은 True)
"abc" 값이 있는 String True
[] 빈 List False (공백이 아니고 비어있지 않은 리스트는 True)
[1, 2] 값이 있는 List False (공백이 아니고 비어있지 않은 리스트는 True)
1 숫자 1 True
0 숫자 0 False (0이 아닌 모든 숫자는 True)
-1 숫자 -1 True
{} 비어있는 dictionaty False (공백이 아니고 비어있지 않은 dictionary는 True)
() 비어있는튜플 False (공백이 아니고 비어있지 않은 Tuple은 True)

* list: 자료 구조 형태의 하나로 순서가 있는 수정가능한 객체의 집합

list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

* tuple: 자료 구조 형태의 하나로 순서가 있는 집합(수정 불가능)

tuple = (1, 2, 3, 4, 5)

 

 

 

소스 코드

🔗 HJ0216/TIL

 

참고 자료

📑 [Python] 리스트, 튜플

 

728x90