Point concept
point는 평면뿐만 아니라 위도 경도가 있는 한점, 3차원의 한점.. 등 많음
하나의 단위. tuple과 유사 그러나 blank.x = 10처럼 개별적으로 변경 가능 x와 y 각각을 개별적으로 바꾸지 않도록 정의를 해야함 -> 둘 중 하나만 바뀌어도 다른 점이 되기 때문
1
2
3
4
5
6
7
8
class Point:
def __init__(self):
self.x = 0
self.y = 0
def x(self):
return self._x
def y(self):
return self._y
Point method
현재 위치에서 얼마만큼을 옮겨가달라는 메소드가 있으면 점을 제대로 옮길 수 있음
1
2
3
4
5
6
7
8
9
class Point:
...
def move(self,dx,dy):
self._x += dx
self._y += dy
def distance(self, other):
dx = self.x() - other.x()
dy = self.y() - other.y()
return math.sqrt(dx**2 + dy**2)
Vector concept
벡터가 한번 정해지고 나면 벡터 안에 들어있는 엘리먼트들을 읽어올 수는 있고 각각을 따로 변화시킬 수 있음 2차원보다 더 큰 차원들이 존재할 수 있음 BUT 순서가 있는 숫자들의 모임
1
2
3
class Vector:
def __init__(self,lst):
self._vec = list(lst)
tuple이 오든 set이 오든 모두 list로 저장하기로 함
append()는 가능해야할까? 놉!
벡터의 차원이 한번 정해지면 차원이 변할 수는 없음
Vector method
1
2
3
4
5
6
7
8
class Vector:
def __add__(self,other):
...
def __sub__(self,other):
...
>>> x = Vector([1,2,3])
>>> x.append()
Error: ...
list를 이용하여 구현(list type)된 class이지만 벡터의 어디에도 append라는 메소드가 정의되어 있지 않기때문에 append()되지 않음 list가 아닌 vector로써 사용하는거다아악 list로 구현되어 있지 않은 add와 sub을 vector에 구현되어 있으면 add와 sub할 수 있고 list로 구현되어 있는 append를 vector에 구현하지 않으면 append할 수 없음
vector의 곱하기는
inner product(내적) -> 벡터연산에 많이 사용됨
outer product(외적) -> 3차원
Point와 Vector의 유사성
Point의 차원 = Vector의 차원과 동일 Point의 이동 = Vector의 덧셈으로 계산 가능 Point간의 거리 = Vector의 뺄셈 및 크기로 계산 …
1
2
3
4
5
6
7
8
9
10
4차원 공간상의 두점 a(a1,a2,a3,a4)와 b(b1,b2,b3,b4)
거리 = sqrt( (a1-b1)제곱 + (a2-b2)제곱 + (a3-b3)제곱 + (a4-b4)제곱 )
점이아니라 Vector로 보자
두 Vector v1(a1,a2,a3,a4)과 v2(b1,b2,b3,b4)의 차이는
v1 - v2 = (a1-b1, a2-b2, a3-b3, a4-b4)
이 것의 사이즈는?
sqrt( (a1-b1)제곱 + (a2-b2)제곱 + (a3-b3)제곱 + (a4-b4)제곱 )
두 점 사이의 거리 = 두 벡터의 차의 크기
–> Point는 일종의 특별한 Vector로 볼 수 있다! —-> Inheritance : 이미 구현된 클래스의 기능을 기반으로 특별한 성질을 더하는것
Point의 차원을 늘리려면 x,y,z,w… 자꾸 늘어나고 제일 처음에 나오는게 x라고 가정하고 짜놨는데 4차원으로 늘어나는 순간 w가 먼저 나와야 하니까 순서도 막 바뀜
Vector에서 구현되어 있는 것들을 가져다가 사용하는게 Point를 구현할때 깔끔하겠다는 생각이 듦?
얍얍
Inheritance
1
2
3
4
5
6
7
8
9
class Vector:
def __init__(self,lst):
...
class Point (Vector):
def __init__(self,x,y):
super().__init__([x,y])
def distance(self,other):
v = self - other
return v.size()
Point는 inherited class
Vector는 super class
Point inherits Vector attribues
Specialising inherited class
1
2
3
>>> p1 = Point(0,1)
>>> print(p1)
Vector([0, 1])
ㅇㅅㅇ..? point줬는데염! –> We should specialize __str__() and __repr__()
1
2
3
4
5
6
7
8
9
10
class Point(Vector):
def __init__(self,x,y):
super().__init__([x,y])
def __repr__(self):
return "Point({},{})".format(self.x(),self.y())
def __str__(self):
return self.__repr__()
>>> p1 = Point(0,1)
>>> print(p1)
Point(0,1)
뜐 됐당
하지만 또 남은게 있다
1
2
>>> p1 = Point(0,1)
>>> p1[0] = 10
Point(x,y)의 x만 set하거나 y만 set할 수는 없어야함
1
2
3
4
5
6
7
8
class Point(Vector):
def __setitem__(self,key,val):
print("Error: Point cannot assign new item")
>>> v1 = Vector([0,1])
>>> v1[0] = 10
>>> p1 = Point(0,1)
>>> p1[0] = 10
Point does not support __setitem__
뀨 now Point is a specialised Vector
그렇다면 이제 전체적으로 보쟈 원래의 Point는
1
2
3
4
5
6
7
8
9
10
11
12
13
import math
class Point2():
def __init__(self,x,y):
self._x = x
self._y = y
def x(self):
return self.x
def y(self):
return self.y
def distance(self,other):
dx = self.x() - other.x()
dy = self.y() - other.y()
return math.sqrt(dx**2 + dy**2)
하나하나 다 새로 만들어야 했지만
Vector 를 상속받은 Point는
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import math
class Vector:
def __init__(self,lst):
self._vec = list(lst)
def __repr__(self):
return "Vector({})".format(self._vec)
def __getitem__(self,key):
return self._vec[key]
def __setitem__(self,key,val):
self._vec[key] = val
def __add__(self,other):
return Vector([self[i] + other[i] for i in range(len(self._vec))])
def __sub__(self,other):
return Vector([self[i] + other[i] for i in range(len(self._vec))])
def size(self):
return math.sqrt(sum([self[i]**2 for i in self._vec]))
class Point (Vector): #Vector를 inherit
def __init__(self,x,y):
super().__init__([x,y]) #super class(vector)의 init
def __repr__(self):
return "Point({},{})".format(self[0],self[1])
def distance(self,other):
d = self - other
return d.size()
def x(self):
return self[0]
def y(self):
return self[1]
def __setitem__(self,key,val): #Point는 각값을 따로 바꾸지 않도록함
print("Error!")
1
2
3
v = Vector([1,2])
v[0] = 10
print(v)
Vector([10, 2])
1
2
3
p1 = Point(1,0)
p2 = Point(0,1)
print(p1.distance(p2))
1.4142135623730951
1
2
p1[0] = 10 #여기서 (1)Error출력하고 (2)더 이상 실행하지 않도록 할 예정 -> 아직 (1)까지만 함
print(p1)
Error! Point(1,0)