import datetime
from datetime import datetime, date
from re import findall, match, sub
#jumin = '202229-3234567'
jumin = '990101-3034918'
#jumin = input('주민등록번호를 입력하세요(하이픈 포함)')
print('입력한 주민등록번호는 : ', jumin, '입니다')
flag = {}
if int(jumin[7]) == 1 or int(jumin[7]) == 2: year = int(jumin[0:2]) + 1900
if int(jumin[7]) == 3 or int(jumin[7]) == 4: year = int(jumin[0:2]) + 2000
#
if year % 4 ==0 :
if year % 100 == 0 :
if year % 400 == 0:
year = '윤년'
month = [31,29,31,30,31,30,31,31,30,31,30,31]
else:
year = '평년'
month = [31,28,31,30,31,30,31,31,30,31,30,31]
else:
year = '윤년'
month = [31,29,31,30,31,30,31,31,30,31,30,31]
else:
year = '평년'
month = [31,28,31,30,31,30,31,31,30,31,30,31]
#
# print('평년/윤년 ---> ',year) # 서비스코드
#
result = match('[0-9]{6}-[1-4][0-9]{6}', jumin)
if len(jumin[0:]) > 14 :
flag['flag1'] = '년도의 자리수 또는 뒷자리의 첫 숫자오류'
flag1 = False
else:
flag['flag1'] = '*'
flag1 = True
#
if 1 <= int(jumin[2:4]) <= 12 : # 월의 숫자를 필터링
flag['flag2'] = ''
flag2 = True
else:
flag['flag2'] = '앞자리의 월 오류'
flag2 = False
#
if len(jumin[7:]) > 7 :
flag['flag3'] = '뒷자리의 글자수 오류'
flag3 = False
else:
flag['flag3'] = '*'
flag3 = True
#
if result and flag1 and flag2 and flag3 :
print('****주민번호 필터링 성공 ')
else :
print('잘못된 주민번호')
print('flag[flag1] : ', flag['flag1'])
print('flag[flag2] : ', flag['flag2'])
print('flag[flag3] : ', flag['flag3'])
if year % 4 ==0 :
if year % 100 == 0 :
if year % 400 == 0:
year = '윤년'
month = [31,29,31,30,31,30,31,31,30,31,30,31]
else:
year = '평년'
month = [31,28,31,30,31,30,31,31,30,31,30,31]
else:
year = '윤년'
month = [31,29,31,30,31,30,31,31,30,31,30,31]
else:
year = '평년'
month = [31,28,31,30,31,30,31,31,30,31,30,31]
if len(jumin[0:]) > 14 :
flag['flag1'] = '년도의 자리수 또는 뒷자리의 첫 숫자오류'
flag1 = False
else:
flag['flag1'] = '*'
flag1 = True
if 1 <= int(jumin[2:4]) <= 12 : # 월의 숫자를 필터링
flag['flag2'] = ''
flag2 = True
else:
flag['flag2'] = '앞자리의 월 오류'
flag2 = False
if 1 <= int(jumin[2:4]) <= 12 : # 월의 숫자를 필터링
flag['flag2'] = ''
flag2 = True
else:
flag['flag2'] = '앞자리의 월 오류'
flag2 = False
#
if len(jumin[7:]) > 7 :
flag['flag3'] = '뒷자리의 글자수 오류'
flag3 = False
else:
flag['flag3'] = '*'
flag3 = True
프로그램 소스를 기준으로 외부에서 입력된 수많은 형식의 데이터가 있습니다.
csv형식, text형식, json형식 등이 있습니다.
개발자는 이러한 형식의 데이터가 자신의 코드를 실행하는데 문제를 일으키지 않도록 점검해야 합니다.
이러한 과정을 필터링이라고 합니다.
숙련된 개발자로 인정받기 위한 좋은 방법은 자신만의 필터링 경험을 축적하는 것입니다.
다른 개발자에 비하여 고급스런 결과물을 만들어 내기 위해 필터링을 고도화 하려는 태도는 매우 바람직합니다.
# 맨 위 코드에 이어서 추가
if 1 <= int(jumin[4:6]) <= month[(int(jumin[2:4]))-1] : # (1)
flag['flag4'] = '*'
flag4 = True
else:
flag4 = False
flag['flag4'] = '앞자리중 월에 대한 일자 오류'
#
###
if result and flag1 and flag2 and flag3 and flag4 and flag4 :
print('****주민번호 필터링 성공 ')
else :
print('잘못된 주민번호')
print('flag[flag1] : ', flag['flag1'])
print('flag[flag2] : ', flag['flag2'])
print('flag[flag3] : ', flag['flag3'])
print('flag[flag4] : ', flag['flag4'])
(1) 일의 숫자가 1 이상이면서 month 리스트의 해당 인덱스 요소의 숫자 이하인지 필터링
→ 앞선 코드에서 아래와 같이 작성한 이유가 여기에 있음

논리의 분기점을 만드는 로직을 만들어야 할 때 이런 방식으로 동작하는 방법도 있다는 걸 알아두면 좋아요.


(+, -)는 외부에서 접근 가능 여부: -는 은닉(private), +는 공용화(public)

→ 클래스와 객체는 1:N의 관계
함수(Function) vs. 메서드(Method) ★★
함수는 독립된 기능을 수행하는 코드(명령문)들의 집합
메서드는 클래스에 포함되어 있는 함수
→ 기능적으로는 매우 비슷
→ 그러나 어느 곳에 존재하는지에 따라 메서드와 함수는 구분해야 함!
# 중첩 함수 형식
def outer_func(매개변수):
변수 선언
def inner_func(매개변수):
명령문
return 값
return 내부함수
외부함수(인수)
# 클래스 형식
class ClassName:
변수 선언
def 생성자(매개변수):
명령문
def 함수명(매개변수):
명령문
# 여기서 함수명 == 메서드명
# def 함수, def 메서드 둘 다 ok
→ 객체를 생성하기 위해 '생성자'라는 특수한 함수를 포함
생성자(Constructor)
객체 지향 프로그래밍에서 객체가 생성될 때 초기화시켜주는 함수
파이썬 생성자 이해하기
클래스 내에서 특별한 이름(__init__)을 갖기만 하면 객체가 생성될 때 자동으로 호출되는 함수 → 객체가 생성될 때 자동으로 생성자인__init__()이 호출됨
생성자는 객체가 생성될 때 사용자가 따로 호출하지 않아도 자동으로 호출되기 때문에 객체를 초기화하거나 초깃값을 설정하는데 유용하게 사용됩니다
클래스 생성자
# (1) 함수 정의
def calc_func(a, b): # 외부함수
# 변수 선언: 자료 저장
x = a # 10
y = b # 20
def plus(): # 내부함수
p = x + y
return p
def minus(): # 내부함수
m = x - y
return m
return plus, minus
# (2) 함수 호출
p, m = calc_func(10, 20)
print("plus =", p())
print("minus =", m())
(1) 함수 정의
(2) 함수 호출
# (3) 클래스 정의
class CalcClass:
# 클래스 변수: 자료 저장
x = y = 0
# 생성자: 객체 생성+[멤버변수 초기화]
def __init__(self, a, b): # A
self.x = a # 10
self.y = b # 20
# 클래스 함수 / 멤버 함수(기능)
def plus(self): # B
p = self.x + self.y # 변수 연산 C
return p
# 클래스 함수 / 멤버 함수(기능)
def minus(self):
m = self.x - self.y # 변수 연산
return m
# (4) 객체 생성: 생성자 → 객체 1
obj = CalcClass(10, 20) # D
# (5) 멤버 호출 # obj.member()
print("plus = ", obj.plus()) # plus = 30
print("minus = ", obj.minus()) # minus = -10
# 추가
obj2 = CalcClass(100, 50) # 생성자 → 객체2
print("plus = ", obj.plus()) # plus = 30
print("minus = ", obj.minus()) # minus = -10
print(id(obj), id(obj2))
(3) 클래스 정의
(4) 객체 생성
(5) 멤버 호출
"내가 그의 이름을 불러주었을 때, 그는 내게로 와서 꽃이 되었다."의 싯구를 코드에 대응하면 다음과 같습니다:
시인의 이상향
→class CalcClass:의 클래스 선언: line 2-19
→ 문서에 해당하는 것(문서 중 아직 이론적으로만 존재하고 현실적이지 않은 것: 사진의 점선)
→ 프로그램에서 읽기 참조/쓰기 참조 불가
이름을 부르는 행위
→CalcClass(10, 20)의 객체 생성
→ 객체가 만들어졌다 == 클래스 안에 정의된 여러 개의 멤버를 실제로 참조할 수 있는 상태다
내게로 와서 꽃이 된 그
→ obj 참조변수가 가리키는 곳에 존재하는 오브젝트
※ A: 괄호 안의 a와 b는 함수의 선언과 호출 중에서 함수 선언의 매개변수에 해당함
※ B: self → 멤버(변수+함수) 참조 객체
※ C: p → 지역변수, self.x, self.y → 전역변수
※ D: 괄호 안 10과 20은 함수의 선언과 호출 중에서 함수 호출의 인수에 해당함

Q.
obj = CalcClass(10, 20)에서CalcClass(10, 20)가 함수 호출이면 앞의obj는 뭔가요?
A. 참조변수입니다.
- 변수
- 필요한 자료를 일시적으로 보관하거나 처리 결과를 담을 수 있는 기억장소 역할
- 실제 값을 저장하는 메모리(Memory) 이름으로 할당됨
- 메모리에 값이 저장된다는 것은 변수에 값이 저장된다는 의미
- 파이썬 변수는 변수에 저장될 값이 먼저 메모리에 객체(Object) 저장된 후 객체의 주소가 변수에 저장됨 → 실제값이 저장되지 않고, 실제값이 저장된 "주소"를 기억하는 참조형 변수가 됨
- 참조형 변수의 특징
- 객체의 자료형에 의해서 변수의 자료형이 결정되기 때문에 변수 선언 시 별도의 자료형을 선언하지 않음
- 파이썬 변수와 메모리 주소 관계
- X 변수에 3.14159를 초기화 할 경우 메모리에 3.14159가 객체로 저장된 후 메모리 주소 12345가 X변수에 할당됨
- 파이썬 변수는 방대한 자료, 함수, 그리고 차드 등 다양한 유형의 객체를 담을 수 있는 막강한 역할을 함

a, b(위 코드에서 10, 20에 해당)
※ 추가
obj = CalcClass(10, 20)과는 별개로 또 하나의 객체를 생성함
해당 객체는 obj2라는 참조변수로 참조
→ obj 참조변수의 주소와 obj2 참조변수의 주소는 다름!


__init__이라는 별도의 이름을 가짐class Car:
# (1) 멤버변수
cc = 0 # 엔진 cc
door = 0 # 문짝 개수
carType = None # null
# (2) 생성자
def __init__(self, cc, door, carType):
# 멤버 변수 초기화
self.cc = cc
self.door = door
self.carType = carType # 승용차, SUV
# (3) 메서드
def display(self):
print("자동차는 %d cc이고 문짝은 %d개, 타입은 %s"
%(self.cc, self.door, self.carType))
# (4) 객체 생성
car1 = Car(2000, 4, "승용차") # 객체 생성 + 초기화
car2 = Car(3000, 5, "SUV")
# (5) 멤버 호출: object.member()
car1.display() # car1 멤버 호출
car2.display() # car2 멤버 호출
(1) 멤버변수
(2) 생성자
__init__이라는 이름과 self 매개변수를 이용하여 선언실인수(argument)라는 개념은 가인수(parameter)의 상대적인 개념
→ 인수를 말할 때 용어를 구별해서 사용해야 함!
실인수(argument; actual parameters): 호출하는 곳, 실제값이 주어지는 곳
가인수(parameter; formal parameters): 호출받는 곳, 값을 받는 곳
(3) 메서드
(4) 객체 생성
참조변수 = Car(실인수)Car(2000, 4, "승용차") 형식의 명령문은 3개의 멤버변수에 각각 cc=2000, door=4, carType="승용차"가 할당되어 car1 참조변수를 가지는 객체가 생성됨(5) 멤버 호출
참조변수.멤버(멤버변수 or 메서드)__init__()이란 이름으로 제공
참조변수 = 클래스이름(실인수)
객체를 생성할 때는 생성자가 포함된 클래스이름 뒤에 괄호()를 붙이고 매개변수에 전달될 실인수를 괄호에 넣어 함수를 호출하듯 객체를 생성
→ 생성된 객체의 주소는 참조변수에 할당됨
→ 참조변수를 이용해 객체의 멤버 호출 가능
# (1) 생성자 이용 멤버변수 초기화
class Multiply:
# 멤버 변수
x = y = 0 # 멤버변수가 만들어짐
# 생성자: 초기화
def __init__(self, x, y):
self.x = x
self.y = y
# 메서드
def mul(self):
return self.x * self.y
obj = Multiply(10, 20) # 생성자
print("곱셈 = ", obj.mul())
(1) 생성자 이용 멤버변수 초기화
__init__(self, x, y)를 정의# (2) 메서드 이용 매개변수 초기화
class Multiply2:
# 멤버 변수
x = y = 0
# 생성자 없음: 기본 생성자 제공
def __init__(self):
pass # 내용 없음을 의미함
# 메서드: 멤버변수 초기화
def data(self, x, y):
self.x = x
self.y = y
# 메서드: 곱셈
def mul(self):
return self.x * self.y
obj = Multiply2() # 기본 생성자
obj.data(10, 20) # 동적 멤버변수 생성
print("곱셈 = ", obj.mul())
(2) 메서드 이용 멤버변수 초기화
def __init__(self):
pass
소멸자(Destructor)
→ 생성자의 반대 역할
→__del__()이란 이름으로 제공
객체 사용이 완료되면 자동으로 실행되어 객체를 메모리에서 소멸시키는 역할
파이썬 자체에서 메모리 관리를 자동으로 해주기 때문에 많이 사용되지는 않음
# 소멸자 사용 예시
class Multiply:
# 생성자: 객체 생성 + 멤버변수 초기화
def __init__(self, x, y):
self.x = x
self.y = y
# 소멸자: 객체 소멸
def __del__(self):
del self.x
del self.y
self.멤버변수
self.메서드()
class Multiply3:
# 멤버변수 없음 → 이전의 소스코드(x = y = 0)와 비교해볼 것
# 생성자 없음 → def __init__(self): 없음
# 동적 멤버변수 생성/초기화
def data(self, x, y):
self.x = x # 멤버변수를 동적으로 할당(생성) → 동적으로 멤버변수가 생성된 후 초기화됨
self.y = y
# 곱셈 연산
def mul(self):
result = self.x * self.y
self.display(result) # 메서드 호출
# 결과 출력
def display(self, result):
print("곱셈 = %d"%(result))
obj = Multiply3() # 기본 생성자
obj.data(10, 20)
obj.mul()
@classmethod라는 함수 장식자를 이용해 선언
class DatePro:
# (1) 멤버 변수
content = "날짜 처리 클래스"
# (2) 생성자
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
# (3) 객체 메서드(instance method)
def display(self):
print("%d-%d-%d"%(self.year, self.month, self.day))
# (4) 클래스 메서드(class method)
@classmethod # 함수 장식자
def date_string(cls, dateStr): # '19951025'
year = dateStr[:4]
month = dateStr[4:6]
day = dateStr[6:]
print(f"{year}년 {month}년 {day}일")
# (5) 객체 멤버
date = DatePro(1995, 10, 25) # 생성자 ★
print(date.content) # 날짜 처리 클래스
print(date.year) # 1995
date.display() # 1995-10-25
# (6) 클래스 멤버
print(DatePro.content) # 날짜 처리 클래스
# print(DatePro.year) # AttributeError: year는 객체의 멤버변수이기 때문
DatePro.date_string("19951025") # 1995년 10월 25일
(1) 멤버 변수
(2) 생성자
self.멤버변수로 선언된 변수는 객체 멤버변수만 됨(3) 객체 메서드(instance method)
(4) 클래스 메서드(class method)
@classmethod라는 함수 장식자(decorator, 데코레이터)를 이용해 먼저 선언한 후 클래스 메서드를 정의(5) 객체 멤버
date는 '참조변수'(또는 '객체'라고 부르기도 함)DatePro(1995, 10, 25)는 객체 생성: 생성자 호출(6) 클래스 멤버