[오늘의 문제] 모듈과 파일처리

shlim55·2025년 11월 6일

코딩테스트

목록 보기
169/223

1. 원의 넓이와 둘레

문제 설명

math 모듈을 활용하여, 원의 둘레와 넓이를 구하세요.

  • 원의 둘레: 2 * π * r
  • 원의 넓이: π * r²

사용자의 입력으로 반지름을 입력받고, 출력되는 둘레와 넓이는 소수점 둘째자리까지 반올림하세요.

Hint

  • 원주율: math.pi, 반올림 함수: round(숫자, 자리수)

입력 예시:

5

출력 예시:

원의 둘레: 31.42
원의 넓이: 78.54

내가 작성한 코드문

import math
pi = math.pi
r = int(input())
print(2*r*pi)
print(f"원의 둘레: {round(2*r*pi, 2)}")
print(f"원의 넓이: {round(r*r*pi, 2)}")

2. 로또 번호 생성기

문제 설명

random 모듈을 사용하여 로또 번호 생성기를 만드세요.

  1. 1부터 45까지의 숫자 중 6개를 랜덤하게 선택합니다
  2. 중복되지 않는 숫자여야 합니다
  3. 결과를 오름차순으로 정렬하여 출력합니다

힌트: random.sample(목록, 뽑을개수) 또는 random.randint(시작범위, 끝범위) 사용

입력 예시:

입력 없음

출력 예시:

이번 주 로또 번호: [3, 12, 23, 31, 38, 42]

(매 실행마다 결과가 다릅니다.)

내가 작성한 코드문

import random
print(f"이번 주 로또 번호: {random.sample(range(1,46), 6)}")

3. 계산기 모듈 만들기

주의사항: 주피터 노트북에서 %%writefile 파일명.py 매직 커맨드를 사용하여 .py 파일을 생성할 수 있습니다.

문제 설명

calculator.py 파일 생성 후, 계산기 모듈을 정의하세요.

  • add(a, b): 두 수를 받고, 덧셈을 반환
  • sub(a, b): 두 수를 받고, 뺄셈을 반환
  • mul(a, b): 두 수를 받고, 곱셈을 반환
  • div(a, b): 두 수를 받고, 나눗셈을 반환

해당 모듈을 불러와 두 숫자를 입력받고, 모듈의 4가지 연산 함수를 순서대로 호출하여 결과를 출력하세요.

입력 예시:

10 5

출력 예시:

15
5
50
2.0

내가 작성한 코드문

%%writefile calculator.py 
# 계산 함수를 정의하세요.

def add(a, b):
    return a+b

def sub(a, b):
    return a-b

def mul(a, b):
    return a*b

def div(a, b):
    return a/b
# calculator 모듈을 불러와 함수를 호출하세요.
from calculator import *

a = int(input())
b = int(input())

print(add(a,b))
print(sub(a,b))
print(mul(a,b))
print(div(a,b))

4. 학생 정보 관리 모듈 만들기

주의사항: 주피터 노트북에서 %%writefile 파일명.py 매직 커맨드를 사용하여 .py 파일을 생성할 수 있습니다.

문제 설명

student.py 파일 생성 후, 학생 정보 관리 모듈을 정의하세요.

  • students: 학생 정보를 보관하는 리스트
  • add_student(name, age, grade): 학생 정보를 추가
  • get_all_students(): 모든 학생 정보를 출력
  • find_student(name): 이름으로 학생을 검색 후, 학생 정보 딕셔너리 반환
  • get_average_age(): 학생들의 평균 나이를 계산후, 반환

학생 정보는 딕셔너리 형태로 정의합니다. (이름, 나이, 성적)

모듈을 불러온 뒤,다음을 수행하세요

  1. 3명의 학생 정보를 추가
  2. 전체 학생 목록 반복문 활용하여 출력
  3. 특정 학생 검색 결과 출력
  4. 평균 나이 계산 및 출력

입력 예시:

입력 없음

출력 예시:

전체 학생 목록
{'name': '김철수', 'age': 20, 'grade': 'A'}
{'name': '이영희', 'age': 22, 'grade': 'B'}
{'name': '박민수', 'age': 21, 'grade': 'A'}

학생 검색: 이영희
{'name': '이영희', 'age': 22, 'grade': 'B'}

평균 나이
21.0세

내가 작성한 코드문

%%writefile student.py 
# 학생 정보 리스트를 정의하세요.
students = []

# 학생 정보는 딕셔너리 형태로 정의합니다. (이름, 나이, 성적)
# dic = {"name": '', "age": 0, "grade": 0}

# 함수들을 정의하세요.
# - add_student(name, age, grade): 학생 정보를 추가
def add_student(name, age, grade):
    dic = {"name": name, "age": age, "grade": grade}
    print(dic)
    students.append(dic)
    return students  
    

# - get_all_students(): 모든 학생 정보를 출력
def get_all_students():
    print(students)

# - find_student(name): 이름으로 학생을 검색 후, 학생 정보 딕셔너리 반환
def find_student(name):
    print(f"학생검색: {name}")
    for student in students:
        if student['name'] == name:
            return student

# - get_average_age(): 학생들의 평균 나이를 계산후, 반환
def get_average_age():
    sum = 0
    avg = 0.0
    for student in students:
        sum += student['age']

    avg = sum / len(students)
    return avg
# 학생 정보 모듈을 불러와 함수를 호출하여 결과를 출력하세요.
import student 
import importlib
importlib.reload(student)

# 1. 3명의 학생 정보를 추가
class Student:
    def __init__(self, name, age, grade):
        self.name = name
        self.age = age
        self.grade =grade

student1 = Student("김철수", 28, 1)        
student2 = Student("이영희", 24, 2)        
student3 = Student("박민수", 26, 3)        

student.add_student(student1.name, student1.age, student1.grade)
student.add_student(student2.name, student2.age, student2.grade)
student.add_student(student3.name, student3.age, student3.grade)

# 2. 전체 학생 목록 반복문 활용하여 출력
for i in range(len(student.students)):
    student.get_all_students()

# 3. 특정 학생 검색 결과 출력
print(student.find_student(student1.name))
print(student.find_student(student2.name))
print(student.find_student(student3.name))

# 4. 평균 나이 계산 및 출력
print(f"평균나이: {student.get_average_age()} 세")

트러블 슈팅
일단 딕셔너리를 리스트에 저장하는 과정

lst = [{"name": name, "age": age, "grade": grade}
, {"name": name, "age": age, "grade": grade}
, {"name": name, "age": age, "grade": grade}
]

이런형태로 저장해야 함 그리고 그것을 네임값으로 조회하는게 생소했다.

객체 초기화 및 add메서드 호출을 통해 객체값 저장

student1 = Student("김철수", 28, 1)        
student2 = Student("이영희", 24, 2)        
student3 = Student("박민수", 26, 3)        

student.add_student(student1.name, student1.age, student1.grade)
student.add_student(student2.name, student2.age, student2.grade)
student.add_student(student3.name, student3.age, student3.grade)

각 매개변수를 딕셔너리에 저장 및 리스트에 딕셔너리 append

dic = {"name": name, "age": age, "grade": grade}
    print(dic)
    students.append(dic)
    return students  

리스트를 반복문 순회하며
딕셔너리의 네임 밸류값이 일치하는 이름이 있는지 확인
있으면 딕셔너리 리턴

def find_student(name):
    print(f"학생검색: {name}")
    for student in students:
        if student['name'] == name:
            return student

평균 나이 계산도 마찬가지다. age 밸류값 합산및
리스트 길이 만큼 나눈다. 그러면 나이 평균값.

def get_average_age():
    sum = 0
    avg = 0.0
    for student in students:
        sum += student['age']

    avg = sum / len(students)
    return avg

5. 일기 파일 만들기

문제 설명

텍스트 파일을 생성하고 일기를 작성한 후, 파일을 읽어서 내용을 출력하는 프로그램을 작성하세요.

  • "diary.txt" 파일을 생성합니다
  • 오늘 날짜와 일기 내용을 작성합니다. (최소 3줄)
  • with 구문을 사용하여 파일을 안전하게 쓰기 처리합니다
  • 작성한 파일을 다시 읽어서 내용을 출력합니다

입력 예시:

diary_content = """
오늘은 파이썬 Day5 수업을 들었다.
모듈과 파일 처리에 대해 배웠다.
내일은 복습을 해야겠다."""

(문자열 형태로 자유롭게 작성)

출력 예시:

오늘은 파이썬 Day5 수업을 들었다.
모듈과 파일 처리에 대해 배웠다.
내일은 복습을 해야겠다.

내가 작성한 코드문

with open("../diary.txt", "w",encoding='utf-8') as f:
    # content = f.read()
    f.write('''
            25년도 11월 6일
            가나다라
            마바사
            ''')
f = open("../diary.txt", "r")
print(f.read())

트러블 슈팅
한단계 위의 폴더를 찾을려면 .. 를 앞에 넣어야 한다 함

6. 파일 포인터 제어하기

문제 설명

파일의 특정 위치를 읽기 위해 tell()과 seek() 함수를 활용하는 프로그램을 작성하세요.

"position_test.txt" 파일을 만들고 "ABCDEFGHIJKLMNOP" 문자열을 저장합니다
파일을 읽기 모드로 열고 다음을 수행합니다:

  • 처음 5글자를 읽고 현재 위치(tell)를 출력
  • 파일 포인터를 10번 위치로 이동(seek)
  • 현재 위치를 확인하고 출력
  • 그 위치부터 5글자를 읽어서 출력

입력 예시:

# 파일에 저장된 내용
"ABCDEFGHIJKLMNOP"

출력 예시:

처음 5글자: ABCDE
현재 위치: 5

이동 후 현재 위치: 10
10번째 위치부터 5글자: KLMNO

내가 작성한 코드문

f = open("position_text.txt", "w", encoding='utf-8')

f.write("ABCDEFGHIJKLMNOP")
f.close()
f = open("position_text.txt", "r", encoding='utf-8')
print(f"처음 5글자: {f.read(5)}")

print(f"현재 위치:{f.tell()}")
print(f.seek(10))
print(f"이동 후 현재 위치:{f.tell()}")
print(f.read(5))

트러블 슈팅
맨처음에 저장하고 f.read()가 안 읽히는 상황이 있었는데

f = open("position_text.txt", "r", encoding='utf-8')

이렇게 "r"타입으로 지정해줘야 한다.

7. 할 일 목록 추가하기

문제 설명

파일의 append 모드를 사용하여 기존 내용에 새로운 내용을 추가하는 프로그램을 작성하세요.

  1. "todo.txt" 파일을 생성하고 할 일 3개를 작성을 완료합니다
  2. append 모드('a')로 파일을 열어 할 일 2개를 추가합니다
  3. 최종 파일 내용을 읽어서 줄 번호와 함께 출력합니다

줄 바꿈(개행) 문자를 삭제하려면 str.strip() 함수를 활용하세요!

입력 예시:

# 처음 작성할 내용
파이썬 공부하기
운동하기
책 읽기

# 추가할 내용
프로젝트 완성하기
블로그 포스팅하기

출력 예시:

최종 TODO 리스트
1. 파이썬 공부하기
2. 운동하기
3. 책 읽기
4. 프로젝트 완성하기
5. 블로그 포스팅하기

내가 작성한 코드문

f = open("todo.txt", "w", encoding='utf-8')

f.write('''
        파이썬공부하기
        운동하기
        책 읽기
        ''')
f.close()
f = open("todo.txt", "a", encoding='utf-8')
f.write('''
        프로젝트 완성하기
        블로그 포스팅하기
        ''')

f.close()
f = open("todo.txt", "r", encoding='utf-8')
print(f.read())

전반적인 파일 처리 메서드 다루기

8. 안전한 계산기

문제 설명

while 무한 루프를 활용하여 사용자 입력을 받아 계산을 수행하되, 다양한 예외 상황을 처리하는 계산기를 만드세요.

요구사항:

  1. 사용자로부터 두 숫자와 연산자(+, -, *, /)를 입력받습니다
  2. 다음 예외 상황을 처리합니다:
  • ValueError: 숫자가 아닌 값을 입력한 경우
  • ZeroDivisionError: 0으로 나누려는 경우
  1. 숫자나 연산자 부분에서 'q'를 입력하면 프로그램을 즉시 종료합니다
  2. 예외 발생 시에도 프로그램이 종료되지 않고 계속 실행되어야 합니다. (예외 발생 시, 경고 메시지 출력하기)

입력 예시:

첫 번째 숫자: 10
연산자 (+, -, *, /): /
두 번째 숫자: 0

첫 번째 숫자: 10
연산자 (+, -, *, /): +
두 번째 숫자: abc

첫 번째 숫자: 10
연산자 (+, -, *, /): +
두 번째 숫자: 5

첫 번째 숫자: q

출력 예시:

첫 번째 숫자: 10
연산자 (+, -, *, /): /
두 번째 숫자: 0
[오류] 0으로 나눌 수 없습니다.

첫 번째 숫자: 10
연산자 (+, -, *, /): +
두 번째 숫자: abc
[오류] 숫자를 입력해주세요.

첫 번째 숫자: 10
연산자 (+, -, *, /): +
두 번째 숫자: 5
결과: 10 + 5 = 15.0

첫 번째 숫자: q
계산기를 종료합니다.

내가 작성한 코드문

while True:

    try:
        num1 = input("첫번째 숫자: ")
        if num1 == 'q':
            print("계산기를 종료합니다.")
            break
        num1 = int(num1)# q 아닐시 정수변환
        operator = input("연산자: ")

        if num2 == 'q':
            print("계산기를 종료합니다.")
            break
        num2 = int(num2)# q 아닐시 정수변환

        if operator =='q':
            print("계산기를 종료합니다.")
            break

        if operator == "+":
            print(f"{num1} + {num2} = {num1+num2}")
        elif operator == "-":
            print(f"{num1} - {num2} = {num1-num2}")
        elif operator == "*":
            print(f"{num1} * {num2} = {num1*num2}")
        elif operator == "/":
            print(f"{num1} / {num2} = {num1/num2}")
        else:
             print("연산자 다시 입력하세요.")
    except ValueError:
        print('숫자를입력하세요')
    except ZeroDivisionError:
        print('[오류] 0으로 나눌 수 없습니다.')

트러블 슈팅
일단 다른건 다 안어려웠는데
q누르면 즉시 루프만 탈출이었다.

num1,num2변수는 일단 맨처음에 인풋을 int()로 감쌌는데

이것을 없앤담에 q로 입력했는지 여부 확인하고 맞으면 break, q가 아닌경우에만 정수타입으로 변환하게 해야 한다.

미니 프로그램: 학생 성적 관리 시스템

*문제 설명

학생 성적 데이터를 파일에 저장한 뒤, 파일을 읽어서 각 학생의 총점/평균, 과목별 평균, 최고 평균 학생을 구해 출력하고, 결과를 score_report.txt로 저장하세요.

*요구사항:

한 줄에 한 학생: "이름,국어,영어,수학"(값마다 콤마로 구분)으로 구성된 students_scores.txt 파일을 읽어서 다음을 출력하세요.

  • 각 학생의 총점과 평균
  • 전체 학생의 과목별 평균(국어/영어/수학)
  • 최고 평균 학생의 이름과 평균
  • 출력 결과는 report_lines 리스트 변수에 결과 문장을 추가하세요.
  • 출력한 결과 전체를 score_report.txt 파일에 담아서 저장하세요.

*힌트

  • 파일 읽기: with open("students_scores.txt", "r", encoding="utf-8") as f:
    for line in f: 로 한 줄씩 읽고, line.strip()으로 공백/개행 제거
  • 데이터 나누기 함수 parse_line(line): 콤마로 구분된 4개의 값을 분리하고, 숫자 값은 숫자로 변환하여 투플 형태로 반환
  • 합계: total = k + e + m
  • 평균: avg = total / 3
  • 소수점 한 자리 포맷팅: f"{avg:.1f}"
  • 과목별 평균: 각 과목 점수를 누적합 하다가 마지막에 학생 수로 나누기
  • 최고 평균: 순회하며 max_avg와 top_name을 계속 갱신
  • 출력 결과에 대한 리스트를 .join 함수를 활용하여 하나의 문자열로 변환하여 파일 쓰기
  • with open("score_report.txt", "w") as f:
    f.write("\n".join(report_lines))

입력 예시:

# students_scores.txt 파일 내용:
김철수,90,85,95
이영희,95,90,100
박민수,80,85,90
최지영,88,92,87
정다은,92,88,90

출력 예시:

김철수: 총점 270점, 평균 90.0점
이영희: 총점 285점, 평균 95.0점
박민수: 총점 255점, 평균 85.0점
최지영: 총점 267점, 평균 89.0점
정다은: 총점 270점, 평균 90.0점

국어 평균: 89.0점
영어 평균: 88.0점
수학 평균: 92.4점

이영희 (평균 95.0점)

결과가 score_report.txt 파일에 저장되었습니다.

내가 작성한 코드문

with open("students_scores.txt", "r", encoding="utf-8") as f:
    # content1 = f.readlines()
    list_tp = []
    tp = ()
    avg_list_tp = []
    avg_tp = ()
    report_line = []
    subject_total = [0, 0, 0]# 과목별 총점
    subject_avg = []

    def parse_line(line):
        total = 0 # 학생 총점 
        line_parts = line.strip().split(',')# 콤마로 구분된 4개의 값을 분리
        print("각줄: ", line_parts)
        # 숫자 값은 숫자로 변환하여 투플 형태로 반환
        for i in line:
            print(i) # 각 줄의 요소 출력
            report_line.append(i)   
            if i.isdigit(): # 각 라인 요소가 숫자인지? 숫자면 튜플형태로 반환 
                total += int(i) # 총점 계산후 
        list_tp.append(total)
        tp = list_tp  
        avg_list_tp.append(total / 3)
        avg_tp = avg_list_tp     
        print("튜플에 저장된 값들", tp) # 튜플에 저장된 값들       
        print("튜플에 저장된 값들", avg_tp) # 튜플에 저장된 값들  

        # 과목별 평균 구하기 
        for i in range(1, len(line)): # ['김철수', '90', '85', '95']
            score_str = line_parts[i].strip()

            subject_avg = subject_total / 5

        return tp

    for line in f: 
        line = line.strip() # 으로 공백/개행 제거
        print(line)
        parse_line(line) # 콤마로 구분된 4개의 값을 분리하고, 숫자 값은 숫자로 변환하여 투플 형태로 반환
        
# 위에서 나온 총점, 평균, 과목별 평균을 저장시킨다. 
# with open("score_report.txt", "w", encoding="utf-8") as f:
    
#     f.write("\n".join(report_lines))

트러블 슈팅

일단, 각 학생별 총점, 평균은 구했지만, 과목별 점수까지는 못구했다.

💡 기존 코드의 문제점

# 과목별 평균 구하기 
        for i in line: # ['김철수', '90', '85', '95']
            # 각 두번째 요소 부터 계산
            for j in range(1, len(line)):
                subject_total += int(line[j]) # ⚠️ 문제 1: 이중 루프 때문에 점수가 과도하게 중복 합산됨
                                              #        (예: 4번의 i 루프마다 3개 점수가 합산)

            subject_avg = subject_total / 5   # ⚠️ 문제 2: 현재 학생의 총점을 전체 학생 수(5)로 나누고 있음
                                              #        (파일 전체를 다 읽은 후에 한 번만 나눠야 함)
            
        return tp # 이 함수는 한 줄(학생 한 명)을 처리할 때마다 호출되므로,
                  # 과목별 '누적' 총점 계산이 이 함수 밖에서 관리되어야 한다.

다른 사람의 풀이

# 학생 점수 분석 스크립트 (한 줄 주석 해석)

# 'parse_line' 함수 정의 시작
def parse_line(line):
    # 입력된 한 줄(line)을 콤마(,) 기준으로 분리하여 이름(name)과
    # 국어(k), 영어(e), 수학(m) 점수 문자열에 각각 할당합니다.
    name, k, e, m = line.split(",")
    # 이름은 그대로 문자열로, 점수들은 정수(int)형으로 변환하여 반환합니다.
    return name, int(k), int(e), int(m)

# --------------------------------------------------------------------------------
# ⭐ 1단계: 전역 변수 초기화 (전체 데이터를 처리하며 누적할 변수들)
# --------------------------------------------------------------------------------

# 과목별 합계 점수를 저장할 변수들을 0으로 초기화합니다.
kor_sum = 0
eng_sum = 0
math_sum = 0
# 처리한 총 학생 수를 저장할 변수를 0으로 초기화합니다.
count = 0

# 최고 평균을 기록한 학생 이름 추적을 위해 빈 문자열로 초기화합니다.
top_name = ""
# 최고 평균 점수를 추적하기 위해 매우 낮은 값(-1)으로 초기화합니다.
max_avg = -1

# 최종 보고서 내용을 문자열 형태로 담아둘 리스트를 초기화합니다.
report_lines = []   

# --------------------------------------------------------------------------------
# ⭐ 2단계: 'students_scores.txt' 파일을 읽고 학생별 분석 수행
# --------------------------------------------------------------------------------

# "students_scores.txt" 파일을 읽기 모드로 열고(as f), with 블록을 벗어나면 자동으로 닫습니다.
with open("students_scores.txt", "r", encoding="utf-8") as f:
    # 파일 객체 f를 한 줄씩 반복합니다. (l은 현재 읽은 줄)
    for l in f:
        # 현재 줄(l)의 앞뒤 공백이나 개행 문자(\n)를 제거합니다.
        line = l.strip()
        # 만약 줄이 비어있다면(빈 줄이라면) 다음 줄로 건너뜁니다.
        if not line:
            continue
        # 정의된 parse_line 함수를 호출하여 이름과 정수형 점수들을 분리해 할당받습니다.
        name, kor, eng, math = parse_line(line)
        
        # 해당 학생의 총점을 계산합니다.
        total = kor + eng + math
        # 해당 학생의 평균을 계산합니다. (3과목 기준)
        avg = total / 3

        # 학생별 총점과 평균 결과를 포맷팅된 문자열로 만듭니다. (평균은 소수점 첫째 자리까지 표시)
        line_out = f"{name}: 총점 {total}점, 평균 {avg:.1f}점"
        # 이 결과를 콘솔(화면)에 출력합니다.
        print(line_out)
        # 이 결과를 최종 보고서 리스트에 추가합니다.
        report_lines.append(line_out)

        # 전체 과목별 총점에 현재 학생의 점수를 누적합니다.
        kor_sum += kor
        eng_sum += eng
        math_sum += math
        # 학생 수를 1 증가시킵니다.
        count += 1

        # 현재 학생의 평균(avg)이 지금까지의 최고 평균(max_avg)보다 높다면,
        if avg > max_avg:
            # 최고 평균 점수를 현재 학생의 평균으로 갱신합니다.
            max_avg = avg
            # 최고 평균 학생 이름도 현재 학생의 이름으로 갱신합니다.
            top_name = name

# --------------------------------------------------------------------------------
# ⭐ 3단계: 파일 읽기가 끝난 후, 과목별 평균 및 최고 학생 정보 계산 및 출력
# --------------------------------------------------------------------------------

# 누적된 과목별 총점을 총 학생 수(count)로 나누어 국어 평균을 계산합니다.
kor_avg = kor_sum / count
# 누적된 과목별 총점을 총 학생 수(count)로 나누어 영어 평균을 계산합니다.
eng_avg = eng_sum / count
# 누적된 과목별 총점을 총 학생 수(count)로 나누어 수학 평균을 계산합니다.
math_avg = math_sum / count

# 국어 평균 결과를 문자열로 만들고, 콘솔에 출력 후 보고서 리스트에 추가합니다.
line_out = f"국어 평균: {kor_avg:.1f}점"
print(line_out)
report_lines.append(line_out)

# 영어 평균 결과를 문자열로 만들고, 콘솔에 출력 후 보고서 리스트에 추가합니다.
line_out = f"영어 평균: {eng_avg:.1f}점"
print(line_out)
report_lines.append(line_out)

# 수학 평균 결과를 문자열로 만들고, 콘솔에 출력 후 보고서 리스트에 추가합니다.
line_out = f"수학 평균: {math_avg:.1f}점"
print(line_out)
report_lines.append(line_out)

# 빈 줄을 추가하여 보고서의 가독성을 높입니다.
report_lines.append("")

# (3) 최고 평균 학생의 이름과 점수를 포맷팅합니다.
line_out = f"{top_name} (평균 {max_avg:.1f}점)"
# 콘솔에 출력합니다.
print(line_out)
# 보고서 리스트에 추가합니다.
report_lines.append(line_out)

# --------------------------------------------------------------------------------
# ⭐ 4단계: 최종 보고서 내용을 'score_report.txt' 파일에 저장
# --------------------------------------------------------------------------------

# "score_report.txt" 파일을 쓰기 모드(w)로 열고(as f), 기존 내용을 덮어씁니다.
with open("score_report.txt", "w", encoding="utf-8") as f:
    # report_lines 리스트의 모든 문자열을 개행 문자(\n)로 연결한 후 파일에 씁니다.
    f.write("\n".join(report_lines))

parse_line 함수에 각각 언패킹 하여 이름, 국어, 영어, 수학 점수 저장

두번째 풀이

import os

# 1. 전역 변수 초기화 (분석 결과를 누적 저장할 공간)
report_lines = []
subject_totals = [0, 0, 0]  # 국어, 영어, 수학 순서
num_students = 0
max_avg = -1.0
top_student_name = ""

def parse_line(line):
    """
    한 학생의 점수 줄을 분석하고, 학생 총점/평균을 계산하며
    전체 과목 총점 및 최고 평균 학생 정보를 갱신합니다.
    """
    global subject_totals, num_students, max_avg, top_student_name

    # 줄 정리 및 데이터 분리
    parts = line.strip().split(',')
    
    # 데이터 유효성 검사 (최소한 이름과 3개 점수가 있어야 함)
    if len(parts) < 4:
        # report_lines.append(f"경고: 데이터 형식이 올바르지 않은 줄을 건너뜁니다: {line.strip()}")
        return

    name = parts[0].strip()
    score_strings = parts[1:]
    scores = []
    
    # 점수 문자열을 숫자로 변환
    try:
        scores = [int(s.strip()) for s in score_strings]
    except ValueError:
        # report_lines.append(f"경고: 점수가 아닌 값이 포함된 줄을 건너뜁니다: {line.strip()}")
        return
        
    # 점수 개수 확인 (3과목 가정)
    if len(scores) != 3:
        # report_lines.append(f"경고: {name} 학생의 점수 개수가 3개가 아닙니다. 계산 건너뜀.")
        return
        
    # 2. 각 학생의 총점과 평균 계산
    student_total = sum(scores)
    student_avg = student_total / len(scores)
    
    # 소수점 한 자리 포맷팅
    avg_formatted = f"{student_avg:.1f}"
    
    # 3. 각 학생의 총점과 평균을 report_lines에 추가
    report_line = f"{name}: 총점 {student_total}점, 평균 {avg_formatted}점"
    report_lines.append(report_line)
    
    # 4. 전체 통계 변수 갱신
    # 과목별 총점 누적
    for i in range(len(scores)):
        subject_totals[i] += scores[i]
        
    # 최고 평균 학생 갱신
    if student_avg > max_avg:
        max_avg = student_avg
        top_student_name = name
        
    num_students += 1

# 메인 로직 실행
filename = "students_scores.txt"
print(f"[{filename}] 파일을 읽어 점수 분석을 시작합니다.")

try:
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            parse_line(line)
except FileNotFoundError:
    print(f"오류: 입력 파일 '{filename}'을 찾을 수 없습니다. 파일을 생성했는지 확인해주세요.")
    exit()

# --- 1. 학생별 총점/평균 출력 완료 ---

# 빈 줄 추가
report_lines.append("")

# --- 2. 전체 학생의 과목별 평균 계산 및 출력 ---
subject_names = ["국어", "영어", "수학"]

if num_students > 0:
    for i in range(len(subject_totals)):
        # 과목 총점을 총 학생 수로 나누어 평균 계산
        average = subject_totals[i] / num_students
        # 소수점 한 자리 포맷팅 후 report_lines에 추가
        avg_line = f"{subject_names[i]} 평균: {average:.1f}점"
        report_lines.append(avg_line)

    # 빈 줄 추가
    report_lines.append("")
    
    # --- 3. 최고 평균 학생의 이름과 평균 출력 ---
    top_avg_formatted = f"{max_avg:.1f}"
    top_student_line = f"{top_student_name} (평균 {top_avg_formatted}점)"
    report_lines.append(top_student_line)

# --- 4. report_lines의 내용을 score_report.txt 파일로 저장 ---
report_filename = "score_report.txt"
try:
    with open(report_filename, "w", encoding="utf-8") as f:
        # 리스트의 모든 문자열을 개행 문자(\n)로 연결하여 파일에 한 번에 쓰기
        f.write("\n".join(report_lines))
    print("\n" + "="*50)
    print(f"성공적으로 분석을 완료했습니다. 결과가 '{report_filename}' 파일에 저장되었습니다.")
    print("="*50)
    
except Exception as e:
    print(f"오류: 보고서 파일을 저장하는 중 오류 발생: {e}")

# (참고: 최종 저장된 파일의 내용을 콘솔에 출력하여 확인)
print("\n[score_report.txt 파일 내용 미리보기]")
print("-" * 30)
print("\n".join(report_lines))
print("-" * 30)
profile
A Normal Programmer

0개의 댓글