10 excel, csv 파일 읽기, 쓰기

|

10 excel, csv 파일 읽기, 쓰기

CSV : MIME - text/csv 타입 csv를 제어하려면 아래처럼 import 해야한다.

import csv # 기본 제공

예제1

# open으로 파일을 열때 인코딩 타입 정해주려면 세 번째 인자로 넣어준다.
with open('./resource/sample1.csv', 'r', encoding='euc-kr') as f:
    reader = csv.reader(f)
    next(reader) # Header 스킵 - 라인 스킵한다 보면 됨
    # 확인
    print(reader)
    print(type(reader))
    print(dir(reader))
    # 메소드 속성 확인, __iter__가 있으면 순회 가능한 것이니 for 돌려볼 수 있다.
    print()

    for c in reader:
        print(c)

예제2

csv 구분자는 대부분 ,(콤마)로 되어있는데, 가끔 |같은 문자로 구분될 때도 있다. 이때는 reader()함수에 delimiter키워드로 구분자를 지정해준다.

with open('./resource/sample2.csv', 'r', encoding='euc-kr') as f:
    reader = csv.reader(f, delimiter='|') # 구분자 정해주는 키워드
    next(reader) # Header 스킵 - 라인 스킵한다 보면 됨
    # 확인
    print(reader)
    print(type(reader))
    print(dir(reader))
    # 메소드 속성 확인, __iter__가 있으면 순회 가능한 것이니 for 돌려보면 좋
    print()

    for c in reader:
        print(c)

예제3 (Dict변환)

with open('./resource/sample1.csv', 'r', encoding='euc-kr') as f:
    reader = csv.DictReader(f)

    for c in reader:
        for k, v in c.items():
            print(k, v)
        print('----------')

예제4 - 쓰기

w = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]

with open('./resource/sample3.csv', 'w', newline='') as f: # newline으로 개행 제거
    wt = csv.writer(f)
    for v in w: # if문 같은 거 쓸 때 활
        wt.writerow(v)

예제5

with open('./resource/sample4.csv', 'w', newline='') as f:
# newline으로 개행 제거
    wt = csv.writer(f)
    wt.writerows(w) # 한번에 다 입용력

# XSL, XLSX
# openpyxl, xlsxwriter, xlrd, xlwt, xlutils
# pandas 를 주로 사용(openpyxl, xlrd 같이)
# pip install xlrd
# pip install openpyxl
# pip install pandas

import pandas as pd

# sheetname='시트명' 또는 숫자, header=숫자(몇번째를 헤더로 정할), skiprow=숫자(몇번째 행은 안가져올지)
xlsx = pd.read_excel('./resource/sample.xlsx')

# 상위 데이터 확인
print(xlsx.head()) # 다섯개 보여줌
print()

# 데이터 확인
print(xlsx.tail()) # 끝에 다섯개 보여줌

# 데이터 확인
print(xlsx.shape) # 행, 열 반

# 엑셀 or CSV 다시 쓰기
xlsx.to_excel('./resource/result.xlsx', index=False)
xlsx.to_csv('./resource/result.csv', index=False)

09 에러 및 예외 처리

|

09 에러 및 예외 처리

완벽한 프로그램은 없고, 에러는 늘 발생한다. 우리는 발생한 에러에 대해 적절한 조치를 취해줘야한다. 항상 예외가 발생하지 않을 것으로 가정하고 먼저 코딩하고, 그 후 런타임 예외 발생시 예외 처리 코딩 권장 (EAFP 코딩 스타일)

예외 종류

문법적으로 에러가 없지만, 코드 실행(런타임) 프로세스에서 발생하는 예외 처리도 중요

  • linter: 코드 스타일, 문법 체크
  • SyntaxError: 잘못된 문법
    print('Test)
    if True
     pass
    x => y
    
  • NameError: 참조변수 없음
    a = 10
    b = 15
    print(c)
    # c는 선언한 적 없음
    
  • ZeroDivisionError: 0 나누기 에러
    print(10 / 0)
    
  • IndexError: 인데스 범위 오버
    x = [10, 20, 30]
    print(x[0])
    print(x[3]) # 예외 발생
    
  • KeyError
    dic = {
     'Name' : 'Kim',
     'Age': 33,
    }
    print(dic['asdf'])
    print(dic.get('hobby')) # get 메소드 추천, 없으면 None 반환
    
  • AttributeError: 모듈, 클래스에 있는 잘못된 속성 사용시에 예외
    import time
    print(time.time())
    print(time.month())
    
  • ValueError: 참조 값이 없을 때 발생
    x = [1, 5, 9]
    x.remove(10)
    x.index(10)
    
  • FileNotFoundError: 파일이 못 찾을 때 발생
    f = open('test.txt', 'r')
    
  • TypeError ```python x = [1, 2] y = (1, 2) z = ‘test’ print(x + y) #예외 print(x + z)

print(x + list(y)) # 형 변환해서 해결


#### 예외 처리 기본 문법
```python
try : 에러가 발생할 가능성이 있는 코드 실행
except : 에러명1
except : 에러명2
else : 에러가 발생하지 않았을 경우 실행
finally : 항상 실행

예제1

에러명을 명시해 주기

name = ['kim', 'lee', 'park']

try:
    z = 'kim' # 리스트에 없는값 하면 에러 발
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except ValueError:
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')

예제2

에러명 명시 안하기

try:
    z = 'ki2m'
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except: # 에러명 없이하면 여기에 다 들어
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')

예제3

finally 사용

try:
    z = 'kim2'
    x = name.index(z)
    print('{} Found it! in name'.format(z, x+1))
except:
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')
finally:
    # db 연결 끊는것 처럼, 에러가 안발생해도 끊고, 발생해도 끊을 때 사용하면 좋음
    print('finally ok!')

예제4

예외 처리는 하지 않지만, 무조건 수행되는 코딩 패턴

try:
    print('Try')
finally:
    print('Ok Finally')

예제5 - 계층적으로 처

try:
    z = 'kim2'
    x = name.index(z)
    print('{} Found it! in name {}'.format(z, x+1))
except ValueError as l: # 에러 메세지 표시
    print('Not found it! - ValueError!')
except IndexError:
    print('Not found it! - IndexError!')
except Exception: # 가장 마지막에 두기
    print('Not found it! - Occurred ValueError!')
else:
    print('Ok! else!')
finally:
    # db 연결 끊는것 처럼, 에러가 안발생해도 끊고, 발생해도 끊을 때 사용하면 좋음
    print('finally ok!')

예제6

예외 발생 : raise raise 키워드로 예외 직접 발생시킬 수 있다.

try:
    a = 'Ki2m'
    if a == 'Kim':
        print('ok 허가!')
    else:
        raise IndexError # 내가 규정하기
except IndexError:
    print('문제 발생!')
except Exception as f:
    print(f) # 에러 메세지가 없어서 출력이 안될것이다.
    print('다른 오류 발생')
else:
    print('Ok!')

08 파일 읽기, 쓰기

|

08 파일 읽기, 쓰기

파일 읽기, 쓰기

파일 읽고 쓰기를 통해서 텍스트에서 내용을 가져와 활용할 수도 있고, 엑셀이나 csv같은 파일을 갖고 와 가공하여 정보로 사용할 수 있다. 파이썬에서는 세 가지의 모드가 있다.

  1. 읽기 모드 r - 파일 읽기만 할 때 사용
  2. 쓰기 모드 w - 파일 내용 쓸 때, 다시 작성하면 기존 파일 삭제
  3. 추가 모드 a - 파일 내용 쓸 때, w와 달리 밑에 내용이 추가됨

예제1 - 파일 읽기

파일을 읽고 쓸 때는 open 함수를 사용하여 제어한다. 첫 번째 인자에는 제어할 파일경로/파일명을 두 번째는 모드에 대해 지정한다.

f = open('./resource/review.txt', 'r') # 절대경로와 읽기모드
content = f.read()
print(content)
print(dir(f))
# 반드시 close 리소스 반환해야한다.
f.close()

read()함수는 전체 문장을 읽어서 표시한다. 그리고 읽고 나서는 리소스를 꼭 반환해야해서 close()를 호출해준다.

예제2

close 항상 하기 귀찮고 잊을 수 있기에 with문을 써서 자동 반환해줄 수 있다!

with open('./resource/review.txt', 'r') as f:
    c = f.read()
    print(c)
    print(list(c)) # 문자열이기에 list로 형변환 해줄 수 있다.
    print(iter(c)) # 리스트는 iterable기에 iter를 호출해볼 수 있다.

예제3

open함수도 아마 iterable 객체로 주는지, for문으로 순회 가능하다.

with open('./resource/review.txt', 'r') as f:
    for c in f:
        print(c.strip())

예제4

읽고, 쓰기에서는 커서라는 개념도 있는데, 우리가 흔히 말하는 마우스 커서같이 위치를 알려주는 개념이라 생각하면 될거 같다. read()함수를 사용하면 전체를 다 읽기에, 커서가 문서 끝으로 가기 때문에 한 번 더 read()함수를 호출해도 이미 문서 끝이기에 아무 내용이 없다.

with open('./resource/review.txt', 'r') as f:
    content = f.read()
    print(">", content)
    # 한 번 읽으면 커서가 끝으로 가서 출력이 안됨
    content = f.read() # 내용이 없음
    print(">", content)

####예제5

한 문장씩 처리

read()함수를 사용하면 전체를 읽기 때문에, 한 문장씩 제어가 위해서는 readline()함수를 이용할 수 있다.

with open('./resource/review.txt', 'r') as f:
    line = f.readline()
    # print(line)
    while line: # NULL될때까지
        print(line, end='###')
        line = f.readline()

예제6

readlines()를 이용하면 문장을 리스트 형태로 저장해서 좀 더 편하게 순회할 수 있다.

with open('./resource/review.txt', 'r') as f:
    contents = f.readlines() # 리스트 형태로 저장
    print(contents)
    for c in contents:
        print(c, end=' ****** ')

예제7

score = []
with open('./resource/score.txt', 'r') as f:
    for line in f:
        score.append(int(line))
    print(score)

print('average : {:6.3}'.format(sum(score)/len(score)))
# 여섯 자리, 소수점 세자리까

파일 쓰기

파일을 읽어봤으면, 쓰기도 해봐야 하는법! 마찬가지로 open함수를 쓰는데 두 번째 인자로 ‘w’, ‘a’를 사용하면 된다.

with open('./resource/text1.txt', 'w') as f:
    f.write('Niceman!\n')

with open('./resource/text1.txt', 'a') as f:
    f.write('Goodman!\n')

‘w’로 호출하면, 만약 기존 파일에 내용이 있으면 전부 삭제되고 새로운 내용이 추가되고, ‘a’로 호출하면 그 다음 줄에 추가된다. 상황에 따라 적절한 옵션을 넣어주면 된다.

예제8

랜덤한 숫자를 넣어보는 예제이다.

from random import randint
with open('./resource/text2.txt', 'w') as f:
    for cnt in range(6):
        f.write(str(randint(1, 50)))
        f.write('\n')

예제9

writelines()를 통해 리스트를 통째로 넣을 수 있다.

# wrtielines : 리스트 -> 파일로 저장
with open('./resource/text3.txt', 'w') as f:
    list = ['Kim\n','Park\n','Hong\n']
    f.writelines(list)

예제10

print() 함수를 통해서도, 내용을 집어넣을 수 있다.

# 프린트 문 활용
with open('./resource/text4.txt', 'w') as f:
    print("test Contents1!", file=f)
    print("test Contents12", file=f)

07 모듈과 패키지

|

07 모듈과 패키지

파이썬은 다른 능력자분들이 미리 만들어둔 파이썬 파일들을 불러와서 함수나 클래스들을 호출할 수 있고, 이를 통해 크롤링이나 엑셀 제어 등 다양한 업무를 수행할 수 있다. 이때 불러온 파이썬 파일을 모듈이라고 부른다. 나도 언젠간 그런 모듈을 배포할 수 있는 개발자가 되기를 희망하며 열심히 공부해야겠다!

모듈을 불러올 때는 경로명을 입력해줘야 하는데 절대경로와 상대경로가 있다.

  • 절대 경로: 최초의 시작점부터 원하는 파일명까지 가는 경로.
    • ex) C:\Users\hsj4665\Desktop\study\test.py
  • 상대 경로: 현재 위치에서 원하는 파일명까지 가는 경로
    • .. : 부모 디렉토리
    • . : 현재 디렉토리
    • ex) ./test2.py 현재 폴더에 있는 test2.py파일에 접근

문법

# 모듈 임포트 할 때
import 파일명 (.py는 제외)
파일명.함수()
파일명.클래스()
이런식으로 호출

# 모듈에서 특정 함수나 클래스를 사용할 때
from 파일명 import 함수 또는 클래스
함수()
클래스()
이런식으로 호출

사용1(클래스)

from pkg.fibonacci import Fibonacci

Fibonacci.fib(300)

print("ex1 :", Fibonacci.fib2(400))
print("ex1: ", Fibonacci(title="test").title)

사용2(클래스) * 사용 메모리 많이 사용돼서 권장 x

from pkg.fibonacci import *

Fibonacci.fib(300)

print("ex2 :", Fibonacci.fib2(400))
print("ex2: ", Fibonacci(title="test").title)

사용3(클래스) - 이름이 길 때 as 활용

from pkg.fibonacci import Fibonacci as fb

fb.fib(300)

print("ex3 :", fb.fib2(400))
print("ex3: ", fb(title="tasdest").title)

사용4(함수)

import pkg.calculations as c

print("ex4 :", c.add(10,100))

사용5(함수) - 권장

from pkg.calculations import div as d
print("ex5 : ", int(d(100,10)))

사용6

import pkg.prints as P
import builtins
P.prt1()
P.prt2()
print(dir(builtins))

모듈에 보이는 if __name__ == "__main__":

기본적으로 모듈을 호출하면 모듈의 파일이 실행되는 식이다 보니 테스트 용으로 사용한 함수나 클래스가 실행 될 수도 있다. 이를 방지하기 위해 if __name__ == "__main__"를 사용하여 본래 파일을 실행할 때에만, 함수나 클래스가 실행되도록 한다.

06 클래스

|

06 클래스

참고

애스크장고 AskDjango

파이썬은 객체지향언어이다.

OOP 주요 특징

  • Encapsulation (캡슐화): 관련 특성/기능을 하나의 클래스에 결합
  • Inheritance (상속): 코드 재활용성 증대
    • 부모 클래스의 특성/기능을 자식 클래스가 물려받음
    • 자식 클래스는 물려받은 특성/기능을 활용/변경/무시/재정의
  • Polymorphism (다형성): 다른 동작을 동일한 함수로 사용할 수 있도록 지원

클래스 정의

class 이름: 이름은 CamelCase 형태로 해준다.

  • snake_case: 소문자와 언더바(_)의 구성으로 함수에서 권장하는 형식
  • CamelCase: 단어를 이어 쓰며 대문자로 단어를 구분하는 형식, 클래스에 권장

클래스 사용 전

from math import sqrt

def get_area(circle):
    return circle['radius'] ** 2
def get_distance(circle1, circle2):
    return sqrt((circle1['x'] - circle2['x']) ** 2 + (circle1['y'] - circle2['y']) ** 2) \
    - (circle1['radius'] + circle2['radius']) # 코드를 다음줄로 이어가려면 '\'를 입력해 주자.

circle1 = {'x':10, 'y':20, 'radius':3}
circle2 = {'x':100, 'y':-40, 'radius':10}

get_area(circle1)
# 9

get_area(circle2)
# 100

get_distance(circle1, circle2)
# 95.16653826391968

가독성이 그리 좋지가 않다.

클래스 사용 후

from math import sqrt

class Circle:
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius
    def area(self):
        return self.radius ** 2
    def distance(self, other):
        return sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2) - (self.radius + other.radius)        

circle1 = Circle(10,20,3)
# 객체 생성 시에, 생성자 함수가 호출되며 인자가 전달
circle1.area() # 9

circle2 = Circle(100, -40, 10)
circle2.area() # 100

circle1.distance(circle2)
# self에는 자신이, other에는 circle2가 들어간다.
# 95.16653826391968

데이터와 함수를 클래스에 소속시킴으로써, 보다 깔끔하게 처리할 수 있다.

상속

상속에 대해 배워보자