본문 바로가기
패스트캠퍼스

[패스트캠퍼스] 파이썬 강의 2주차 / 함수, 튜플, 딕셔너리, 클래스, 생성자, 상속, 오버라이딩, 모듈, 패키치, 파일입출력, 예외처리

by 리잼 2022. 9. 2.
반응형

함수

함수를 사용하는 이유

  • 재사용성이 좋아진다
  • 유지보수가 편해진다
  • 코드 가독성이 좋아진다
# 실습문제 1
# 3개의 정수를 인자로 받는다
# 합계와 평균을 구하는 함수를 작성한다

def printSumAvg(x,y,z):
    """
    합계와 평균을 구하는 함수
    """
    sum = x+y+z
    print("합계 :" ,sum, "평균 :", int(sum/3)) # 그냥 sum/3을 해도 되지만 이렇게하면 20.0이 출력됨
					# 강사님의 요구사항은 20이 출력되는것 이므로 int로 정수형 변환

printSumAvg(10,20,30)

# 실습문제 2
# 로또 예상번호 추출 프로그램
# 1. 로또 번호 6개를 생성한다
# 2. 로또 번호는 1~45까지의 랜덤번호이다
# 3. 6개의 숫자 모두 달라야한다
# 4. getRandomNumber()함수를 사용해서 구현한다.

from itertools import count
import random

def getRandomNumber():
    """
    1~45까지 랜덤 추출해주는 함수
    """
    number = random.randint(1,45)
    return number

lottos = [] #로또 번호를 받을 리스트 

count = 0 # 현재 뽑은 숫자 개수

while True:         # 중복 숫자 방지를 위한 while문
    if count == 6:  # 뽑은 숫자가 6개면 종료
        break
    result = getRandomNumber() # 6개의 번호를 result에 저장
    if result not in lottos:  # 받아온 result값이 lottos에 없으면
        lottos.append(result) # 받아온 번호를 lottos 리스트에 저장
        count += 1            # 숫자를 받아올 때마다 1씩 증가
    

lottos.sort() #리스트 오름차순 정렬

for i in lottos:
    print(i, end=" ") # 리스트 형태가 아닌 숫자만 출력되게 하기위한 반복문

로또 번호를 출력하는데 중복인 수가 있으면 안 되는 조건을 코드로 작성하는 걸 순간 잊어버렸다

그래서 일단 중복이 돼도 6개 멀쩡히 출력되는 코드를 완성하고 강사님의 도움을 받았다.. 다시 한번 새겨 넣어야지.


튜플

  • 시퀀스 자료형
  • 수정, 추가, 삭제가 불가능한 리스트 ( 읽기만 가능 )

튜플 만들기

  • 튜플 = (데이터, 데이터, 데이터)
  • 튜플 = 데이터, 데이터, 데이터
    괄호를 생략하고 생성이 가능하다.

패킹과 언패킹

  • numbers = 3,4,5  # 패킹
    a, b, c = numbers  # 언패킹

패킹 : 여러 개의 데이터를 하나의 변수에 할당

언패킹 : 컬렉션의 각 데이터를 각각의 변수에 할당

 

튜플 함수

  • 특정값의 인덱스 구하기 >> 튜플.index()
  • 특정값의 개수                >> 튜플.count()
  • 최댓값, 최솟값               >> max(튜플), min(튜플)
  • 합계                               >> sum(튜플)

딕셔너리

딕셔너리 특징

  • 시퀀스 자료형
  • 키와 데이터를 가지고 있는 사전형 자료형
  • 사전 형태의 자료를 만들 때 편리

딕셔너리 = {키1: 데이터1, 키2: 데이터2}

 

딕셔너리 사용방법

  • 접근 방법 : 딕셔너리["키"]
  • 할당 방법 : 딕셔너리["키"] = 데이터
  • 삭제하기  : del 딕셔너리["키"]
# 딕셔너리 만들기
stock_a = {"삼성전자" : 82000, "LG전자" : 150000}

stock_b = {
    "삼성전자" : [82000, 81500, 82000, 81500, 82000],
    "LG전자" : [150000, 149000, 148000, 151000, 152000]
}

stock_c ={                      # 중첩 딕셔너리도 가능하다
    "삼성전자" : {
        "현재가" : 82000,
        "보유수량" : 5,
        "매수단가" : 81000
    }
}

# 딕셔너리 접근하기
print(stock_a["삼성전자"])  # 82000
print(stock_c["삼성전자"]['보유수량']) # 82000, 5

# 딕셔너리 할당
stock_a["삼성전자"] = 85000
print(stock_a) # {'삼성전자': 85000, 'LG전자': 150000}

# 딕셔너리 삭제
del stock_a["LG전자"]
print(stock_a) # {'삼성전자': 85000}

# 딕셔너리 함수
stock_d = {
    "삼성전자" : 82000,
    "LG전자" : 123000,
    "NAVER" : 370000,
    "카카오" : 133000
}
# items() : 키와 데이터 쌍
for item in stock_d.items():
    print(item)

# keys() : 키
for key in stock_d.keys():
    print(key)

# values() : 데이터
for values in stock_d.values():
    print(values)

클래스

클래스와 객체

  • 클래스
    객체를 만들기 위한 설계도
  • 객체
    설계도로부터 만들어낸 제품

클래스를 사용하는 이유

클래스를 사용하지 않은경우
클래스를 사용한 경우

같은 내용을 출력하지만 클래스를 사용 안 한경 우와 한경우 코드의 양이 달라지고, 가독성도 좋아진다.

클래스와 객체의 개념

  • 클래스
    • 속성
      클래스의 특징을 나타냄
    • 메서드
      클래스의 동작을 나타냄
# 클래스 만들기
class 클래스이름:
	def 메소드이름(self):
    	명령 블록
  • 클래스 호출 방법
    인스턴스 = 클래스 이름()
    인스턴스.메서드()
# 파이썬에서는 자료형도 클래스다

a = 10
b = "문자열 객체"
c = True

print(type(a)) # <class 'int'>
print(type(b)) # <class 'str'>
print(type(c)) # <class 'bool'>

생성자

__init__

  • 인스턴스를 생성할 때 반드시 호출되는 메서드
  • self는 매개변수로 해당되지 않음
  • self는 생성하려는 인스턴스 자기 자신을 뜻한다

클래스와 인스턴스 생성


상속

  • 클래스에 중복된 코드를 제거하고, 유지보수를 용이하게 하기 위해 사용
  • 부모 클래스의 속성을 자식 클래스가 사용할 수 있다

3개의 인스턴스는 부모 클래스에서 이름, 체력, 공격력 속성을 상속받고

늑대를 제외한 나머지 2개의 인스턴스는 move 메서드를 재정의 하여 다르게 출력되도록 하였다.


오버라이딩


클래스 실습문제

 

# 실습문제 1
# 아이템 공통 : 이름, 가격, 무게, 판매하기, 버리기
# 장비 아이템 : 착용효과, 착용하기
# 소모품 아이템 : 착용효과, 사용하기
# (단 버리기는 버릴 수 있는 아이템만 가능)

class Item:
    def __init__(self, name, price, weight, isdropable):
        self.name = name
        self.price = price
        self.weight = weight
        self.isdropable = isdropable

    def sale(self):
        print(f"[{self.name}] 판매 가격은 [{self.price}] 입니다.")

    def discard(self):
        if self.isdropable:
            print(f"[{self.name}] 버렸습니다.")
        else:
            print(f"[{self.name}] 버릴 수 없습니다.")

class WearableItem(Item):
    def __init__(self, name, price, weight, isdropable, effect):
        super().__init__(name, price, weight, isdropable)
        self.effect = effect

    def wear(self):
        print(f"[{self.name}]을 착용하였습니다. {self.effect}")

class UseableItem(Item):
    def __init__(self, name, price, weight, isdropable, effect):
        super().__init__(name, price, weight, isdropable)
        self.effect = effect
    
    def use(self):
        print(f"[{self.name}]을 사용하였습니다. {self.effect}")

sword = WearableItem("단검", 30000, 3.5, True, "체력 5000 증가, 마력 5000증가")
potion = UseableItem("체력 포션", 500, 0.1, False, "체력 50을 회복했습니다.")
sword.wear() # [단검]을 착용하였습니다. 체력 5000 증가, 마력 5000증가
sword.sale() # [단검] 판매 가격은 [30000] 입니다.
potion.discard() # [체력 포션] 버릴 수 없습니다.

개인적으로 클래스와 오버라이딩은 좀 더 자세히 공부할 필요가 있는 거 같다.

수업을 들을 땐 이해한 거 같았으나 실습 문제를 풀 때 제대로 풀지 못했다.

다른 예제를 풀어보면서 복습복습 해야겠다.


모듈

모듈의 개념

  • 한 개의 완성된 프로그램 파일
    각종 변수, 함수, 클래스를 담고 있는 파이썬 파일

내장 모듈

  • 파이썬 설치 시 자동으로 설치되는 모듈
    ex) math, calendar ...

외부 모듈

  • 다른 사람이 만든 파이썬 모듈. pip로 설치해서 사용
    ex) pyautogui ...

모듈 만들기

결제정보 모듈
모듈 사용결과

 

패키지

패키지 실습 과정에서 오류가 하나 발생했는데

모듈 절대경로, 상대경로 import 에러였다..

폴더 구조
VSC setting.json 창

VSC 설정에서 경로 지정 설정을 해줘도

자꾸 이렇게 노란 줄이 뜨는 게 아닌가..

이럴 땐 설정에 추가해준 문구를 다 지우고

이렇게 경로를 직접 다 적어줘야 출력이 되는 것을 확인했다.. 

그렇지만 이렇게 다 적기엔 너무 불편한데 차차 방법을 알아가 봐야겠다;


파일 입출력

파일 열기 모드

  • w : 쓰기 모드 ( write )
  • a : 추가 모드 ( append )
  • r : 읽기 모드 ( read )

파일 작업 순서

  • 파일 열기 > 파일 작업 > 파일 닫기

파일 입출력 실습

파일을 작성하는 코드
인코딩을 해주지 않아 글씨가 깨져버린다
encoding="utf_8" 을 추가해주면
정상적으로 출력되는것을 볼 수 있다.

with open

  • 파일을 open으로 그냥 불러오게 되면 작업 종료 시 항상 close()로 파일을 닫아줘야 한다
  • with 구문을 사용하면 이런 귀찮은 짓을 하지 않아도 된다!

CSV 파일 다루기

  • CSV ( Comma Separated Values )
    데이터가 콤마로 구분된 텍스트 파일 형식

실습문제

# 실습문제 1
# 보유한 주식이 목표가에 도달했을 때 종목별 수익금과 수익률을 출력해주는
# 프로그램작성

# 파일 생성
import csv

stock = [
    ["종목", "매입가", "수량", "목표가"],
    ["삼성전자", 85000, 10, 90000],
    ["NAVER", 380000, 5, 400000]
]

file = open("./myvenv/Chapter10/stock.csv", "w", newline="", encoding="utf-8-sig")

writer = csv.writer(file)

for d in stock:
    writer.writerow(d)

file.close()

# 파일 열기

def show_profit(data):
    name = data[0] # 종목
    purchase_price = int(data[1]) # 매입가
    amount = int(data[2]) # 수량
    target_price = int(data[3]) #목표가 

    profit = (target_price - purchase_price) * amount #수익금
    profit_ratio = (target_price/purchase_price -1) * 100 #수익률

    print(f"{name} {profit} {profit_ratio : .2f}%") # 수익률에 소수점 2자리를 맞춰줌

file = open("./myvenv/Chapter10/stock.csv", "r", encoding="utf-8-sig")
reader = list(csv.reader(file))
for data in reader[1:]:
    show_profit(data)

에러와 예외 처리

예외처리가 필요한 이유

  • 프로그램 실행 중 발생하는 에러를 미연에 방지

try-except, else, finally

try:
	# 예외가 발생할 수 있는코드
except:
	# 예외 발생시 실행할 코드
else:
	# 예외가 발생하지 않은 경우 실행할 코드
finally:
	# 항생 실행할 코드
    
#######################################################

# 원화를 입력, 환율 입력 - > 달러

won = input("원화 금액을 입력하세요 : ")
dollar = input("환율을 입력하세요 : ")

try: # 예외가 발생할 수 있는코드
    print(int(won) / int(dollar))
except ValueError as  e: 	# 예외 발생시 실행할 코드
    print("문자열 예외가 발생했습니다.", e)
except ZeroDivisionError as e:
    print("나누기 0은 불가능합니다.", e)
else:
    print("예외가 발생하지 않았을 때 실행되는 코드")
finally:
    print("언제나 실행되는 코드")

에러 만들기

raise

raise 예외("예외메세지")

에러 만들기

class 예외(Exception):
	def __init__(self):
    	super().__init__("에러메세지")

2주차 후기

다른 건 딱히 어렵다고 느낀 건 없는데 전부터 헷갈렸던 클래스를 다시 만나니 또 헷갈린다

복습이 중요한 것 같고, 다른 예제를 많이 풀어보면서 내 것으로 만드는 것이 중요해 보인다

3주차 부터는 심화과정인데 기대가 된다.

반응형