import random
rNum = random.randint(100, 1000)
print(f'rNum: {rNum}')
for num in range(1, rNum+1):
soinsuFlag = 0
# 약수
if rNum % num == 0:
print(f'약수 : {num}')
soinsuFlag += 1
# 소수
if num != 1:
flag = True
for n in range(2, num):
if num % n == 0:
flag = False
break
if flag:
print(f'소수 : {num}')
soinsuFlag += 1
# 소인수
if soinsuFlag == 2:
print(f'소인수 : {num}')
먼저 한/영, 영/한 등 사전을 만드는 상위 클래스를 만들어주고, 추상클래스로 구현하여 구체적인 하위 클래스 사전에서 메소드를 만들도록 강제한다.
class KorToEng(AbsDictionary): # 상위 클래스 상속받기
def __init__(self):
super().__init__()
def registWord(self, w1, w2):
print(f'단어 등록 / {w1} : {w2} ')
self.wordDict[w1] = w2
def removeWord(self, w1):
print(f'단어 제거 / {w1}')
del self.wordDict[w1]
def updateWord(self, w1, w2):
print(f'단어 변경 / {w1} : {w2} ')
self.wordDict[w1] = w2
def searchWord(self, w1):
print(f'단어 검색 / {w1} : {self.wordDict[w1]}')
def printWord(self):
for i in self.wordDict:
print(f'{i} -> {self.wordDict[i]}')
상위 추상클래스를 상속 받아 구체적으로 메소드를 구현한다.
import ADictionary as ad # 다른 실행 파일에서 위의 클래스가 저장된 Adictionary.py를 불러온다
kte = ad.KorToEng()
kte.registWord('책', 'bok')
kte.registWord('나비', 'butterfly')
kte.registWord('연필', 'pencil')
kte.registWord('학생', 'studen')
kte.registWord('선생님', 'teacher')
kte.printWord()
kte.updateWord('책', 'book')
kte.searchWord('책')
kte.removeWord('책')
kte.printWord()
이와 같은 방식으로 한영 사전 KorToEng() 클래스를 불러와 kte 인스턴스를 선언한다.
KorToEng 클래스에 구현해 놓은 메소드들을 이용할 수 있게 된다.
📍 소수 판별기 프로그래밍
class NotPrimeException(Exception):
def __init__(self, n):
super().__init__(f'{n} is not a prime number')
class PrimeException(Exception):
def __init__(self, n):
super().__init__(f'{n} is a prime number')
NotPrimeException : 소수가 아니라고 표현하는 (exception 발생시키는 X) 클래스 정의
PrimeException : 소수라고 표현하는 (exception 발생시키는 X) 클래스 정의
def isPrime(number):
flag = True
for i in range(2, number):
if number % i == 0:
flag = False
break
if flag == True:
raise PrimeException(number)
else:
raise NotPrimeException(number)
isPrime 함수 : 숫자가 소수인지 판별하고, 맞다면 PrimeException을, 아니라면 NotPrimeException을 발생(raise)시키는 기능
import Primecheck as pc
import random
prime_nums = []
n = 0
while n < 10:
rn = random.randint(2, 1000)
if rn not in prime_nums:
try:
pc.isPrime(rn)
except pc.PrimeException as e:
print(e)
prime_nums.append(rn)
except pc.NotPrimeException as e:
print(e)
continue
else:
print(f'{rn} is already in')
continue
n += 1
print(prime_nums)
소수를 확인하는 primecheck.py를 불러오기
2 ~ 1000 의 난수가 소수면 PrimeException이 발생하고 리스트에 추가, 소수가 아니면 NotPrimeException이 발생하고 다시 iter를 실행하는 반복문 작성
📍 상품 총 구매금액 계산하기 프로그래밍
g1price = 1200; g2price = 1000; g3price = 800
g4price = 2000; g5price = 900
def calculate(*gcs):
gcsDic = {}
againCntInput = {}
for idx, gc in enumerate(gcs):
try:
gcsDic[f'g{idx+1}'] = int(gc)
except Exception as e:
againCntInput[f'g{idx+1}'] = gc
print(e)
totalPrice = 0
for g in gcsDic:
totalPrice += globals()[f'{g}price'] * gcsDic[g]
totalPrice = format(totalPrice, ',')
print(f'총 구매금액 : {totalPrice}원')
print(f'미결제 항목')
for g in againCntInput:
print(f'상품: {g}, 구매 개수: {againCntInput[g]}')
상품금액 x 구매 개수로 총 구매금액을 구하는데, 개수로 숫자가 아닌 값이 입력되면 예외처리
def sendSMS(msg):
if len(msg) > 10:
raise Exception("길이초과! MMS 전환 후 발송", 1)
else:
print("SMS 발송!")
def sendMMS(msg):
if len(msg) <= 10:
raise Exception("길이미달! SMS 전환 후 발송", 2)
else:
print("MMS 발송!")
msg = "1234567891011"
try:
sendSMS(msg)
except Exception as e:
if e.args[1] == 1:
sendMMS(msg)
elif e.args[1] == 2:
sendSMS(msg)
📍 파일 열기, 읽기, 쓰기
with ~ as 문을 이용하여 파일을 열고, 읽고, 쓸 수 있다.
with open("content/text.txt", 'r') as f: # 읽기
print(f.read())
with open("content/text.txt", 'w') as f: # 쓰기, 이미 있다면 새로 덮어쓴다.
f.write("안녕하세요.")
with open("content/text.txt", 'a') as f: # 쓰기, 이어서 쓴다.
f.write("반갑습니다.")
📍 writelines()
여러 데이터를 포함한 자료형을 쓸 때 사용
alpha = ['a', 'b', 'c', 'd']
with open('contents/text.txt', 'a') as f:
f.writelines(alpha)
📍 readlines()
파일의 모든 데이터를 읽어서 리스트 형태로 반환
with open('contents/text.txt', 'r') as f:
alpha_lst = f.readlines()
자동차를 예로 들면, 자동차의 배터리가 차체와 일체형이 아닌 교체형일 때, 배터리(수정이 필요한 부분)만 교체할 수 있어서(결합도가 낮아서) 이상적인 프로그램을 만들 수 있다.
📍 클래스와 객체
기능들을 아우를 수 있는 클래스를 선언하고 그 안에 각 기능을 만든다.
객체 car1, car2는 클래스를 호출하여 만든 각각의 객체이다. car1과 car2 라는 객체로 작업함으로써 결합도를 낮춰 원본 클래스를 유지하면서 기능하게 할 수 있다.
생성자 __init__은 객체가 생성될 때 먼저 자동 호출된다. 속성을 초기화하는 기능
객체의 속성값(위의 예시에서는 color, length)은 객체에 따라 다르게 지정할 수 있으며, 지정 후에도 변경할수 있다.
car1.color = 'orange' # red를 orange로 변경
📍 얕은 복사, 깊은 복사
car1 = Car('red', 200)
위와 같이 객체를 생성한 경우 car1이라는 변수는 객체의 메모리 주소를 저장하고 이를 통해 객체를 참조한다.
얕은 복사
그런데, car3 = car1 과 같이 car3을 생성할 경우, 객체 자체가 복사되지 않고 참조하는 주소를 복사하게 된다.
즉, car1에서 속성을 변경할 경우 car3의 속성도 변경된다.(같은 주소를 바라보고 있기 때문에)
깊은 복사
깊은 복사를 할 경우, 참조하는 주소를 복사하는 것이 아니라 똑같은 객체를 다른 메모리 주소에 저장한다.
즉, car1에서 속성을 변경해도 car3는 다른 주소를 참조하고 있기 때문에 영향을 받지 않는다.
# 깊은 복사
import copy
car3 = car1.copy()
car3 = copy.deepcopy(car1) # deepcopy()는 배열의 내부 객체까지 복사. 이중 배열이상에서도 완전한 깊은 복사 가능
📍 클래스 상속
클래스는 다른 클래스를 상속하여 상위 클래스의 속성과 기능을 사용할 수 있다.
class CalculatorSuper:
def __init__(self, pNum1, pNum2):
self.pNum1 = pNum1
self.pNum2 = pNum2
def add(self, n1, n2):
return n1 + n2
def sub(self, n1, n2):
return n1 - n2
class CalculatorChild(CalculatorSuper): # 위의 상위 클래스를 상속받는다.
def __init__(self, cNum1, cNum2):
super().__init__(100, 200) # super().__init__ 을 하면 하위 클래스 객체 생성시 상위클래스의 속성 초기화 가능
def mul(self, n1, n2):
return n1 * n2
def div(self, n1, n2):
return n1 / n2
cal = CalculatorChild() # 하위 클래스 객체 생성
cal.add(10, 20) # 상위 클래스의 기능임에도 상속받았기에 사용가능
📍 오버라이딩
오버라이딩 : 하위 클래스에서 상위 클래스의 메서드를 재정의
class Robot:
def fire(self):
print("총알 발사!!")
class NewRobot(Robot): # 상속
def fire(self):
print("레이저 발사!!") # 상위 클래스의 fire 메서드가 아닌 재정의 된 fire로, "레이저 발사!!" 출력
📍 추상클래스
상위 클래스에서 하위 클래스에 메서드 구현을 강요한다.
즉, 상위 클래스에서는 메서드를 선언만 해놓고, 하위 클래스에서 꼭 구현하여야만 기능할 수 있도록 한다.
from abc import ABCMeta
from abc import abstractmethod
class AirPlane(metaclass=ABCMeta):
@abstractmethod
def flight(self): # 추상 클래스를 선언했으므로 하위클래스에서 이 추상 메서드를 꼭 구현하여야만 한다.
pass
class Airliner(AirPlane):
def flight(self): # 추상 메서드 구현
print("시속 400km/h 비행!!")
인수의 개수를 특정하지 않을 때에는 addCal(*num) 과 같이 적으면 정해지지 않은 개수의 인수를 입력 가능
# x, y 를 입력하면 x + y를 반환하는 함수
def addCal(x, y):
return x + y
📍 함수 내에서 다른 함수 호출하기
구구단 2단 함수를 호출하면 3단도 이어서 호출하는 구조 작성하기
def guguDan2():
for i in range(1, 10):
print('2 * {} = {}'.format(i, 2*i))
guguDan3() # 함수 안에서 다른 함수 호출
def guguDan3():
for i in range(1, 10):
print('3 * {} = {}'.format(i, 3*i))
guguDan2() # 만든 함수를 호출하면 guguDan3도 함께 호출
📍 함수 만들기 실습
사용자가 길이(cm)를 입력하면 mm로 환산한 값을 반환하는 함수
def cmToMm(cm):
result = cm * 10
return result
length = float(input('길이(cm) 입력: '))
returnValue = cmToMm(length)
print(f'mm 반환값은 {returnValue}mm 입니다.')
📍 전역변수와 지역변수
전역변수 : 함수 밖에 선언된 변수, 함수안에서 재정의 하더라도 시스템에서는 수정되지 않는다.
# num이 10 보다 크면 if 이하 실행, 작거나 같으면 else 이하 실행
num = 6
if num > 10:
print('정답입니다.')
else:
print('오답입니다.')
# 점수에 따라 등급 매기기
score = 77
if score > 90:
print('A')
elif score > 80: # elif -> else if -> 그렇지 않고 이렇다면~ 실행
print('B')
elif score > 70: # 여기에서 True 이므로 C 출력
print('C')
else:
print('D')
📍 조건식
조건을 바탕으로 식 만들기 (ex. 조건에 따라 변수에 값을 다르게 할당)
# 한국이면 블레이크를, 아니라면 Blake를 name에 할당
country = '미국'
name = '블레이크' if country == '한국' else 'Blake'
# name = 'Blake' 할당
📍 중첩 조건문
조건문 안에 또 다른 조건문이 있는 구조
score = 68
if score <= 70:
print('재시험')
# 그렇지 않은 경우, 다시 조건에 따라 나눈다
else:
if score > 90:
print('A')
elif score > 80:
print('B')
elif score > 70:
print('C')
📍 반복문
반복문의 종류
횟수에 의한 반복 : 횟수를 정하고 그만큼 반복 실행
for i in range(10):
print(i)
# 1, 2, 3, 4, 5, 6, 7, 8, 9 반복 출력
조건에 의한 반복 : 조건을 정하고 조건이 만족하는 한 계속 반복 실행
num = 0
while (num < 10):
print(num)
num += 1
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 까지 출력 반복 실행하고, 그다음 10이 넘어가므로 종료