본문 바로가기

Programming

[Python][문법] 기초 - 7. 파일 입출력_예외처리

반응형
#!/usr/bin/env python
# coding: utf-8

# # 1. 파일 입출력

# ### 1.1 파일 생성 및 열기

# <center>파일 열기 모드</center>| <center>설 명</center>
# ----|----
# <center>'r'</center> | <div style="text-align: left">읽기 모드로 연다. - Default</div>
# <center>'w'</center> | <div style="text-align: left">쓰기 모드로 연다. - 기존 내용 삭제</div>
# <center>'a'</center> | <div style="text-align: left">추가 모드로 연다.</div>    
# <center>'b'</center> | <div style="text-align: left">이진 모드로 연다.</div>    
# <center>'t'</center> | <div style="text-align: left">텍스트 모드로 연다. - Default</div>    

# #### write

# In[ ]:


fp = open('data/hello.txt', 'w')
fp.write('Hello World!')
fp.close()


# In[ ]:


fp = open('data/text.txt', 'w')
fp.write('{}\n'.format(1))
fp.write('{:.2f}\n'.format(3.1415))
fp.write('Hello World\n')
fp.write('서울과학종합대학원 빅데이터MBA\n')
fp.close()
 


# #### read line: 한줄씩 읽기

# In[ ]:


fp = open('data/text.txt', 'r')
line = fp.readline()
print(line.strip())

line = fp.readline()
print(line.strip())

line = fp.readline()
print(line.strip())

line = fp.readline()
print(line.strip())

fp.close()


# #### read lines: 여러줄을 한번에 읽어 리스트에 저장하기

# In[ ]:


fp = open('data/text.txt', 'r')
lines = fp.readlines()
print(lines)

fp.close()


# #### read: 파일 내용 모두 읽기

# In[ ]:


fp = open('data/text.txt', 'r')
contents = fp.read()
print(contents)

fp.close()


# #### 중요 파일 메서드와 속성
#
# <center>메서드| <center>설 명
# :---|:---
# read([size])        | <div style="text-align: left">파일에서 데이터를 읽어서 문자열로 반환한다. <br> size 인자를 사용해서 몇 바이트를 읽을 것인지 지정할 수 있다.
# readline([size])    | <div style="text-align: left">파일에서 한 줄을 읽어 문자열로 반환한다. <br> size 인자를 사용해서 몇 바이트를 읽을 것인지 지정할 수 있다.
# readlines([size])   | <div style="text-align: left">파일의 매 줄을 모두 읽어 리스트로 반환한다. <br> size 인자를 사용해서 몇 바이트를 읽을 것인지 지정할 수 있다.
# write(str)          | <div style="text-align: left">전달받은 문자열을 파일에 기록한다.
# writelines(strings) | <div style="text-align: left">전달받은 문자열 리스트를 파일에 기록한다.
# close()             | <div style="text-align: left">파일 핸들을 닫는다.
# flush()             | <div style="text-align: left">내부 I/O 버퍼를 디스크로 비운다.
# seek(pos)           | <div style="text-align: left">파일 내에서 지정한 위치(정수)로 이동한다.
# tell()              | <div style="text-align: left">현재 파일의 위치(정수)를 반환한다.
#

# ### 1.2 직렬화 / 역직렬화 (serialize / deserialize)

# #### <참고> Protocol Buffers

# In[ ]:


# pickle_dump

import pickle

fp = open('data/binary.dat', 'wb')

pickle.dump(1, fp)
pickle.dump(3.14, fp)
pickle.dump('Hello World', fp)
pickle.dump('서울과학종합대학원 빅데이터MBA', fp)
pickle.dump([1,2,3], fp)
pickle.dump((1,2,3), fp)
pickle.dump({'line':0, 'rectangle':1, 'triangle':2}, fp)

fp.close()


# In[ ]:


# pickle_load

import pickle

fp = open('data/binary.dat', 'rb')

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)

data = pickle.load(fp)
print(data)


fp.close()


# ### 1.3 with 문

# In[ ]:


with open('data/text.txt', 'rt') as fp:
    lines = fp.readlines()
   
    for line in lines:
        print(line.strip())

print('Done!')


# ### 1.4 예제: 성적 처리 시스템(파일 입출력)

# In[ ]:


# student.py

class Student(object):

    def __init__(self, num, name, kor, eng, math):
   
        # 학생의 속성
        self._num  = num
        self._name = name
        self._kor  = kor
        self._eng  = eng
        self._math = math
       
        self._total = 0
        self._avg   = 0.0
        self._order = 0
       
        # 총점과 평균을 구한다.
        self._calculate_total()
        self._calculate_avg()
   
    def _calculate_total(self):
        self._total = self._kor + self._eng + self._math
       
    def _calculate_avg(self):
        self._avg = self._total / 3
   
    @property
    def num(self):
        return self._num
       
    @property
    def name(self):
        return self._name
       
    @property
    def kor(self):
        return self._kor
       
    @property
    def eng(self):
        return self._eng
       
    @property
    def math(self):
        return self._math
       
    @property
    def total(self):
        return self._total
       
    @property
    def avg(self):
        return self._avg
       
    @property
    def order(self):
        return self._order
       
    @order.setter
    def order(self, value):
        self._order = value


# In[ ]:


# grade_system

class StudentGradeSystem(object):

    # StudentGradeSystem 객체의 생성자, 성적 파일을 입력 받는다.
    def __init__(self, score_file):
   
        self._score_file = score_file
   
        # 학생 객체를 저장할 리스트
        self._students = []
       
        # 반 성적을 저장할 속성
        self._class_avg = 0.0
        self._kor_avg   = 0.0
        self._eng_avg   = 0.0
        self._math_avg  = 0.0
       
        self._register_students()
   
    # 성적 파일로부터 학생 데이터를 입력 받는다
    def _register_students(self):
        with open(self._score_file, 'rt', encoding='cp949') as fp:
            lines = fp.readlines()
           
            for line in lines:
                items = (line.strip()).split(',')
               
                num  = items[0]
                name = items[1]
                kor  = int(items[2])
                eng  = int(items[3])
                math = int(items[4])
               
                student = Student(num, name, kor, eng, math)
                self._students.append(student)
               
    # 학생 등수를 구한다.
    def _calculate_student_order(self):
        temp_students = sorted(self._students, key = lambda x: x.total, reverse = True)
       
        order = 1
        for student in temp_students:
            student.order = order
            order = order + 1
           
        self._students = temp_students
   
    # 반 평균을 구한다.
    def _calculate_class_avg(self):
        total = 0
       
        for student in self._students:
            total = total + student.total
       
        self._class_avg = total / len(self._students)

    # 국어 평균을 구한다.
    def _calculate_kor_avg(self):
        total = 0
       
        for student in self._students:
            total = total + student.kor
       
        self._kor_avg = total / len(self._students)

    # 영어 평균을 구한다.
    def _calculate_eng_avg(self):
        total = 0
       
        for student in self._students:
            total = total + student.eng
       
        self._eng_avg = total / len(self._students)

    # 수학 평균을 구한다.
    def _calculate_math_avg(self):
        total = 0
       
        for student in self._students:
            total = total + student.math
       
        self._math_avg = total / len(self._students)

    # 반 성적 정보를 구한다.
    def _calculate_class_information(self):
        self._calculate_class_avg()
        self._calculate_kor_avg()
        self._calculate_eng_avg()
        self._calculate_math_avg()

    # 학생 객체를 등록한다.
    def register_student(self, student):
        self._students.append(student)

    # 학생 성적 및 반 성적을 처리한다.
    def process(self):
        self._calculate_student_order()         # 학생 순위를 구한다.
        self._calculate_class_information()     # 반 성적 정보를 구한다.

    # 처리된 성적 내용을 output_file에 출력한다.
    def output_result(self, output_file):
   
        student_output_format =  '번호: {:2}, 이름: {}, 국어: {}, 영어: {}, 수학: {}, 총점: {}, 평균: {:.2f}, 등수: {}\n'
       
        with open(output_file, 'wt') as fp:
            for student in self._students:
                student_output = student_output_format.format(
                                     student.num, student.name,
                                     student.kor, student.eng, student.math,
                                     student.total, student.avg, student.order)
                fp.write(student_output)
   
            fp.write('\n')
            fp.write('반 평균  : {:.2f}\n'.format(self._class_avg))
            fp.write('국어 평균: {:.2f}\n'.format(self._kor_avg)  )
            fp.write('영어 평균: {:.2f}\n'.format(self._eng_avg)  )
            fp.write('수학 평균: {:.2f}\n'.format(self._math_avg) )
           
        print('성적 처리가 끝났습니다.')


# In[ ]:


# main

# 성적이 기록된 파일을 읽는다.
student_grade_system = StudentGradeSystem('data/score.csv')

# 성적을 처리한다. - 총점, 평균, 등수 등을 계산
student_grade_system.process()

# 처리된 성적을 파일에 기록한다.
student_grade_system.output_result('data/result.csv')


# ---

# # 2. 예외 처리

# ### 2.1 예외 처리

# - 정상종료
# - 문법 오류
# - 논리 오류
# - 예외

# In[ ]:


# exception_divide1

def divide(m, n):
    return m / n

result = divide(3, 2)
print(result)

result = divide(3, 0)
print(result)


# In[ ]:


# exception_divide

def divide(m, n):
    try:
        result = m / n
   
    except ZeroDivisionError:
        print('0으로 나눌 수 없습니다.')
   
    except:
        print('ZeroDivisionError 이외의 예외가 발생했습니다.')
   
    else:
        return result
   
    finally:
        print('나눗셈 연산입니다.')

res = divide(3, 2)
print(res)
print()

res = divide(3, 0)
print(res)
print()

res = divide(None, 0)
print(res)


# ### 2.2 예외 발생시키기

# In[ ]:


raise TypeError


# In[ ]:


raise TypeError('타입 오류입니다.')


# In[ ]:


try:
    raise TypeError('타입 오류입니다.', '이것은 예제입니다.')

except TypeError as e:
    print(e.args)
   


# ### 2.3 사용자 정의 예외

# In[ ]:


# age_exception

# 사용자 정의 예외를 정의 했습니다.
class AgeException(Exception):

    def __init__(self, msg):
        self._message = msg
   
# 입력 함수
def input_age():
    age = int(input('나이를 입력해 주세요: '))
       
    if age < 0:
        raise AgeException('나이는 음수가 될 수 없습니다.')
    elif age > 150:
        raise AgeException('150세 이상 살 수 있을까요?')
    else:
        return age
   
# main

try:
    age = input_age()
   
except AgeException as e:
    print(e.args[0])
   
else:
    print('나이는 {}세입니다.'.format(age))
   
   


# ---

# In[ ]:


# end of file


# In[ ]:





반응형
LIST