if(command != null && command.equals("calculate")) { //최초 요청 시 command가 null이면 계산기 화면을 출력하고, command값이 calculate이면 계산 결과를 출력합니다.
String result = calculate(Float.parseFloat(won), operator); pw.print("변환결과"); pw.print(""+ result + ""); pw.print("환율 계산기"); return; } pw.print(""); pw.print("환율 계산기"); pw.print("
"); pw.print(""); pw.close(); } // 원화를 선택한 외화로 환산합니다. private static String calculate(float won, String operator) { String result = null; if(operator.equals("dollar")) { result = String.format("%.6f", won / USD_RATE); }else if (operator.equals("en")) { result = String.format("%.6f", won / JPY_RATE); }else if (operator.equals("wian")) { result = String.format("%.6f", won / CNY_RATE); }else if (operator.equals("pound")) { result = String.format("%.6f", won / GBP_RATE); }else if (operator.equals("euro")) { result = String.format("%.6f", won / EUR_RATE); } return result; } }
#정규 표현식 # 단순 문자열 매칭이 아니라 문자열의 패턴으로 검색하는 것 import re
# 사용시 : 패턴 컴파일 -> 패턴 객체의 메서드로 검색 수행 p = re.compile(r"P[a-z]+") #[] 패턴 1글자 + 1글자 이상 #대문자 P로 시작하고 소문자(a-z) 1글자 이상 있는 문자열 print(p.match("Life"))# 현재 패턴이 life와 일치하는지? print("p match Python?", p.match("Python")) print("p match Pizza?", p.match("Pizza"))
source = "Life is too short, you need Python" # 방법 1. 패턴 컴파일 후 검색 수행 p = re.compile(r"L[a-z]+") print(p.match("Life"))
# 방법 2. 축약형, 패턴 문자열과 검색 대상 문자열을 함께 제공 print(re.match(r"[A-Z][a-z]+", source)) # 매치된 내용을 추출할 경우 group() 메서드로 뽑을 수 있다 print("Match 된 내용:", re.match(r"[A-Z][a-z]+", source).group())
#축약 문자 # \d(숫자), \w(문자), \s (공백문자) # \D(숫자가 아닌 것), \W(문자가 아닌 것), \S(공백문자 아닌것) # search -> 전체 문자열 대상 패턴 검색 #findall -> 전체 문자열 대상 검색 후 list로 반환 # finditer -> 검색 후 iterator(반복자)를 반환 source = "Paint C JavaScript 123 456 Perl Java Python P123 Ruby" #p로 시작되는 문자열 패턴만 검색해서 iterator을 반환 iter = re.finditer(r"\bp\w+", source, re.IGNORECASE) #re.IGNORECASE는 대소문자를 구분하지 말고 검색하라는 의미다 for x in iter: print("검색된 단어:", x)
# 자주 사용될 수 있는 패턴들 # 전화번호의 예 tel = re.compile(r"(\d{2,3})-(\d{3,4})-(\d{4})") m = tel.match("010-1234-5678") print("result:", m) # () 로 묶은 것은 groups() 메서드로 추출 print("groups:", m.groups()) #groups #매칭된 전체 내용을 추출: group() print("매칭된 내용:", m.group()) #group tel= re.compile(r"(?P<area>\d{2,3})-(?P<exchange>\d{3,4})-(?P<number>\d{4})") # 그룹핑시 (?P<이름>) 형식을 부여하면 매칭 결과에 이름을 부여할 수 있다 # 이름이 부여된 매칭 결과는 groupdict()메서드로 사전으로 반환받을 수 있다. m = tel.match("010-1234-5678") print(m.groups()) # 그룹핑된 결과 확인 print(m.group()) #매칭된 전체 결과 print(m.groupdict()) #부여한 이름을 기반으로 한 dict 객체 반환 # 이메일 pattern = r"\w+[\w\.]*@[\w\.]*\.[a-z]+" source = "skyun.nam@gmail.com" print(re.match(pattern, source))
# 한글 매칭 (Unicode 기반) # 한국어 정규식의 예제 source = "English 대한민국 Japan China" p = re.compile(r"[가-힣]+") print(p.findall(source))
# class """ -새로운 이름 공간을 지원하는 단위: 데이터의 설계도 - 새로운 클래스는 새로운 자료형을 정의하는 것 - 인스턴스는 이 자료형의 객체를 생성하는 것 - 클래스와 인스턴스는 직접적인 영향을 갖는다 -인스턴스에서 클래스 멤ㅂ와 접근은 자능 -클래스 맴버에서 인스턴스 멤버의 접근은 불가 """ class MyString(str): # str은 상속받은 새로운 클래스 pass #특정 클래스를 상속받지 않을 경우, object 상속 s = MyString() # 생성자 호출 print(type(s))
# 어떤 클래스를 상속 받은 클래스잉ㄴ가? # __bases__ -> 부모의 목록을 튜플로 반환 print("MyString의 부모:", MyString.__bases__)
#특정 부모를 상속받지 않을 경우() 없어도 된다 class myobj: #object를 상속 pass print(myobj.__bases__) #파이썬은 여러 부모로부터의 상속을 허용한다 #파이썬은 여러 부모로부터의 상속을 허용한다 class Complex(str, myobj): # str로부터 모든 맴버들 #myobj로부터 모든 멤버들을 물려받는다 pass print("Complex의 부모:", Complex.__bases__)
#특정 클래스가 다른 클래스의 자식인지 확인 # issubclass 함수 print("Complex가 str의 자식인가?", issubclass(Complex,str))
#클래스의 생성 # 인스턴스를 위한 멤버는 항상 self를 붙여준다 class Point: # 클래스 멤버: # 클래스 이름 공간 내에 생성 # 모든 인스턴스 맴버 공유 # 클래스 맴버는 인스턴스 생성 없이도 사용할 수 있다. instance_count = 0 def __init__(self, x = 0, y = 0): # 생성자 #파이썬은 여러 개의 생성자를 만들 수 없으므로 # 범용적으로 사용될 수 있는 유일한 생성자를 작성 self.x = x self.y = y Point.instance_count +=1 #소멸자 def __del__(self): #객체가 제거될 때 호출 Point.instance_count -= 1 #__str__ def __str__(self):#문자열 출력 #str() 호출 혹은 print를 할 때 사용되는 비공식 문자열(일반 사용자 대상) return "Point x={}, y={}".format(self.x, self.y) #__repr__ def __repr__(self): #문자열 출력 # 개발자용, 공식문자열 # repr() 함수로 전달 받을 수 있다. # 이 문자열로 해당 객체를 복원해 낼 수 있어야 한다. return "Point({},{})".format(self.x,self.y)
def setX(self,x): self.x = x def setY(self, y): self.y = y def getX(self): return self.x def getY(self): return self.y
#연산자 오버로딩 # 새로운 데이터 타입에 필요한 연산자의 행동을 재정의하는 것 # 산술 연산자 오버로딩 예제 def __add__(self, other): # Point(self) + other # other 타입을 점검해서 각기 다른 행독을 취하도록 if isinstance(other, Point): #합산된 객체가 Point self.x += other.x self.y += other.y elif isinstance(other, int): self.x += other self.y += other else: self += other
return self #역이항 연산자 : other + Point def __radd__(self,other): if isinstance(other, str): return other + str(self) elif isinstance(other, int): self.x += other self.y += other else: self + other return self def bound_class_method(): #생성된 인스턴스를 통해 직접 메서드에 접근하는 방법 p = Point() # bound 방식의 경우, 첫 번째 인자 self는 전달하지 않아도 된다. p.setX(10) p.setY(20)
# 클래스 멤버는 모든 인스턴스에서 접근 가능 # 생성 없이도 직접 접근 가능 print("p1의 instance_count의 주소:", id(p1.instance_count)) print("p2의 instance_count의 주소:", id(p2.instance_count))
#클래스 멤버의 변경 # 공유 메모리 영역으로 활용할 수 있다 Point.instance_count += 1 p1.instance_count += 1 p2.instance_count += 1 print("p2의 instance_count:", p2.instance_count) print("p1의 instance_count:", p1.instance_count)
#class_member() def lifecycle(): # 생성자와 소멸자 테스트 p1 = Point() # 생성자의 기본값이 사용 print(p1) print("instance_count:", Point.instance_count)
del p2 print("instance_count:", Point.instance_count)
#lifecycle() def str_repr(): p = Point(10,20) print(p) # __str__ 호출 print("포인트 p=" + str(p)) # __str__ #repr 함수를 사용하면 __repr__ 문자열을 얻을 수 있다. print("repr of p:", repr(p))
#eval 함수를 사용하면 파이썬 코드를 테스트 할 수 있다. #이때 repr로 전달 받은 문자열(개발자용)을 넘겨주면 같은 객체가 복원되어야 한다. p_repr = eval(repr(p)) print(p_repr, type(p_repr))