20230314 kdt 학습일지
2023. 3. 14. 17:35ㆍ학습일지
728x90
1. 파일 읽기 및 저장하기
1-1.fileinput
- 텍스트 파일을 읽고, 쓰고, 저장하는 기능을 편리하게 사용할 수 있도록 해주는 라이브러리
- 여러개의 파일을 읽어서 수정할 수 있음
In [8]:
import fileinput
import os
import glob
In [9]:
#현재 경로 확인
os. getcwd()
Out[9]:
'C:\\Python\\jupyter'
In [10]:
#디렉토리 내 파일 확인
os. listdir(os.getcwd())
Out[10]:
['.ipynb_checkpoints', '24. 파일 입출력 라이브러리.ipynb', 'sample']
In [11]:
#경로 설정
path = 'sample/'
In [12]:
#glob(): 해당 경로의 파일 이름을 리스트로 반환
glob.glob(os.path.join(path,'*.txt'))
Out[12]:
['sample\\새파일1.txt',
'sample\\새파일2.txt',
'sample\\새파일3.txt',
'sample\\새파일4.txt',
'sample\\새파일5.txt']
In [13]:
os.path.join(path,'*.txt')
Out[13]:
'sample/*.txt'
In [17]:
with fileinput.input(glob.glob(os.path.join(path,'*.txt'))) as f:
for line in f:
print(line)
1번째 줄입니다.
2번째 줄입니다.
3번째 줄입니다.
4번째 줄입니다.
5번째 줄입니다.
6번째 줄입니다.
7번째 줄입니다.
8번째 줄입니다.
9번째 줄입니다.
10번째 줄입니다.
11번째 줄입니다.
12번째 줄입니다.
13번째 줄입니다.
14번째 줄입니다.
15번째 줄입니다.
In [25]:
txt_files = glob.glob(os.path.join(path, '*.txt'))
In [30]:
# 각 파일의 첫번째 라인을 찾아 변경하기
with fileinput.input(txt_files, inplace=True)as f:
for line in f:
if f.isfirstline():
print('첫번째 라인입니다.')
else:
print(line,end='')
In [32]:
with fileinput.input(txt_files, inplace=True)as f:
for line in f:
if line in f =='첫번째 라인입니다\n':
print('1번째 라인입니다.',end='\n')
else:
print(line,end='')
5번째 줄입니다.
In [35]:
#키워드 포함 라인 포함하기
with fileinput.input(txt_files, inplace=True)as f:
for line in f:
if '1번째' in line:
print('1번째 라인입니다.',end='\n')
else:
print(line,end='')
In [38]:
#텍스트 치환하기
with fileinput.input(txt_files, inplace=True)as f:
for line in f:
if '12번째' in line:
print(line.replace('12번째','열두번째'),end='\n')
else:
print(line,end='')
1-2.pickle
- 파이썬에서 사용하는 딕셔너리, 리스트. 클래스등의 자료형을 변환 없이 그대로 파일로 저장하고 불러올 때 사용하는 모듈
In [40]:
import pickle
In [41]:
data= ['apple','banana','orange']
In [46]:
#파일 저장
with open('list.pkl', 'wb') as f:
pickle.dump(data,f)
In [47]:
#파일 읽기
with open('list.pkl', 'rb') as f:
data = pickle.load(f)
In [48]:
type(data)
Out[48]:
list
In [49]:
print(data)
['apple', 'banana', 'orange']
In [50]:
#딕셔너리 저장
data = {}
data[1]= {'id':1,'userid':'apple','name':'김사과','gender':'여자','age':20}
In [54]:
#파일 저장
with open('dict.pkl', 'wb') as f:
pickle. dump(data,f)
In [53]:
print(data)
{1: {'id': 1, 'userid': 'apple', 'name': '김사과', 'gender': '여자', 'age': 20}}
2. 파일 찾기, 복사, 이동하기
2-1. 파일 확장자로 찾기
In [61]:
#파일 확장자로 찾기
os.getcwd()
Out[61]:
'C:\\Python\\jupyter'
In [62]:
for filename in glob.glob('*.txt'):
print(filename)
주피터 노트북 .txt
In [63]:
#txt 파일 찾기 : 하위 경로
for filename in glob.glob('**/*.txt'):
print(filename)
sample\새파일1.txt
sample\새파일2.txt
sample\새파일3.txt
sample\새파일4.txt
sample\새파일5.txt
In [64]:
#txt 파일 찾기 : 현재와 하위 경로 모두 포함
for filename in glob.glob('**/*.txt',recursive=True):
print(filename)
주피터 노트북 .txt
sample\새파일1.txt
sample\새파일2.txt
sample\새파일3.txt
sample\새파일4.txt
sample\새파일5.txt
In [69]:
#파일명 글자수로 찾기
for filename in glob.glob('????.*',recursive=True): # 글자수 4개
print(filename)
dict.pkl
list.pkl
In [73]:
for filename in glob.glob('??????.*',recursive=True):# 글자수 6개
print(filename)
주피터노트북.txt
In [79]:
#문자열 패턴 포함 파일명 찾기
for filename in glob('[a-z][a-z][a-z][a-z]???.*',recursive=True): # 영어 알파벳4개
print(filename)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[79], line 2
1 #문자열 패턴 포함 파일명 찾기
----> 2 for filename in glob('[a-z][a-z][a-z][a-z]???.*',recursive=True): # 영어 알파벳4개
3 print(filename)
TypeError: 'module' object is not callable
In [78]:
for filename in glob.glob('**/새파일*.*'):
print(filename)
sample\새파일1.txt
sample\새파일2.txt
sample\새파일3.txt
sample\새파일4.txt
sample\새파일5.txt
In [80]:
for filename in glob.glob('**/*프로젝트*.*'):
print(filename)
project\프로젝트.txt
2-2 fnmatch
- glob과 동일하게 특정한 패턴을 따르는 파일명을 찾아주는 모듈
- 파일명 매칭 여부를 True, False형태로 반환하기 때문에 os. listdir() 함수와 함께 사용
In [81]:
import fnmatch
In [85]:
#파일명은 '새'시작하고 확장명은 .txt를 검색
#확장자를 제외한 파일명의 길이는 4개이며, 파일명의 마지막 문자는 숫자입니다.
for filename in os. listdir('./sample'):
if fnmatch.fnmatch(filename,'새??[0-9].txt'):
print(filename)
새파일1.txt
새파일2.txt
새파일3.txt
새파일4.txt
새파일5.txt
2-3.shutil
- 파일을 복사하거나 이동할 때 사용하는 내장 모듈
In [87]:
import shutil
In [88]:
#파일 복사하기
shutil.copy('./sample/새파일1.txt', './sample/새파일1_복사본.txt')
Out[88]:
'./sample/새파일1_복사본.txt'
In [89]:
#파일 이동하기
shutil.move('./sample/새파일1_복사본.txt','./새파일1_복사본.txt')
Out[89]:
'./새파일1_복사본.txt'
In [90]:
#확장명 바꾸기
shutil.move('./새파일1_복사본.txt','./새파일_복사본.py')
Out[90]:
'./새파일_복사본.py'
3. 파일 압축
3-1. 데이터 압축
- 대용량 데이터 및 대량의 파일을 전송 시 전송 속도가 느리며 전송 문제가 발생할 가능성이 매우 높음
- 데이터 압축의 종류
- 손실압축 : 사람이 눈치채지 못할 수준의 정보만 버리고 압축하는 방법
- 무손실 압축 : 데이터 손실이 전혀 없는 압축
- 압축률 : 압축된 자료랑(압축된 데이터 크기) / 원시 자료량(원래 데이터 크기)
- 다양한 압축 알고리즘에 따라 압축 성능 및 시간이 좌우됨
- 압축: 인코딩(incoding)
- 압축 해제: 디코딩(Decoding)
3-2. zlib
- 데이터를 압축하거나 해제할 때 사용하는 모듈
- compress()와 decompress() 함수로 문자열을 압축하거나 해제하는 것
- 데이터 크기를 줄여서 전송이 필요한 경우 사용
In [95]:
import zlib
In [96]:
data= 'Hello Python!'*10000
In [97]:
print(len(data))# 130000byte
130000
In [99]:
compress_data = zlib.compress(data.encode(encoding='utf-8'))
print(len(compress_data #293byte
293
In [100]:
compress_data
Out[100]:
b'x\x9c\xed\xc71\r\x00 \x0c\x000+\xe0f\'&H8\x16\xf6\xf0\xe0\x1e\x1f\xa4\xfd\x1a3\xb3\xda\xb8g\xd5\xee!"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""?\xe6\x01le79'
In [102]:
org_data = zlib.decompress(compress_data).decode('utf-8')
print(len(org_data))
130000
3-3. gzip
- 파일을 압축하거나 해제할 때 사용하는 모듈
- 내부적으로 zlib 알고리즘 사용
In [114]:
import gzip
In [115]:
with open('org_data.txt','w') as f:
f.write(data)
In [117]:
#gzip으로 압축
with gzip.open('compressed.txt.gz', 'wb') as f:
f.write(data.encode('utf-8'))
In [118]:
#gzip 압축해제
with gzip.open('compressed.txt.gz', 'rb') as f:
org_data = f.read().decode('utf-8')
In [120]:
print(len(org_data))
130000
3-4. zipfile
- 여러개 파일을 zip 확장자로 합쳐서 압축할 때 사용하는 모듈
In [121]:
import zipfile
In [128]:
#파일 합치고 압축하기
with zipfile.ZipFile('./sample/새파일. zip','w') as myzip:
myzip.write('./sample/새파일1.txt')
myzip.write('./sample/새파일2.txt')
myzip.write('./sample/새파일3.txt')
myzip.write('./sample/새파일4.txt')
myzip.write('./sample/새파일5.txt')
In [132]:
#압축 해제하기
with zipfile.ZipFile('./sample/새파일.zip') as myzip:
3-5. tarfile
- 여러개 파일을 tar 확장자로 합쳐서 압축할 때 사용하는 모듈
In [127]:
import tarfile
In [135]:
#파일 합치고 압축하기
with tarfile.open('./sample/새파일.tar','w') as mytar:
mytar.add('./sample/새파일1.txt')
mytar.add('./sample/새파일2.txt')
mytar.add('./sample/새파일3.txt')
mytar.add('./sample/새파일4.txt')
mytar.add('./sample/새파일5.txt')
In [136]:
#압축 해제하기
with tarfile.open('./sample/새파일.tar') as mytar:
mytar.extractall()
In [ ]:
1. 압축파일 정리하기
In [9]:
import os
os.getcwd()
Out[9]:
'C:\\Python\\jupyter'
In [10]:
# 정리 대상 폴더 경로를 설정
target_path = './고라니'
In [11]:
# 압축 파일 확인
import glob
zipfile_path = []
for filename in glob.glob(os.path.join(target_path, '**/*.zip'), recursive=True):
zipfile_path.append(filename)
print(zipfile_path)
['./고라니\\데이터저장_물류.zip']
In [12]:
# 압축 파일 해제
import zipfile
for filename in zipfile_path:
with zipfile.ZipFile(filename) as myzip:
zipinfo = myzip.infolist() # zip파일 정보
for info in zipinfo:
decode_name = info.filename.encode('cp437').decode('euc-kr') # 한글 깨짐 방지
info.filename = os.path.join(target_path, decode_name)
myzip.extract(info)
2. 파일명 정리하기
In [13]:
!pip install openpyxl
Requirement already satisfied: openpyxl in c:\users\administrator\appdata\local\programs\python\python38\lib\site-packages (3.1.2)
Requirement already satisfied: et-xmlfile in c:\users\administrator\appdata\local\programs\python\python38\lib\site-packages (from openpyxl) (1.1.0)
WARNING: You are using pip version 21.1.1; however, version 23.0.1 is available.
You should consider upgrading via the 'c:\users\administrator\appdata\local\programs\python\python38\python.exe -m pip install --upgrade pip' command.
In [14]:
import openpyxl as opx
In [15]:
# 폴더별 파일명을 입력 받아 엑셀파일에 저장하는 함수
def getFileName(target_path):
wb = opx.Workbook()
ws = wb.active # 새로 생성한 WorkBook의 활성화 시트를 ws로 정의
ws.cell(row=1, column=1).value = '파일경로'
ws.cell(row=1, column=2).value = '파일명(변경전)'
ws.cell(row=1, column=3).value = '파일명(변경후)'
i = 2
current_dir = target_path
filelist = os.listdir(current_dir)
for filename in filelist:
ws.cell(row=i, column=1).value = current_dir + "/"
ws.cell(row=i, column=2).value = filename
i = i+1
wb.save(os.path.join(target_path, 'filelist.xlsx'))
In [16]:
getFileName(target_path)
3. 파일명 변경하기
In [17]:
def excelRead(filepath : str) -> list:
wb = opx. load_workbook(filepath)
ws = wb.active
dirpath = [r[0].value for r in ws]
file_before = [r[1].value for r in ws]
file_after = [r[2].value for r in ws]
len_num = len(dirpath)
datalist = []
for i in range(1, len_num):
temp_tuple = (dirpath[i], file_before[i],file_after[i])
datalist.append(temp_tuple)
return datalist
In [22]:
rename_list = excelRead(os.path.join(target_path,'filelist.xlsx'))
print(rename_list)
[('./고라니/', 'A_2022_01_13_부서로그_인사_001.pdf', 'A_2022_01_13_부서로그_인사_001.pdf'), ('./고라니/', 'A_2022_01_13_부서로그_인사_002.pdf', 'A_2022_01_13_부서로그_인사_002.pdf'), ('./고라니/', 'A_2022_01_13_부서로그_인사_003.pdf', 'A_2022_01_13_부서로그_인사_003.pdf'), ('./고라니/', 'A_2022_04_10_생산로그_생산_001.pdf', 'A_2022_04_10_생산로그_생산_001.pdf'), ('./고라니/', 'A_2022_04_10_생산로그_생산_002.pdf', 'A_2022_04_10_생산로그_생산_002.pdf'), ('./고라니/', 'A_2022_04_10_생산로그_생산_003.pdf', 'A_2022_04_10_생산로그_생산_003.pdf'), ('./고라니/', 'A_2022_04_10_생산로그_생산_004.pdf', 'A_2022_04_10_생산로그_생산_004.pdf'), ('./고라니/', 'A_2022_06_30_생산로그_생산_001.pdf', 'A_2022_06_30_생산로그_생산_001.pdf'), ('./고라니/', 'A_2022_06_30_생산로그_생산_002.pdf', 'A_2022_06_30_생산로그_생산_002.pdf'), ('./고라니/', 'A_2022_07_20_부서로그_인사_001.pdf', 'A_2022_07_20_부서로그_인사_001.pdf'), ('./고라니/', 'A_2022_07_20_부서로그_인사_002.pdf', 'A_2022_07_20_부서로그_인사_002.pdf'), ('./고라니/', 'A_2022_07_20_부서로그_인사_003.pdf', 'A_2022_07_20_부서로그_인사_003.pdf'), ('./고라니/', 'A_2022_07_20_부서로그_인사_004 (1).pdf', 'A_2022_07_20_부서로그_인사_004.pdf'), ('./고라니/', 'B_2022_02_20_상반기_클래스설계_001.xlsx', 'B_2022_02_20_상반기_클래스설계_001.xlsx'), ('./고라니/', 'B_2022_02_20_상반기_클래스설계_002.xlsx', 'B_2022_02_20_상반기_클래스설계_002.xlsx'), ('./고라니/', 'B_2022_06_20_하반기_클래스설계_001.xlsx', 'B_2022_06_20_하반기_클래스설계_001.xlsx'), ('./고라니/', 'B_2022_06_30_하반기_클래스설계_002.xlsx', 'B_2022_06_30_하반기_클래스설계_002.xlsx'), ('./고라니/', 'C_2022_03_30_데이터베이스_ERD_001.xlsx', 'C_2022_03_30_데이터베이스_ERD_001.xlsx'), ('./고라니/', 'C_2022_03_30_데이터베이스_ERD_002.xlsx', 'C_2022_03_30_데이터베이스_ERD_002.xlsx'), ('./고라니/', 'C_2022_03_30_데이터베이스_ERD_003.xlsx', 'C_2022_03_30_데이터베이스_ERD_003.xlsx'), ('./고라니/', 'C_2022_09_10_데이터베이스_ERD_001 (1).xlsx', 'C_2022_09_10_데이터베이스_ERD_001.xlsx'), ('./고라니/', 'C_2022_09_10_데이터베이스_ERD_002.xlsx', 'C_2022_09_10_데이터베이스_ERD_002.xlsx'), ('./고라니/', 'C_2022_09_10_데이터베이스_ERD_003.xlsx', 'C_2022_09_10_데이터베이스_ERD_003.xlsx'), ('./고라니/', 'D_20220110_데이터저장_물류_001.pdf', 'D_20220110_데이터저장_물류_001.pdf'), ('./고라니/', 'D_20220110_데이터저장_물류_002.pdf', 'D_20220110_데이터저장_물류_002.pdf'), ('./고라니/', 'D_20220723_데이터저장_물류_001.pdf', 'D_20220723_데이터저장_물류_001.pdf'), ('./고라니/', 'D_20220723_센터가동현황_물류_002.pdf', 'D_20220723_센터가동현황_물류_002.pdf'), ('./고라니/', '내사진.jpg', '강사님사진.jpg'), ('./고라니/', '데이터저장_물류.zip', '데이터저장_물류.zip'), ('./고라니/', '새파일1_복사본.txt', '새파일1_복사본.txt'), ('./고라니/', '점심시간.txt', '저녁시간.txt'), ('./고라니/', '주피터노트북.txt', '주피터노트북.txt')]
In [23]:
import shutil
def fileRename(datalist : list):
for data in datalist:
print(data[1] + '의 파일명을 ' + data[2] + '로 변경합니다.')
shutil.move(data[0]+data[1], data[0]+data[2])
In [24]:
# import shutil
# def fileRename(datalist : list):
# for data in datalist:
# print(data[1]+'의 파일명을'+data[2]+'로 변경합니다.')
# shutil.move(data[0]+data[2,data[0]+data[1]])
In [25]:
fileRename(rename_list)
A_2022_01_13_부서로그_인사_001.pdf의 파일명을 A_2022_01_13_부서로그_인사_001.pdf로 변경합니다.
A_2022_01_13_부서로그_인사_002.pdf의 파일명을 A_2022_01_13_부서로그_인사_002.pdf로 변경합니다.
A_2022_01_13_부서로그_인사_003.pdf의 파일명을 A_2022_01_13_부서로그_인사_003.pdf로 변경합니다.
A_2022_04_10_생산로그_생산_001.pdf의 파일명을 A_2022_04_10_생산로그_생산_001.pdf로 변경합니다.
A_2022_04_10_생산로그_생산_002.pdf의 파일명을 A_2022_04_10_생산로그_생산_002.pdf로 변경합니다.
A_2022_04_10_생산로그_생산_003.pdf의 파일명을 A_2022_04_10_생산로그_생산_003.pdf로 변경합니다.
A_2022_04_10_생산로그_생산_004.pdf의 파일명을 A_2022_04_10_생산로그_생산_004.pdf로 변경합니다.
A_2022_06_30_생산로그_생산_001.pdf의 파일명을 A_2022_06_30_생산로그_생산_001.pdf로 변경합니다.
A_2022_06_30_생산로그_생산_002.pdf의 파일명을 A_2022_06_30_생산로그_생산_002.pdf로 변경합니다.
A_2022_07_20_부서로그_인사_001.pdf의 파일명을 A_2022_07_20_부서로그_인사_001.pdf로 변경합니다.
A_2022_07_20_부서로그_인사_002.pdf의 파일명을 A_2022_07_20_부서로그_인사_002.pdf로 변경합니다.
A_2022_07_20_부서로그_인사_003.pdf의 파일명을 A_2022_07_20_부서로그_인사_003.pdf로 변경합니다.
A_2022_07_20_부서로그_인사_004 (1).pdf의 파일명을 A_2022_07_20_부서로그_인사_004.pdf로 변경합니다.
B_2022_02_20_상반기_클래스설계_001.xlsx의 파일명을 B_2022_02_20_상반기_클래스설계_001.xlsx로 변경합니다.
B_2022_02_20_상반기_클래스설계_002.xlsx의 파일명을 B_2022_02_20_상반기_클래스설계_002.xlsx로 변경합니다.
B_2022_06_20_하반기_클래스설계_001.xlsx의 파일명을 B_2022_06_20_하반기_클래스설계_001.xlsx로 변경합니다.
B_2022_06_30_하반기_클래스설계_002.xlsx의 파일명을 B_2022_06_30_하반기_클래스설계_002.xlsx로 변경합니다.
C_2022_03_30_데이터베이스_ERD_001.xlsx의 파일명을 C_2022_03_30_데이터베이스_ERD_001.xlsx로 변경합니다.
C_2022_03_30_데이터베이스_ERD_002.xlsx의 파일명을 C_2022_03_30_데이터베이스_ERD_002.xlsx로 변경합니다.
C_2022_03_30_데이터베이스_ERD_003.xlsx의 파일명을 C_2022_03_30_데이터베이스_ERD_003.xlsx로 변경합니다.
C_2022_09_10_데이터베이스_ERD_001 (1).xlsx의 파일명을 C_2022_09_10_데이터베이스_ERD_001.xlsx로 변경합니다.
C_2022_09_10_데이터베이스_ERD_002.xlsx의 파일명을 C_2022_09_10_데이터베이스_ERD_002.xlsx로 변경합니다.
C_2022_09_10_데이터베이스_ERD_003.xlsx의 파일명을 C_2022_09_10_데이터베이스_ERD_003.xlsx로 변경합니다.
D_20220110_데이터저장_물류_001.pdf의 파일명을 D_20220110_데이터저장_물류_001.pdf로 변경합니다.
D_20220110_데이터저장_물류_002.pdf의 파일명을 D_20220110_데이터저장_물류_002.pdf로 변경합니다.
D_20220723_데이터저장_물류_001.pdf의 파일명을 D_20220723_데이터저장_물류_001.pdf로 변경합니다.
D_20220723_센터가동현황_물류_002.pdf의 파일명을 D_20220723_센터가동현황_물류_002.pdf로 변경합니다.
내사진.jpg의 파일명을 강사님사진.jpg로 변경합니다.
데이터저장_물류.zip의 파일명을 데이터저장_물류.zip로 변경합니다.
새파일1_복사본.txt의 파일명을 새파일1_복사본.txt로 변경합니다.
점심시간.txt의 파일명을 저녁시간.txt로 변경합니다.
주피터노트북.txt의 파일명을 주피터노트북.txt로 변경합니다.
4. 폴더 생성하기
In [22]:
import fnmatch
In [23]:
def categoryList(target_path : str) -> list:
file_list = []
for filename in os. listdir(target_path):
if fnmatch. fnmatch(filename,'*_[0-9][0-9][0-9].*'):
file_list.append(filename)
category = []
for file in file_list:
#B_2022_02_20_상반기_클래스설계_001.xisx
temp_list = file.split('_')
category.append(temp_list[-2])
temp_set = set(category)
result = list(temp_set)
return result
In [24]:
categoryList(target_path)
Out[24]:
['인사', '물류', '생산', 'ERD', '클래스설계']
In [25]:
categorylist = categoryList(target_path)+['기타']
print(categorylist)
['인사', '물류', '생산', 'ERD', '클래스설계', '기타']
In [26]:
import pathlib
In [27]:
new_path = './new_dir'
def makeDir(new_path:str, categorylist:list):
for category in categorylist:
new_dir= pathlib.Path(os.path.join(new_path, category))
new_dir.mkdir(parents=True,exist_ok=True)
In [28]:
makeDir(new_path,categorylist)
5. 파일 분류 및 이동하기
In [29]:
import shutil
In [33]:
def moveFile(new_path, target_path,categorylist):
dirlist = os.listdir(new_path) # 이동시킬 경로에 생성된 분류 디렉토리 리스트
filelist= os.listdir(target_path) #이동시킬 파일명 리스트
categorydic = {}
for file in filelist:
try :
temp_list = file. split('_')
assert temp_list[-2] in categorylist #카테고리가 맞지 않으면 에러 발생
categorydic[file] = temp_list[-2] #{'파일명':'분류명'}
except:
categorydic[file] = '기타' #{'파일명' : '기타'}
# print(categorydic)
for key, value in categorydic.items():
shutil.copy(target_path+"/"+key,new_path+"/"+value)
In [34]:
moveFile(new_path, target_path, categorylist)
과제
노트북에 어질러져 있는 파일이나 파일을 만들어 또는 시나리오를 만들어 파일정리 프로그래밍을 한다.
728x90
반응형
'학습일지' 카테고리의 다른 글
20230316 kdt 수업일지 (0) | 2023.03.16 |
---|---|
20230315 kdt 학습일지 (0) | 2023.03.15 |
20230313 kdt 학습 일지 (1) | 2023.03.14 |
20230310 KDT 학습일지 (0) | 2023.03.10 |
20230309 KDT 학습일지 (0) | 2023.03.10 |