# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# + [markdown] slideshow={"slide_type": "slide"}
# ## File, Pickle, OS
#
# 1. File
# 1. Pickle
# 1. OS

# + [markdown] slideshow={"slide_type": "slide"}
# ### 1. File
# python을 이용하여 파일을 쓰고 읽기가 가능합니다. 파일 쓰고 읽기의 옵션은 아래와 같습니다.
#
# - 파일 쓰기 읽기 옵션
#     - 파일 쓰기 (w) : 파일이 존재하면 덮어씀 
#     - 파일 쓰기 (x) : 파일이 존재하지 않을때만 생성 
#     - 파일 읽기 (r) 
#     - 파일 추가 (a) 
#
# - 파일 타입 옵션
#     - 텍스트 타입 (t) 
#     - 이진 타입 (b)

# + [markdown] slideshow={"slide_type": "slide"}
# #### 1.1 파일 쓰기 - write
#
# 1. 텍스트 파일쓰기
# 1. 바이너리(2진, binary) 파일 쓰기
# -

# !mkdir file

# + [markdown] slideshow={"slide_type": "slide"}
# ##### 1.1.1 텍스트 파일 쓰기 (옵션 : wt) - write
# -

s = """datascicence
jupyter notebook write
fighting!!
"""
f = open("file/test1.txt", 'wt')
f.write(s)
f.close()

# !cat file/test1.txt

# !tree file

# + [markdown] slideshow={"slide_type": "slide"}
# print를 이용하여 파일쓰기 (옵션 : wt) - write

# +
s = """datascicence
jupyter notebook print"""

f = open("file/test2.txt", 'wt')
print(s, file=f, end="\n")
f.close()
# -

# !cat file/test2.txt

# + [markdown] slideshow={"slide_type": "slide"}
# 파일이 존재 하지 않을때만 파일 쓰기 (옵션 : xt) - write

# +
s = """datascicence
jupyter notebook write x"""

# 이미 파일이 있어서 파일 작성이 안됩니다.
# f = open("file/test2.txt", 'xt') 
f = open("file/test3.txt", 'xt')
f.write(s)
f.close()
# -

# !cat file/test3.txt

# + [markdown] slideshow={"slide_type": "slide"}
# ##### 1.1.2 바이너리(binary) 파일 쓰기  (옵션 : wb) - write
# bytes : 2진 데이터로 형변환 시켜줌 
#
# 2진 데이터로 형변환 후 저장해야 저장이 가능합니다.

# +
data = bytes(range(5, 10))

f = open("file/b_range.b", 'wb')
f.write(data)
f.close()

data
# -

# !cat file/b_range.b

# + [markdown] slideshow={"slide_type": "slide"}
# #### 1.2 파일 읽기 - read
#
# 1. 텍스트 파일 읽기
# 1. 바이너리 파일 읽기

# + [markdown] slideshow={"slide_type": "slide"}
# ##### 1.2.1 텍스트 파일 읽기
# -

# 텍스트 파일의 모두 읽어오기 (옵션 : rt) - read

f = open("file/test1.txt", 'rt')
s = f.read()
f.close()
print(s)

# + [markdown] slideshow={"slide_type": "-"}
# 텍스트 파일의 모두 읽어오기 (옵션 : rt) - read
# -

f = open("file/test2.txt", 'rt')
s = f.read()
f.close()
print(s)

# + [markdown] slideshow={"slide_type": "slide"}
# 텍스트 파일의 일부만 읽어오기 (옵션 : rt) - read
# -

# 일부만 읽기
f = open("file/test1.txt", 'rt')
s = f.read(15) # 15자만 읽어옴
f.close()
print(s, len(s))

# + [markdown] slideshow={"slide_type": "-"}
# 텍스트 파일의 한줄 읽어오기 (옵션 : rt) - readline

# +
f = open("file/test1.txt", 'rt')

s = f.readline()
print(s, end="")

s = f.readline()
print(s)

f.close()

# + [markdown] slideshow={"slide_type": "slide"}
# 텍스트 파일 두줄 읽기 (옵션 : rt) - readline 
#
# for문을 이용하여 f.readline을 실행하면 한줄씩 순서대로 읽어 옵니다.
# -

f = open("file/test1.txt", 'rt')
for _ in range(2):
    s = f.readline()
    print(s, end="")
f.close()

# + [markdown] slideshow={"slide_type": "-"}
# 텍스트 파일 끝까지 읽기 (옵션 : rt) - readline 
#
# while 반복문을 사용하여 문자열이 없을때까지 읽어오는 코드입니다.
# -

f = open("file/test1.txt", 'rt')
while True:
    s = f.readline()
    if not s:
        break
    print(s, end="")
f.close()

# + [markdown] slideshow={"slide_type": "slide"}
# 여러줄을 리스트로 읽어오기 - readlines
#
# readlines 함수를 사용하면 여러줄을 리스트로 읽어올수 있습니다.

# +
f = open("file/test1.txt", 'rt')

s = f.readlines()
print(s)

f.close()

# + [markdown] slideshow={"slide_type": "-"}
# ##### 1.2.2 바이너리(2진, binary) 파일 읽기
# -

# open 함수에서 rb 옵션으로 이진데이터를 읽어 올수 있습니다.

# +
f = open("file/b_range.b", 'rb')

data = f.read()
print(list(data))

f.close()

# + [markdown] slideshow={"slide_type": "slide"}
# 파일 추가(a) - open 함수에서 a옵션을 주면 원래 있던 파일의 내용에 추가로 문자열을 넣을수 있습니다.
# -

s = "\npython"
f = open("file/test1.txt", 'at')
f.write(s)
f.close()

f = open("file/test1.txt", 'rt')
s = f.read()
print(s)
f.close()

# + [markdown] slideshow={"slide_type": "slide"}
# #### 1.3 with
# with를 사용하면 close를 안써도 자동으로 close를 하여 파일을 읽고 쓸때 조금 더 편리합니다.
# -

test = open("file/test1.txt", 'rt')
with test as f: 
    s = f.read()
    print(s)    

# + [markdown] slideshow={"slide_type": "skip"}
# ### Quiz
# - 아래의 텍스트 데이터를 `file/grade.csv` 파일이름으로 저장하고 num이 2 ~ 4줄을 읽어와 print문으로 아래의 결과와 같이 출력되는 코드를 작성하세요.
#
# ```
# num, subject, points
# 1, Math, 90
# 2, Korean, 80
# 3, English, 100
# 4, Science, 70
# 5, Computer, 90
#
# 결과
# num, subject, points
# 2, Korean, 80
# 3, English, 100
# 4, Science, 70
# ```

# + slideshow={"slide_type": "skip"}
# TODO
grade = """num, subject, points
1, Math, 90
2, Korean, 80
3, English, 100
4, Science, 70
5, Computer, 90"""

with open("file/grade.csv", "wt") as f:
    f.write(grade)

# + slideshow={"slide_type": "skip"}
with open("file/grade.csv", "rt") as f:
    csv = f.readlines()

def read_csv(csv, start, end):
    result = csv[0:1] + csv[start:end+1]
    print("".join(result)[:-1])


# + slideshow={"slide_type": "skip"}
read_csv(csv, 1, 4)

# + [markdown] slideshow={"slide_type": "slide"}
# ### 2. Pickle
# - 객체를 파일로 저장하는것을 직렬화(serialization) 이라고 합니다.
# - pickle을 사용하여 객체를 직렬화 하여 저장할수 있습니다.
# - pickle은 파이썬에서 직렬화를 통해 바이너리 형태의 데이터를 저장하고 복원하는 모듈입니다.

# + slideshow={"slide_type": "slide"}
import pickle

class A():
    
    def __init__(self, data):
        self.data = data
        
    def disp(self):
        print(self.data)
        
a = A("pickle test")

a.disp()

# + [markdown] slideshow={"slide_type": "slide"}
# #### 2.1 객체 저장하기
# -

f = open("file/obj.pkl", "wb")
pickle.dump(a, f)
f.close()

with open("file/obj.pkl", "wb") as f:
    pickle.dump(a, f)

# + [markdown] slideshow={"slide_type": "-"}
# #### 2.2 객체 로드하기

# +
with open("file/obj.pkl", "rb") as f:
    a = pickle.load(f)
    
a.disp()

# + [markdown] slideshow={"slide_type": "slide"}
# ### 3. OS
# 파일시스템을 파이썬 코드로 컨트롤 할수 있는 패키지입니다.
#
# 1. 디렉토리 만들기
# 1. 파일리스트 읽기
# 1. 파일 삭제
# 1. 디렉토리 삭제
# 1. 파일과 디렉토리를 모두 삭제
# 1. 파일 존재 여부 확인
# 1. 파일 타입이 디렉토리인지 확인
# 1. 복사하기
# 1. 파일 이름 변경하기
# 1. 권한설정
# -

import os

# %ls

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.1 디렉토리 만들기
# -

os.makedirs("os_dir")

# %ls

# + slideshow={"slide_type": "-"}
s = "data science"
with open("os_dir/test.txt", "wt") as f:
    f.write(s)

s2 = "data science2"
with open("os_dir/test2.txt", "wt") as f:
    f.write(s)

s3 = "data,science2"
with open("os_dir/test3.csv", "wt") as f:
    f.write(s)


# -

# !ls os_dir

# + slideshow={"slide_type": "slide"}
def make_dir_files():
    
    os.makedirs("os_dir")
    
    s = "data science"
    with open("os_dir/test.txt", "wt") as f:
        f.write(s)

    s2 = "data science2"
    with open("os_dir/test2.txt", "wt") as f:
        f.write(s)

    s3 = "data,science2"
    with open("os_dir/test3.csv", "wt") as f:
        f.write(s)


# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.2 디렉토리내 파일 리스트 읽기
# -

os.listdir("os_dir")

# + [markdown] slideshow={"slide_type": "-"}
# #### 3.3 파일 삭제
# -

os.remove("os_dir/test3.csv")

os.listdir("os_dir")

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.4 디렉토리 삭제
# - 디렉토리내에 파일이 있으면 삭제가 안됩니다.
# -

try:
    os.removedirs("os_dir")
except Exception as e:
    print(e)


# + [markdown] slideshow={"slide_type": "skip"}
# ##### Quiz
# - 디렉토리 이름을 입력하면 디렉토리내에 모든 파일이 삭제되는 함수를 만드세요.

# + slideshow={"slide_type": "skip"}
# !ls os_dir

# + slideshow={"slide_type": "skip"}
def remove_files(path):
    files = os.listdir(path)
    for file in files:
        os.remove("{}/{}".format(path, file))


# + slideshow={"slide_type": "skip"}
remove_files("os_dir")

# + slideshow={"slide_type": "skip"}
os.listdir("os_dir")

# + slideshow={"slide_type": "skip"}
os.removedirs("os_dir")

# + slideshow={"slide_type": "skip"}
# %ls

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.5 파일과 디렉토리를 모두 삭제 - rmtree
# -

# 위에서 디렉토리와 파일을 다시 생성

make_dir_files()

# !tree os_dir

# + slideshow={"slide_type": "-"}
import shutil

shutil.rmtree("os_dir")
# -

# %ls

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.6 파일의 존재 여부 확인 - exists
# - 디렉토리와 파일이 있는지 확인
# -

# 위에서 디렉토리와 파일을 다시 생성

make_dir_files()

os.path.exists("os_dir/test.txt")

# %ls os_dir

os.path.exists("os_dir/test3.txt")

os.path.exists("os_dir")

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.7 파일 타입이 디렉토리인지 확인 - isdir
# -

os.path.isdir("os_dir")

os.path.isdir("os_dir/test.txt")

# + [markdown] slideshow={"slide_type": "-"}
# #### 3.8 복사하기
# -

# %ls os_dir

shutil.copy("os_dir/test.txt", "os_dir/copy.txt")

# %ls os_dir

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.9 이름 바꾸기
# -

# 이름 바꾸기 (!mv)
os.rename("os_dir/copy.txt", "os_dir/rename.txt")

# %ls os_dir

# + [markdown] slideshow={"slide_type": "slide"}
# #### 3.10 권한설정
# - windows os는 리눅스 계열과 파일 시스템의 규칙이 달라서 제대로 동작되지 않습니다.
# - `-rw-r--r--` : 10개의 문자로 이루어진 권한에 관련된 정보
#     - `[:1]` : 타입
#     - `[1:4]` : 소유자에 대한 파일의 권한
#     - `[4:7]` : 그룹에 대한 파일의 권한
#     - `[7:]` : 모든 사용자에 대한 파일의 권한
# - 권한
#     - rwx : r(읽기), w(쓰기), x(실행)
# - 권한 설정 진법(2진수, 8진수)    
#     - chmod 731 os_dir/test.txt
#     - 7(8) - 111 - rwx
#     - 5(8) - 101 - r-x

# + slideshow={"slide_type": "slide"}
# %ls -al os_dir
# -

import os
os.chmod("os_dir/test.txt", 0o200)

# %ls -al os_dir

# %cat os_dir/test.txt

# + slideshow={"slide_type": "slide"}
os.chmod("os_dir/test.txt", 0o400)
# -

# %ls -al os_dir

# %cat os_dir/test.txt

# + slideshow={"slide_type": "slide"}
# - rwx rx- -x-
os.chmod("os_dir/test.txt", 0o762)
# -

# %ls -al os_dir/test.txt

# +
# - -wx r-x --x
# 351

# + [markdown] slideshow={"slide_type": "-"}
# 테스트 디렉토리 제거
# -

# !rm -rf file

# !rm -rf os_dir



# #### 카테고리 분류기로 문서 분류하기

import os

# +
# 1. 디렉토리생성
# -

categories = {100:"정치", 101:"경제", 102:"사회", 103:"생활/문화", 104:"세계", 105:"IT/과학"}
categories.keys()

for dname in categories.keys():
    os.makedirs("articles/{}".format(dname))

# !ls articles

# +
# 2. 텍스트 리스트 가져오기
# -

articles = os.listdir("articles/texts")
len(articles), articles[:2]

# articles = !ls articles/texts
len(articles)

# +
# 3. 모델 불러오기

# +
import pickle

# 모델 불러오기
with open("articles/model.pkl", "rb") as f:
    model = pickle.load(f)

# +
# 텍스트 불러오기
with open("articles/texts/{}".format(articles[0]), "rt") as f:
    article_txt = f.read()

article_txt[:50]
# -

# 모델로 예측하기
category = model.predict([article_txt])[0]
category, categories[category]

# +
# 4. 파일 이동하기
# -

articles[0]

os.rename("articles/texts/{}".format(articles[0]), "articles/{}/{}".format(category, articles[0]))

# !ls articles/101

with open("articles/101/{}".format(articles[0]), "rt") as f:
    article_txt = f.read()
article_txt[:50]

# +
# 5. 반복문으로 만들기
# -

for idx, filename in enumerate(articles[1:]):

    # 1. 텍스트 불러오기
    with open("articles/texts/{}".format(filename), "rt") as f:
        article_txt = f.read()
        
    # 2. 모델로 카테고리 예측하기
    category = model.predict([article_txt])[0]
    
    # 3. 파일 이동하기
    os.rename("articles/texts/{}".format(filename), "articles/{}/{}".format(category, filename))
    
    print(idx, end=" ")

StarcoderdataJupyterScriptsDedupFiltered