누운 상태에서 나의 양 다리로 상대의 한쪽 다리를 얽어매어 방어하는 형태의 가드다. 하프 가드는 Top포지션(위에서 공격해 들어오는 사람)이나 Bottom포지션(아래에서 방어하는 사람)중 누가 절대적으로 유리하다 할 수 없어서 더욱 재미있는 가드 중에 하나라고 한다. 그리고 그만큼 기술 종류도 많다고 한다. 여기저기 찾아보니 오래한 사람일수록 하프 가드를 선호 한다는 이야기도 있다.
요즘 나도 하프가드를 많이 쓴다. 씁쓸한건 나의 경우 재미 보단 내 오픈가드가 워낙 취약해서 그렇다. 내 오픈가드가 워낙 잘 뚫리다보니 눈치껏 오픈가드가 뚫릴거 같으면 재빨리 하프가드로 전환 한다. 나도 좀 남들처럼 멋지게 오픈가드 스윕 해보고 싶은데……
하프가드 기본
하프가드 기본 강좌
하프가드 주의사항
하프가드 스윕
하프가드 스윕 1번 : 언더 훅으로 백 포지션 잡기, 가장 처음 배운거, 옥토퍼스 가드로 전환이 가능한데 그건 나중에…..
하프가드 스윕 2, Shaolin Sweep이라는데 이름은 확실치 않음, 하프가드 시저라고 하는 부분도 있는데?, 요즘 내가 자주 써먹는 스윕
어쩌다 python-django 로 웹 어플리케이션 하나를 만들게 되었는데 이거 은근 신세계다. django 같은 프레임워크야 뭐 많으니까 놀랄게 없더라도 python의 decorator는 나에게 뭔가 신세계를 보여줬다. java-spring에서 그렇게 복잡했던 AOP가 decorator를 쓰면 그냥 별 고민 없이 끝나버린다. 이걸 AOP라고 해도 될런지 모르겠지만 말이다. 여튼 decorator에 감탄한 나머지 까먹기 전에 decorator 파트만 정리해본다.
그런데 데코레이션을 붙이는 순강 망한다. __doc__이 안나온다. 실제로 django api application을 만들면서 api endpoint 메소드들을 decorator로 신나게 감쌌더니 Sweager UI에서 doc 처리하지 못해 공백 API 가이드만 한가득 나왔다.
생각해보면 당연한 일이다. 실행시간에 실제로 접근하는 메타데이터는 func가 아니라 데코레이터가 만들어준 wrapper의 메터데이터니 제대로 나올리가 없다. 그렇다. 우린 망했다.
그렇다고 진짜 망한건 아니다. decorator에 @wraps 달아주면 모든것이 해결된다. 모든 decorator에는 반드시 @wraps를 달아주자. 그것이 모두가 행복해지는 길이다. 이유는 찾아보기 귀찮아서 생략. (대충 소스 보니 func의 __doc__ 같은 meta 정보를 wrapper에 복사해 넣는거 같은데 확실한건 아님!)
x와 y를 더합니다.
:param x:
:param y:
:return:
func before
3
func after
x와 y를 더합니다.
:param x:
:param y:
:return:
hello, decorator!
func2 before
3
func2 after
class로도 decorator 선언이 가능하다고도 합니다.
class로 만드는게 뭔가 낙타표기도 되고 그래서 뭔가 그 뭔가 멋져보이는거 같은데 여기엔 치명적인 단점이 있다. @wraps를 붙일수가 없다. 그나마 parameter를 가지는 데코레이터의 경우 __call__ 시점에서 wrapper를 만들면서 @wraps를 붙여줄수 있는데 parameter가 없는 데코레이터의 경우 wraps를 붙일 방법이 보이질 않는다. 이거 저거 찾아보니 결국 __doc__, __name__들을 복사해 넣는데 이럴거면 그냥 function으로 데코레이터 만들란다.
from functools import wraps
# 그냥 Class 데코레이터, @wraps를 붙일만한데가 보이지 않는다.
class Decorator:
def __init__ (self, func):
self.func = func
def __call__ (self, *args, **kwargs):
print("%s %s" % (self.func.__name__, "before"))
result = self.func(*args, **kwargs)
print("%s %s" % (self.func.__name__, "after"))
return result
# 파레매터를 가지는 Class 데코레이터, __call__에서 @wraps를 넣어준다.
class DecoratorWithParam:
def __init__ (self, param):
self.param = param
def __call__ (self, func):
@wraps(func)
def decorator(*args, **kwargs):
print(self.param)
print("%s %s" % (func.__name__, "before"))
result = func(*args, **kwargs)
print("%s %s" % (func.__name__, "after"))
return decorator
@Decorator
def func(x, y):
"""
x와 y를 더합니다.
:param x:
:param y:
:return:
"""
print(x + y)
return x + y
@DecoratorWithParam("hello, decorator!")
def func2(x, y):
"""
x와 y를 더합니다.
:param x:
:param y:
:return:
"""
print(x + y)
return x + y
print(func.__doc__)
func(1,2)
print(func2.__doc__)
func2(1,2)
---- 출력 ----
None # 아, 이거 짜증나네
func before
3
func after
x와 y를 더합니다.
:param x:
:param y:
:return:
hello, decorator!
func2 before
3
func2 after
요즘 사이드 마운트만 당했다 하면 빠져나오지 못하고 너무 허부적 댄다. 원래 빠져나오기 어려운 자세라고 하지만 연습도 지식도 많이 부족한거 같다. 다음 운동떄는 사이드 마운트 내어 주고 스파링을 시작해볼까 한다.
제일 처음 배운 기본적인 탈출법
상대와 내 몸 사이 틈을 만들고 엉덩이 빼기로 틈을 더욱 크게 벌린다. 그리고 재빨리 무릎을 상대 허리 깊숙이 밀어넣어 가드 자세를 취한다. 나의 경우는 무릎 넣는 타이밍에 문제가 있는지 허리를 빼앗기 전에 다시 사이드 마운트로 원상 복귀가 되어버린다. 초반 빈공간 만들때 체력 소모가 좀 큰게 단점인거 같다.
– 공간 만들기 위해 몸을 좌우 브릿주 해주는게 포인트인 영상
– 빈틈을 만들기 위해 브릿지를 강조해주는 영상
– 기본 외에 몇가지 응용이 있는 영상
힙롤 이라고 하는거 같던데 1번보다 체력소모도 작고 효과도 확실한거 같다. 다만 삑사리 나면 백을 잡혀버리는 리스크가 있다. 몇번 시도했는데 아직 성공한적은 없다.
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
public class Solution {
public int lengthOfLongestSubstring(String s) {
boolean[] cache = new boolean[255];
int count = 0;
int maxCount = 0;
int head = 0, tail = 0;
while(head < s.length()){
if(cache[s.charAt(head)] != true){
cache[s.charAt(head)] = true;
maxCount = Math.max(head-tail+1, maxCount);
head++;
}
else{
cache[s.charAt(tail)] = false;
tail++;
}
}
return maxCount;
}
}
// you can also use imports, for example:
// import java.util.*;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int[] solution(int N, int[] A) {
int maxCounter = N+1;
int counters[] = new int[N];
for(int i = 0 ; i < counters.length ; i++){
counters[i] = 0;
}
int nextMax = 0;
int curMax = 0;
for(int i = 0 ; i < A.length ; i++){
int counterNumber = A[i];
int counterIndex = counterNumber - 1;
if(counterNumber < maxCounter){
if(counters[counterIndex] <= curMax){
counters[counterIndex] = curMax;
}
counters[counterIndex]++;
nextMax = Math.max(nextMax, counters[counterIndex]);
}
else{
curMax = nextMax;
}
}
for(int i = 0 ; i < counters.length ; i++){
if(counters[i] < curMax){
counters[i] = curMax;
}
}
return counters;
}
}