-
Python 기초 공부 - 4Programming/Python 2021. 3. 6. 15:47반응형
4일차
2019.12.30
객체 지향 프로그래밍 (class -> (instance) Object)
- Class : 멤버변수(속성) + 멤버함수(공유되어 지어짐)
- 인스턴스할 때 멤버변수(속성)을 저장하는 공간만 확보
class Triangle: def setData(self, width, height): # 함수를 이용한 초기화 self.width=width self.height=height def area(self): # self는 매개변수 취급을 안함, 넣어야만 함수로 만들수있음. return self.width*self.height/2 tri1 = Triangle() # 인스턴스 한다. () 함수처럼 tri1.setData(10,20) print(tri1.width, tri1.height, tri1.area())
10 20 100.0
# __init__ : Object에 있는 함수 (상속) class Triangle : def __init__(self,width,height): # 초기화 함수, 생성자, 강제로 호출불가한 함수 self.width = width self.height = height def area(self): return self.width*self.height/2 tri1 = Triangle(10,20) # tri1.__init__(10,20) 불가, 인스턴스 할 때 자동으로 호출 print(tri1.width,tri1.height,tri1.area())
10 20 100.0
# 클래스변수, 멤버변수, 지역변수 class Myclass(object): # 선언하는 순간에 메모리에 자리를 잡읍 """클래스의 예""" i = 12345 # class변수 , 공용변수 def __init__(self): self.i = 54321 # 멤버변수 num = 100 # 지역변수 def f(self): return self.i Myclass.__doc__ # Object의 속성
'클래스의 예'
myclass=Myclass() # self.i에 대한 메모리 확보 print(myclass.i) # 멤버변수호출 myclass.f()
54321
54321
print(myclass.i) print(Myclass.i) print(Myclass().i) # 참조가 없기 때문에 사용과 동시에 메모리에서 사라짐.
54321
12345
54321
from time import time, ctime, sleep # 시간은 초로 관리 ctime(문자열로 convert) class Life: def __init__(self): # 생성자 self.birth = ctime() # 현재의 시간을 문자열로 변환 print ('생성', self.birth) def __del__(self): # 소멸자 (메모리에서 사라질때 자동으로 호출) print ('사망', ctime()) def test(self): #mylife = Life() print('Sleeping for 3 sec') sleep(3) # 초 li = Life() # 오른쪽은 heap에 저장, 왼쪽은 그 주소를 가리키는 stack에 생성 li.test() del li # 자동으로 가비지 컬렉션됨.
생성 Mon Dec 30 11:10:05 2019 Sleeping for 3 sec 사망 Mon Dec 30 11:10:08 2019
# 사원관리 class Employee: empCount = 0 # 사원수를 저장 : 클래스 변수 생성 def __init__(self, name, salary): self.name = name # 이름 self.salary = salary # 급여 Employee.empCount +=1 def displayCount(self): print("직원수 = %d" % Employee.empCount) def displayEmployee(self): print("이름: ", self.name, ", 급여 : ", self.salary) def __call__(self, *pargs, **kargs): print("Called:", pargs, kargs)
emp = Employee("임준영", 500) print(emp.displayCount()) # 1 emp1 = Employee("빅데이터", 500) print(emp1.displayCount()) # 2 공유변수이기 때문 print(emp.displayEmployee()) # 2 데이터를 담고있는 위치가 다르기 때문 print(emp1.displayEmployee()) print(emp("빅데이터", 500,100, c=100)) # class를 함수처럼 사용하고 싶을때. # __call__을 오버라이딩
직원수 = 1
None 직원수 = 2
None 이름: 임준영 , 급여 : 500
None 이름: 빅데이터 , 급여 : 500
None Called: ('빅데이터', 500, 100) {'c': 100}
None
# 실시간으로 변수를 추가가능 emp1.age = 7 emp.age = 8
print(emp.__dict__) # object 를 상속
{'name': '임준영', 'salary': 500, 'age': 8}
문제
- 이름과 나이를 저장하는 Student class를 생성하시오
- 이름과 나이를 출력하는 pring 함수를 클래스내에 정의하시오
class Student: def __init__(self, name, age): """학생관리""" self.name = name self.age = age def pring(self): print("이름 :", self.name, ", 나이 : ", self.age) def __repr__(self): #__str__ return "나의 이름은 " + self.name
hhh = Student("임준영",24) hhh.pring() print(hhh)
이름 : 임준영 , 나이 : 24
나의 이름은 임준영
# object로 부터 상속 print(hhh.__class__) # 어떤 클래스에서 인스턴스 되었는지를 확인
<class '__main__.Student'>
#Student("임준영", 24) g = hhh.__class__("임준영", 24) # 인스턴스된 변수로 부터 클래스 생성 print(g)
# x1=10;y1=20 # x2=20;y2=30 # distance = math.sqrt ((x1-x2)**2+(y1-y2)**2) import math # 1개를 다루는 클래스를 작성하고 있지만 거리값은 두개를 이용 class Point: def __init__(self,x,y): self.x=x self.y=y def __srt__(self): # __repr__ 문자열을 요구하는 함수에 들어가면 실행 return "좌표는 (%d, %d)" % (self.x, self.y) def dist(self, other): # 피타고라스 정리 distance=math.sqrt((self.x-other.x)**2+(self.y-other.y)**2) return distance def collision(self,other): return self.dist(other)<3
xx = Point(7,3) xx2 = Point(4,7) print(xx) print(xx2) xx.dist(xx2)
print("두점 사이의 거리는 = ", xx.dist(xx2)) if xx.collision(xx2): print("충돌했습니다.") else: print("충돌하지 않았습니다.")
문제: point 클래스를 이용하여 Circle 클래스를 정의하시오
- 원 : 중심점하고 반지름
- 원과 원이 충돌하는지를 확인하는 함수를 작성하시오.
- 서로 반지름이 차이가 중심점하고의 거리에 들어가면 충돌임.
import math joong = point(3,4) class circle: def __init__(self,joong,ban): self.joong = joong self.ban = ban def dist(self): return "원의중심은 " + str(self.joong) + "반지름은 " + str(self.ban) def coll(self,other): if self.joong.dist(other.joong) < self.ban + other.ban : result = "충돌한다" else: return "충돌하지 않는다." return result
cir = circle(xx, 1) cir2 = circle(xx2, 5) print(cir) print(cir2)
<__main__.circle object at 0x00000160E3B3DC08>
<__main__.circle object at 0x00000160E3B3D708>
print(cir.coll(cir2)) circle.coll(cir,cir2) # self
충돌한다
'충돌한다'
point 를 이용해서 사각형 Rectangle 클래스를 작성하시오
- 사각형의 면적을 구하는 함수를 작성하시오 x1-x2 * y1-y2
- 사각형의 둘레를 구하는 함수를 작성하시오 (x1-x2) * 2 + (y1 - y2)
- 대각선의 길이를 구하는 함수를 작성하시오 (x1-x2)*2 + (y1 - y2) *2
class Rectangle: def __init__(self, po1,po2): # po1 = Point() 매핑 self.po1 = po1 self.po2 = po2 def area(self): result = abs((self.po1.x - self.po2.x) * (self.po1.y - self.po2.y)) return result def perimeter(self): result = abs(self.po1.x - self.po2.x)*2 + abs(self.po1.y - self.po2.y)*2 return result def diagonal_dist(self): result = math.sqrt((self.po1.x-self.po2.x)**2+(self.po1.y - self.po2.y)**2) return result
vector = 길이 = 크기 + 방향
- 내적 유사도 = cos 유사도 = dot연산 , 요소끼리 곱하고 다 더해주면됨.
- A'B
- A = [10,20,30] , B = [20,30,40]
- A'B = [10 * 20 + 20 * 30 + 30 * 40]
xx = Point(7,3) xx1 = Point(4,9) re = Rectangle(xx,xx1) print(re.perimeter())
18
문제 : Vector class를 작성하시오
- x,y의 2차원 벡터 구현
- 벡터의 연산 (+,-,*,/) : 요소별로 계산하면됨.
- dot 함수를 구현하시오 : 백터의 요소별로 곱하고 모두 더해주면 내적 유사도
- cos 값으로 변환하는 함수를 구현하시오 cos theta = acos(A내적B/|A||B|) |A| = math.sqrt(x^2 + y^2)
class Vector: def __init__(self,x,y): self.x = x self.y = y def __repr__(self): return "(좌표는 %d, %d)" % (self.x, self.y) def __add__(self, other): #연산자 오버로딩을 오버 라이딩으로 구현할것 return Vector(self.x + other.x, self.y + other.y) def __mul__(self,other): return Vector(self.x * other.x, self.y * other.y) def __sub__(self,other): return Vector(self.x - other.x, self.y - other.y) def __truediv__(self,other): return Vector(self.x / other.x , self.y / other.y)
f = Vector(10,20) g = Vector(20,27) print(f) print(f+f) print(f+g) print(f*g) print(f/g) print(f-g)
(좌표는 10, 20)
(좌표는 20, 40)
(좌표는 30, 47)
(좌표는 200, 540)
(좌표는 0, 0)
(좌표는 -10, -7)
3차원 벡터를 클래스로 구현하시오. (연산자 오버로딩 +,-,*,/)
import math class Vector: def __init__(self,x,y,z): self.x = x self.y = y self.z = z def __repr__(self): return "(좌표는 %d, %d, %d)" % (self.x, self.y, self.z) def __add__(self, other): #연산자 오버로딩을 오버 라이딩으로 구현할것 return Vector(self.x + other.x, self.y + other.y , self.z + other.z ) def __mul__(self,other): return Vector(self.x * other.x, self.y * other.y, self.z * other.z) def __sub__(self,other): return Vector(self.x - other.x, self.y - other.y, self.z - other.z) def dist(self): return math.sqrt(self.x*self.x+self.y*self.y+self.z*self.z) # 방향만 바뀌어야지 크기까지 바뀌면 안됨 def norm(self): dist = self.dist() return self.x/dist, self.y/dist, self.z/dist def dot(self,other): return (self.x*other.x + self.y * other.y + self.z * other.z) def theta(self,other): dot = self.dot(other) dist1 = self.dist() dist2 = other.dist() # radian -> degree 로 (컴퓨터는 라디안 만 사용) return math.acos(dot/(dist1*dist2)) * (180/math.pi) # 변환과정이 필요 -> 사람이 사용하는 각도입력(90도) -> 라디안 변환(math.pi/180) -> 계산후 # -> 사람이 사용하는 degree로 변환해서 출력
f = Vector(10,20,25) g = Vector(20,27,35) q = Vector(30,37,40) print(f+g+q) print(f*g*q) print(f-g-q) print()
(좌표는 60, 84, 100)
(좌표는 6000, 19980, 35000)
(좌표는 -40, -44, -50)
f = Vector(10,0,0) g = Vector(0,27,0) print(f) print(f+f) print(f-g) print(f*g) print("f벡터의 크기 = ", f.dist()) print("g벡터의 크기 = ", g.dist()) print("f의 normal vector = ", f.norm()) # 1.0 0.0 0.0 print("g의 normal vector = ", g.norm()) # 0.0 1.0 0.0 print("두 벡터의 내적 = ", g.dot(f)) # 0 내적이 0이면 두 벡터는 90도 직교한다. print("f와 g의 사이각은 = ", f.theta(g)) # 90
(좌표는 10, 0, 0)
(좌표는 20, 0, 0)
(좌표는 10, -27, 0)
(좌표는 0, 0, 0)
f벡터의 크기 = 10.0
g벡터의 크기 = 27.0
f의 normal vector = (1.0, 0.0, 0.0)
g의 normal vector = (0.0, 1.0, 0.0)
두 벡터의 내적 = 0
f와 g의 사이각은 = 90.0# deep copy와 copy의 차이 import copy a=[1,2,3] b=[4,5,a] # 주소 x=[a,b,10] y=copy.copy(x) t=copy.deepcopy(x) # 주소복사 e=copy.deepcopy(y) # 원래의 요소를 별도의 공간에 복사한 다음 주소전달 print("a = ", a) print(x) print(y) print(t) print(e) a.append(100) print(x) print(y) print(t) print(e)
a = [1, 2, 3]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]
[[1, 2, 3, 100], [4, 5, [1, 2, 3, 100]], 10]
[[1, 2, 3, 100], [4, 5, [1, 2, 3, 100]], 10]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]
[[1, 2, 3], [4, 5, [1, 2, 3]], 10]이름, 국어, 수학, 영어를 관리하는 Studunt class를 작성하시오. (1인분만 관리)
- 총점과 평균도 계산해서 멤버 변수에 저장
class Student: studCount = 0 def __init__(self,name,kor,eng,mat): self.name = name self.kor = int(kor) self.eng = int(eng) self.mat = int(mat) self.tot = self.kor + self.mat + self.eng self.avg = self.tot / 3 Student.studCount += 1
### 메뉴화 def start(): students = [] while True: choice = input("1.입력 2.출력 3.계산 4.종료 =>") if choice == '1': name = input("이름 : ") kor = input("국어 점수 : ") eng = input("영어 점수 : ") mat = input("수학 점수 : ") stud = Student(name,kor,eng,mat) students.append(stud) elif choice == '2': for s in students: print("이름 :%s 국어:%s 영어:%s 수학:%s 총점:%s 평균:%s" % (s.name, s.kor,s.eng, s.mat,s.tot,round(s.avg,2))) elif choice == '3': kortot =0; engtot=0; mattot=0 for s in students: kortot += s.kor engtot += s.eng mattot += s.mat koravg = round(kortot / len(students),2) engavg = round(engtot / len(students),2) matavg = round(mattot / len(students),2) print("총 학생수 : %s명" % len(students)) print("국어평균: %s\t\t영어평균 : %s\t\t 수학평균: %s\t\t" % (koravg,engavg,matavg)) elif choice == '4': break start()
1.입력 2.출력 3.계산 4.종료 => 임준영
1.입력 2.출력 3.계산 4.종료 => 1
이름 : 임준영
국어 점수 : 80
영어 점수 : 80
수학 점수 : 80
1.입력 2.출력 3.계산 4.종료 => 1
이름 : 하하
국어 점수 : 80
영어 점수 : 75
수학 점수 : 96
1.입력 2.출력 3.계산 4.종료 => 2
이름 :임준영 국어:80 영어:80 수학:80 총점:240 평균:80.0
이름 :하하 국어:80 영어:75 수학:96 총점:251 평균:83.67
1.입력 2.출력 3.계산 4.종료 => 3
총 학생수 : 2명
국어평균: 80.0 영어평균 : 77.5 수학평균: 88.0
1.입력 2.출력 3.계산 4.종료 => 42개로 분리된 class
- 기본적인 데이터를 저장하는 클래스
- Management(입력, 출력, 검색, 수정등)
- 메뉴함수
import sys class Student: def __init__(self): self.bunho=0; self.name = ''; self.kor = 0; self.mat = 0; self.eng = 0 self.total = 0; self.aver = 0; self.grade="" def inputData(self): self.name = input("이름을 입력하시오 : ") self.kor = eval(input("국어 점수 : ")) self.mat = eval(input("수학 점수 : ")) self.eng = eval(input("영어 점수 : ")) def calc_total_aver(self): self.total = self.kor + self.mat + self.eng self.aver = round(self.total / 3,2) self.grade = self.calcSemGrade() def calcSemGrade(self): if self.aver >= 90: return "A" elif self.aver >= 80: return "B" elif self.aver >= 70: return "C" elif self.aver >= 60: return "D" else: return "F" def __str__(self): return '%5s %5s %6.2f %6.2f %6.2f %7.2f %7.2f %5s' % (self.bunho, self.name, self.kor, self.mat, self.eng, self.total, self.aver, self.grade) def __cmp__(self, other): return self.name == other.name
class Management: schoolname = "제주 아카데미" bunho = 0 def __init__(self,count): print("메뉴를 선택하시오") self.sungjuk = [] self.count = count def input(self): for co_in in range(self.count): stu = Student() stu.inputData() Management.bunho += 1 #번호를 자동으로 입력받기위해 stu.bunho = Management.bunho self.sungjuk.append(stu) def print_sungjuk(self): for per in self.sungjuk: print(per) print() def calc_sungjuk(self): for per in self.sungjuk: per.calc_total_aver() def search_name(self): name = input("검색할 학생 이름을 추가하시오") for per in self.sungjuk: if (per.name == name): print(per) return print("검색하고자 하는 학생이 없습니다.") return def research_name(self): name = input("검색할 학생 이름을 검색하시오.") name2 = input("변경할 학생 이름을 검색하시오.") for per in self.sungjuk: if (per.name == name): per.name = name2 print("변경완료") return def del_name(self): name = input("삭제할 학생 이름을 검색하시오.") for per in self.sungjuk: if (per.name == name): self.sungjuk.remove(per) return else: print("삭제할 학생이 없습니다.") def sort_aver(self): return self.sungjuk.sort(key=lambda x: x.total, reverse=True)
sj = ["번호", "이름","국어", "수학","영어","총점","평균","학점"] menu = ["입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)"] # 정렬을 총점으로 정렬 man_sung = Management(1) while 1: sel = input(menu) if sel == "1": man_sung.input() continue elif sel == "2": print(Management.schoolname + "성적 계산표") print('%5s %5s %6s %6s %6s %7s %7s %7s' % ('번호','이름','국어','수학','영어','총점','평균','학점')) man_sung.print_sungjuk() continue elif sel == "3": man_sung.calc_sungjuk() print("계산이 완료 되었습니다. - 확인하려면 출력해보세요") continue elif sel == "4": man_sung.search_name() continue elif sel == "5": man_sung.research_name() continue elif sel == "6": man_sung.del_name() continue elif sel == "7": man_sung.sort_aver() continue elif sel == "8": break else: print(" 잘못된 입력입니다. 다시입력하세요. ") continue
메뉴를 선택하시오
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 1
이름을 입력하시오 : qwe
국어 점수 : 12
수학 점수 : 12
영어 점수 : 12
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 1
이름을 입력하시오 : qweqwe
국어 점수 : 21
수학 점수 : 21
영어 점수 : 12
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
1 qwe 12.00 12.00 12.00 0.00 0.00
2 qweqwe 21.00 21.00 12.00 0.00 0.00
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 3
계산이 완료 되었습니다. - 확인하려면 출력해보세요
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
1 qwe 12.00 12.00 12.00 36.00 12.00 F
2 qweqwe 21.00 21.00 12.00 54.00 18.00 F
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 1
이름을 입력하시오 : qwe
국어 점수 : 112
수학 점수 : 123
영어 점수 : 13
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 4
검색할 학생 이름을 추가하시오 qwe
1 qwe 12.00 12.00 12.00 36.00 12.00 F
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
1 qwe 12.00 12.00 12.00 36.00 12.00 F
2 qweqwe 21.00 21.00 12.00 54.00 18.00 F
3 qwe 112.00 123.00 13.00 0.00 0.00
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 5
검색할 학생 이름을 검색하시오. qwe
변경할 학생 이름을 검색하시오. rrrr
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
1 rrrr 12.00 12.00 12.00 36.00 12.00 F
2 qweqwe 21.00 21.00 12.00 54.00 18.00 F
3 qwe 112.00 123.00 13.00 0.00 0.00
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 7
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
2 qweqwe 21.00 21.00 12.00 54.00 18.00 F
1 rrrr 12.00 12.00 12.00 36.00 12.00 F
3 qwe 112.00 123.00 13.00 0.00 0.00
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 6
잘못된 입력입니다. 다시입력하세요.
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 6
삭제할 학생 이름을 검색하시오. qwe
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 2
제주 아카데미성적 계산표
번호 이름 국어 수학 영어 총점 평균 학점
2 qweqwe 21.00 21.00 12.00 54.00 18.00 F
1 rrrr 12.00 12.00 12.00 36.00 12.00 F
['입력(1), 출력(2),계산(3),검색(4),이름수정(5) , 이름삭제(6),정렬(7), 종료(8)'] 8반응형'Programming > Python' 카테고리의 다른 글
Python 기초 공부 - 6 (Pandas) (0) 2021.03.08 Python 기초 공부 - 5 (mariaDB 연동) (0) 2021.03.07 Python 기초 공부 - 3 (0) 2021.03.05 Python 기초 공부 - 2 (0) 2021.03.04 Python 기초 공부 - 1 (0) 2021.03.04