[zero-base/] DS Part 1. Python 중급 - 10일차 스터디 노트

손윤재·2023년 12월 16일

제로베이스 DS 22기

목록 보기
11/55
post-thumbnail

파이썬 중급 문제풀이

- 예외처리, 파일입출력


👍 예제 1. 예외처리

사용자가 입력한 상품 구매 개수 값이 정수로 형변환이 안되면 예외처리한다.

📣 총 구매 금액을 계산하고 결과를 출력하는 함수를 정의

  1. 매개변수: 사용자가 입력한 구매 개수를 반복이 가능한 자료형으로 받는다.

    def calculate(*goods_cnt):
  2. 지역변수: 정상적으로 입력된 구매 개수를 저장할 변수와 잘못 입력된 데이터를 예외처리 후 저장할 변수를 선언한다.

    	goods_cnt_dic = {}
        wrong_cnt_dic = {}
    • 상품 번호 Key 값과 상품 구매 개수인 Value 값을 쌍으로 저장하는 Dictionary 자료 구조를 사용한다.
  3. 함수 호출부에서 입력받은 인수를 for문을 이용해 위에 선언한 변수에 저장한다.
    📍 구매 개수를 정수로 형변환할 수 없는 경우를 예외로 처리한다.

      for idx, g_cnt in enumerate(goods_cnt):
          try:
              goods_cnt_dic[f'g{idx+1}'] = int(g_cnt)
          except Exception as e:
              wrong_cnt_dic[f'g{idx+1}'] = g_cnt
              print(e)
    • goods_cnt에는 구매 개수에 대한 정보만 있으므로 enumerate()함수로 index를 생성해 상품 번호로 사용한다. 상품 번호는 Dictionary 키값으로 설정한다.

    • goods_cnt의 구매 개수 문자열 데이터 중 int로 형변환할 수 없어 예외가 발생하면 별도의 wrong_cnt_dic에 저장한다.

  1. 총 구매 금액을 구한다.
    for문으로 goods_cnt_dic에서 구매 개수를 가져와 상품별 가격과 곱한 후 모두 더한다.

       total_price = 0
        for g_no, g_cnt in goods_cnt_dic.items()
            total_price += globals()[f'{g_no}price'] * g_cnt
    • 💡 'globals()' 내장함수는 현재 영역에 있는 모든 전역변수들을 Dictionary 형태로 반환한다. Key 값에 변수명이, value 값에 데이터가 저장되어 있다.

    • 상품별 가격이 함수 밖에 선언되어 있다.

       g1price = 1200
        g2price = 1000
        g3price = 800
        g4price = 2000
        g5price = 900
  2. 결과를 출력한다. 미결제 항목으로 wrong_cnt_dic의 값도 같이 출력해준다.

      print('-----------------------------')
       print(' 총 구매 금액: {:,}원'.format(totalPrice)
       print('-------- 미결제 항목 --------')
       for g, cnt in wrong_cnt_dic.items():
           print(f' 상품: {g},\t 구매 개수: {cnt}')
       print('-----------------------------')

📣 함수 실행

	import module_CalculatePurchase as cp

    g1Cnt = input('goods1 구매 개수: ')
    g2Cnt = input('goods2 구매 개수: ')
    g3Cnt = input('goods3 구매 개수: ')
    g4Cnt = input('goods4 구매 개수: ')
    g5Cnt = input('goods5 구매 개수: ')

    cp.calculate(g1Cnt, g2Cnt, g3Cnt, g4Cnt, g5Cnt)
  • 실행결과는 다음과 같이 출력된다.
     goods1 구매 개수: 2
      goods2 구매 개수: 7
      goods3 구매 개수: three
      goods4 구매 개수: 1
      goods5 구매 개수: 삼
      
      -----------------------------
       총 구매 금액: 11,400원
      -------- 미결제 항목 --------
       상품: g3,	 구매 개수: three
       상품: g5,	 구매 개수: 삼
      -----------------------------



👊 예제 2. 파일 입출력

섬마을에 과일, 생선, 야채를 판매하는 배가 다음 주로 입항한다고 할 때,
모든 배가 입항하는 날짜를 텍스트 파일에 기록한다.
(첫 입항일은 2023년 1월 1일 오전 10로 한다.)

📌 세 배가 같이 입항하는 날은 세 주기의 최소공배수에 해당하는 날마다이다.
     3, 4, 5의 최소공배수인 60일 마다 세 배가 같이 입항하게 된다.

  1. 세 수 중 가장 작은 값을 찾는다.
    최대공약수는 세 수 중 가장 작은 수보다 클 수 없다.❗
    	min_val = min(ship1, ship2, ship3)
    👉 내장 함수인 min()으로 최소값을 구할 수 있다.
  1. 1부터 (min_val+1) 값까지 for문을 돌면서 세 수에 공통으로 나누어 떨어지는 수를 찾는다. 나누어 떨어지는 수 중 가장 큰 수가 최대공약수이다.
      gcd = 0
       for i in range(1, min_val + 1):
       if ship1 % i == 0 and ship2 % i == 0 and ship3 % i == 0:
           gcd = i
  1. 최소공배수는 세 수를 모두 곱한 값에서 최대공약수의 제곱수를 나누어 구한다.
    ex> 12, 60, 84를 소인수 분해했을 때 교집합 인수들의 곱이 최대공약수이다.
          12 = 2 × 2 × 3
          60 = 2 × 2 × 3 × 5
          84 = 2 × 2 × 3 × 7
          ➡ 최대공약수 = 2 × 2 × 3
    🚩 최소공배수는 합집합 인수들의 곱이다.
          ➡ 최대공약수가 (2 × 2 × 3 × 5 × 7)이므로 세 수를 곱한 후
              2번 반복해서 곱해진 최대공약수를 나누어 주면 최소공배수가 된다.
    	⭐ lcm = (ship1 * ship2 * ship3) // (gcd ** 2)

📌 모든 배가 입항하는 날짜를 텍스트 파일에 출력한다.

  1. datetime 모듈을 이용해 첫 입항일을 세팅한다.

    from datetime import datetime
    
     # 첫입항일 세팅
     baseTime = datetime(2023, 1, 1, 10, 0, 0)
  1. open(__path, __mode) 함수로 출력할 텍스트 파일을 열고 입항일을 차례대로 출력한다.

    • with 키워를 사용하면 close() 함수를 쓰지 않아도 된다.

    • 기준일로부터 60일 이후의 날짜를 얻기 위해 timedelta 모듈을 사용한다.

    • write() 함수는 자동 개행이 이루어지지 않으므로 개행을 명시해야 한다.

        with open('C:/pythonTxt/EX/ship_arrive.txt', 'w') as f:
             f.write(f'2023년 모든 선박 입항일\n')
             f.write(f'{baseTime}\n')
    
             nextTime = baseTime + timedelta(days=lcm)
             while nextTime.year == 2023:
                 f.write(f'{nextTime}\n')
                 nextTime += timedelta(days=lcm)
    • write() 대신 자동 개행이 이루어지는 print() 함수를 써도 된다.
         with open(uri + 'ship_arrive.txt', 'a') as f:
              print(f'2023년 모든 선박 입항일', file=f)
              print(f'{baseTime}', file=f)
    
              nextTime = baseTime + timedelta(days=lcm)
              while nextTime.year == 2023:
                  print(f'{nextTime}', file=f)
                  nextTime += timedelta(days=lcm)
  1. 파일 출력 결과


profile
ISTP(정신승리), To Be Data Scientist

0개의 댓글