파이썬의 함정 - 2  

@classmethod 와  @staticmethod 의 차이

자바나  C++  베이스에서 파이썬으로 옮겨 왔을때 가장 실수하기 쉬운 부분에 대해서 살펴보겠습니다.
특히나 클래스 메소드와 정적 메소드는 가장 이질적인
 부분 중 하나인데요
전문가를 위한 파이썬을 지은 파이썬구루인 루시아누 하말류는 이렇게 말합니다.

@classmethod 는 쓰임새가 많은 게 확실하지만, @staticmethod 는 사용해야하는 이유를 잘 모르겠다.
클래스와 함께 작동하지 않는 함수를 정의하려면, 단지 함수를 모듈에 정의하면 된다. 아마 함수가 클래스를 건드리지는 않지만, 그 클래스와 밀접히 연관되어 있어서 클래스 코드 가까운 곳에 두고 싶을 수는 있을 것이다. 그런 경우에는 클래스의 바로 앞이나 뒤에서 함수를 정의하면 된다. 

루시아누 하말류의 이 말에 대해 주변에서 동의하지 않는 사람중 레오나르도 로챌은 '파이썬에서 정적,클래스,추상메서드를 사용하는 최종 가이드'를 읽어보라고 권했지만 하말류는 그래도 역시 납득하지 못했다는 썰이 있습니다.

이제 이것들이 무엇인지 살펴보고 각자 판단해 보시길 바랍니다. (저는 하말류에 동감합니다)

@staticmethod

먼저 @staticmethod 를 살펴보시죠.  (우리가 알고 있는 그 정적메소드라고 생각하면 됩니다) 

class Test :
    num = 0

    @staticmethod
    def add (x, y) :
        return x + y


print Test.add(1,1)

이건 우리가 평소 알고 있던 정적 메소드와 비슷합니다.
클래스에서 직접 접근하며, 객체별로 달라지는 것이 아니라 함께 공유하는 것이죠.
주로 유틸리티성 클래스 만들때 사용하기도 합니다.

여기까지는 매우 마음이 편한데.. 다음을 보세요.

class Test :
    num = 0

    @staticmethod
    def add (x, y) :
        return x + y


t = Test()
print t.add(1,1)

파이썬은 이렇게 객체를 통해서 정적함수를 호출하는데 아무 이상이 없습니다. (@classmethod 도 마찬가지) 

C++ 이나 자바에서는 에러죠. 즉 객체를 위한 메소드와 정적메소드의 스코프가 완전히 다릅니다만.. 
위에 제 실수 입니다. C# 은 에러 , Java , C++은 warning 정도지, 언어스펙으로 안되지는 않군요. ;;
아마 고슬링도 잘못된 것 을 알 겁니다. 다만 하위호환성 때문에 고치질 못하고 있는 것 일뿐..
허용하면 정적메소드,일반메소드 리팩토링이 원할하다 등등 각종 이유도 있긴 한데  개인적으로 꽝입니다.
그냥 막는게 최선이라 봅니다.

파이썬은 그렇지 않습니다.  막나갑니다. @@  


class TestTestTestTest :
num = 10

@staticmethod
def add (x, y) :
return x + y + self.num # TestTestTestTest.num 이면 가능


t = TestTestTestTest()
print t.add(1,1)

마지막으로 정적함수이기때문에 당연히 self 를 통한 접근은 불가능합니다. 저 코드는 에러입니다.!

@classmethod

이제 @classmethod 를 살펴보시죠.  이것도 staticmethod와 거의 동일합니다만.. 한가지 차이가 있습니다.


class Test :
    num = 10

    @classmethod
    def add (x, y) :
        return x + y


print Test.add(1,1)

이렇게 하면 에러입니다. -.-;;;  눈을 크게 뜨고 봐도 모르겠지요? 

 

class Test :
    num = 10

    @classmethod
    def add (cls, x, y) :
        return x + y


print Test.add(1,1)

파이썬은 ~~이렇게 add 함수의 첫번째 인자로 cls 를 줘야합니다. (cls 말고 다른 말로 넣어도 됩니다) 
클래스 메소드는 클래스 자체를 첫번째 인자로 넣어줘야합니다. 즉 클래스 자체를 객체처럼 봄. 

(파이썬은 객체함수를 나타낼때 무조건 def (self, x, y) 이렇게 self 를 첫번째 인자로 넣어야하는데요.
즉 자바나 C++ 에서 this 를 명시 안해도 되나, 파이썬은 강제합니다.)

그럼 이런게 왜 필요한걸까요? 필요할때가 있습니다.

(@classmethod 로 하면 cls 로 접근하는 편리성은 있습니다. 클래스명이 길다면 @staticmethod 경우 클래스를 다 적어줘야 하지만요. 뭐 이건 그냥 매우 부차적인 겁니다) 

다음 예를 보시죠

# coding: utf-8
class Date :

word = 'date : '

def __init__(self, date):
self.date = self.word + date

@staticmethod
def now():
return Date("today")


def show(self):
print self.date


a = Date("2016, 9, 13")
a.show()
b = Date.now()
b.show()

@staticmethod 를 이용해서 Factory 메소드 2개를 만들었습니다.

아래처럼 지정일/오늘로 초기화한 객체를 돌려주고 있네요.

date : 2016, 9, 13
date : today

근데 이렇게 상속받아서 하면 어떻게 될까요?

class KoreanDate(Date):
word = '날짜 : '


a = KoreanDate.now()
a.show() 결과) daate : today

date : today 이렇게 나옵니다.  now() 를 통해 KoreanDate 객체가 생성되는게 아니라 Date 객체가 생성되네요.

이때 @classmethod 의 힘이 나옵니다.

# coding: utf-8
class Date :

word = 'date : '

def __init__(self, date):
self.date = self.word + date

@classmethod
def now(cls):
return cls("today")

def show(self):
print self.date



class KoreanDate(Date):
word = '날짜 : '


a = KoreanDate.now()
a.show() 결과) 날짜 : today

위처럼 now 를 @classmethod 로 바꾸어서 cls 를 전달해서 그것으로 객체를 생성하면 
Date 객체 대신해서 KoreaDate 객체를 돌려 받게 됩니다. 

날짜 : today   # 이제 제대로 나오네요.

자 이제 이해 했으니 처음에 루시아누 하말류가 왜 "staticmethod 를 사용해야하는지 모르겠다" 를 각자 생각해보세요. 클래스라는 네임스페이스로 묶고 싶은 정적 메소드는 모두 @classmethod  를 이용해서 사용하면 될 거 같습니다만 상속에서 사용되어 혼동을 초래할 여지가 없거나 조금이라도 더 간략하게 표현하고 싶을 경우 @staticmethod 를 사용하는게 더 편해 보이구요.

자바 같은 경우는 클래스와 분리 될 수 가 없지만 파이썬 경우는 애초에 모듈에 유틸리티 함수들 만 따로 모으는게 자연스러운 일이니 어떻게 보면 굳이 필요 없어 보이기도 합니다. 따라서 논쟁의 여지가 없어 보이네요. (다중상속이 필요하냐? 필요 없냐? 혹은 체크예외가 필요하냐 필요없냐 같은 차원높은 논의가 발생할 여지가 없는 단순한 사항) 

부록 : java 에서 static method on instance

class Base
{
    static void foo()
    {
        System.out.println("Base.foo()");
    }
}

class Derived extends Base
{
    static void foo()
    {
        System.out.println("Derived.foo()");
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Base b = new Derived();
        b.foo(); // Prints "Base.foo()"
        b = null;
        b.foo(); // Still prints "Base.foo()"
    }
}

http://stackoverflow.com/questions/610458/why-isnt-calling-a-static-method-by-way-of-an-instance-an-error-for-the-java-co

파이썬의 함정 - 1  (부제: 나의 삽질기)


클래스 변수와 객체 변수에  대한 함정


자바나  C++  베이스에서 파이썬으로 옮겨 왔을때 가장 실수하기 쉬운 부분에 대해서 살펴보겠습니다.

먼저 아래 코드를 보시죠.

class Test :

num =
0

def show(self):
print 'num :' + str(num)

t =
Test()
t.show()

어떻게 될까요? 

에러입니다.

어디서?

print 'num :' +  str(num)

네 여기에서 num 를 못찾아서 에러가 납니다.  클래스 변수 num 을  찾지 못하네요.

이걸 해결하려면 

print 'num :' + str(self.num)

이렇게 self 를 붙여 주어야 하는데요.

self 는 JAVA나 C++에서 this 와 같으며  현재 객체를 말합니다. 

print 'num :' + str(Test.num)

이렇게 클래스 변수로 나타낼 수도 있습니다.

그럼 아래는 어떻게 될까요? 

class Test :

num = 0

def show(self):
print 'num :' + str(self.num)


t = Test()
Test.num = 10
t.show()

Test.num = 10 이렇게 클래스 변수에 직접 접근하여 10을 대입해 주었습니다. 클래스 공통 10 인거죠
self.num 은 객체 스스로라고 했으니깐 0 일꺼 같지만

결과는 "num  :10"  이렇게 됩니다.  아직 클래스변수와 객체변수로 나누어지지 않았네요.

그럼 아래는 어떻게 될까요?

class Test :

num = 100

def __init__(self):
self.num = 0
def show(self):
print 'num :' + str(self.num)


t = Test()
Test.num = 10
t.show()

__init__ 라는 생성자를 이용하여  self.num 을 초기화 하였습니다. 이때 결과는 "num  :0"  이렇게 됩니다. 
즉 __init__ 생성자에서 초기화를 해 줘서 객체별 변수로 바뀝니다.

그럼 아래는 어떨까요?

class Test:
num = 100

def show(self):
print 'num :' + str(self.num)

def inc(self):
self.num = self.num + 1


t1 = Test()
t2 = Test()

t1.inc()
t2.inc()
t1.show()
t2.show()

객체를 2개 만들었습니다. 그리고 각각 inc()  함수를 호출하여 1씩 증가 시켰는데요.
show()  호출하면 둘다 101 을 나타냅니다. 

__init__ 생성자에서 초기화 하지도 않았는데  self.num 에 값을 대입하면서  객체변수가 된거 같습니다.

(기존의 클래스 변수의 값을 가지고 객체변수로 초기화) 


마지막으로 하나 보시죠. 이게 히트입니다. (동시에 아주 큰 실수입니다.  본문 끝까지 읽으셔야해요. 제발~)

class Test:
num =
0
ar = []

def show(self):
print 'num :' + str(self.num)
print 'list :' + str(self.ar)

def inc(self, n):
self.num = self.num + n

def inc_list(self, n):
self.ar.append(n)


t1 = Test()
t2 = Test()

t1.inc(2)
t2.inc(3)

t1.inc_list(
1)
t2.inc_list(
5)

t1.show()
t2.show()

이거 show() 하면 t1 객체의 num 는 2 ,  t2 객체의 num 는 3이 됩니다.  즉 값이 객체별로 분리되지만
리스트의 경우는 분리되지 않네요..

num :2

list :[1, 5]

num :3

list :[1, 5]

이렇게 나옵니다.

즉 리스트의 경우는 self 를 해도 두개의 객체가 리스트 ar 을  공유하게 됩니다.
자바와  C++ 에서는 상상도 못할..

이 경우는 
Test  클래스에 __init__(self) 를 추가하여 여기에서 초기화 해야 객체별로 리스트(ar)가 생성되는 건 가 싶어.. 
class Test:
num = 0
ar = []

def __init__(self):
self.ar = []

def show(self):
print 'num :' + str(self.num)
print 'list :' + str(self.ar)

def inc(self):
self.num = self.num + 1

def inc_list(self, n):
self.ar.append(n)


t1 = Test()
t2 = Test()

t1.inc()
t2.inc()

t1.inc_list(1)
t2.inc_list(5)

t1.show()
t2.show()

해보니 잘 됩니다. 

__init__ 에서 초기화 해주어야 객체 별 변수가 된다면 모두 그게 적용되야 하는데 

파이썬에서는 일반타입하고 배열타입하고 다르게 작동하는거 같습니다.
즉 일반타입은 자동으로 __init__ 초기화가 이루어지는 모냥.. ??   땡~~
여기까지 저의 착각이었습니다.  아래  읽으세요.


앗 큰 실수!! 

위에 작동방식이 너무 상식밖이라.. 파이썬 창조자 머리에 꽃 맞은것도 아니고 

굳이 저렇게 헤깔리게 할까 싶어서 다시 살펴본결과

 def inc(self):
self.num = self.num + 1

def inc_list(self, n):
self.ar.append(n)

이거 두개 사이에 차이가 있음을 발견 

위에 num 은 초기화 해주고 있으나, ar 는 초기화가 아니네요. 
self.ar.append(1) 이것을 sefl.num = 1 같은 초기화라고 착각한것 입니다. 
self.ar = [] 이렇게 초기화를 해줘야 했었는데 말이죠.


즉 __init__ 뿐 아니라 다른 어느 곳 에서 든지 ar 도 초기화를 한다면 동일하게 객체변수화 합니다. 

예를들어 아래 처럼 아무데서나  초기화 해주면 됩니다.

 def listInit(self):
self.ar = []

아래처럼 외부에서 초기화 해줘도 되구요.


t1.ar = []
t2.ar = []



결론 

애초에 공유목적 ( 즉 정적변수 ) 로 작동할때만 class 아래에 클래스 변수로 놓고 , 객체별로 사용될 변수들은 클래스 변수 자리가 아니라 __init__ 에 넣는게 파이썬 스타일/이디엄 인듯.  이렇게 되면 저런 실수는 하지 않게 되겠지요.  그래도 실수를 통해 하나 진득히 배우게 된거 같습니다. ^^

파이썬 최고 성능을 위한 프로젝트들 


흠 표준 파이썬은 아무래도 조금 느립니다, 그래서 성능을 최대로 올리기위한 여러 방법이 있긴 합니다..
고성능 파이썬이란 책도 사놓고 조금 읽긴했는데 파이썬 쓰면서 성능때문에 신경 쓸 빠에는..생각해보면
그럴바엔 그냥 C++ 쓸거 같긴하네요. 그냥 표준 파이썬 (CPython) + Async + 병렬,분산으로 최대한 쇼부봐야..

원문은 아래 링크에 있습니다.  번역 예정..

http://www.infoworld.com/article/2880767/python/5-projects-push-python-performance.html




PyPy

Among the candidates for a drop-in replacement for CPython, PyPy is easily the most visible (Quora, for instance, uses it in production). It also stands the best chance of becoming the default, as it's highly compatible with existing Python code.

PyPy uses just-in-time (JIT) compilation, the same technique used by Google Chrome's V8 JavaScript engine to speed up that language. The most recent release, PyPy 2.5, emerged at the beginning of February with a slew of performance improvements, among them better-integrated support for some common libraries used to accelerate Python performance such as NumPy.

Those using Python 3.x have to work with a separate build of the project, PyPy3. Unfortunately for lovers of bleeding-edge language features, that version supports up to Python 3.2.5 only, although support for 3.3 is in the works.


Pyston

Pyston, sponsored by Dropbox, uses the LLVM compiler infrastructure to also speed up Python with JITing. Compared to PyPy, Pyston is in the very early stages -- it's at revision 0.2 so far and supports only a limited subset of the language's features. Much of the work has been divided between supporting core features of the language and bringing up performance of key benchmarks to an acceptable level. It'll be a while before Pyston can be considered remotely production-ready.


Nuitka

Rather than replace the Python runtime, some teams are doing away with a Python runtime entirely and seeking ways to transpile Python code to languages that run natively at high speed. Case in point: Nuitka, which converts Python to C++ code -- although it relies on executables from the existing Python runtimes to work its magic. That limits its portability, but there's no denying the value of the velocity gained from this conversion. Long-term plans for Nuitka include allowing Nuitka-compiled Python to interface directly with C code, allowing for even greater speed.


Cython

Cython (C extensions for Python) is a superset of Python, a version of the language that compiles to C and interfaces with C/C++ code. It's one way to write C extensions for Python (where code that needs to run fast can be implemented), but can also be used on its own, separate from conventional Python code. The downside is that you're not really writing Python, so porting existing code wouldn't be totally automatic.

That said, Cython provides several advantages for the sake of speed not available in vanilla Python, among them variable typing à la C itself. A number of scientific packages for Python, such as scikit-learn, draw on Cython features like this to keep operations lean and fast.


Numba

Numba combines two of the previous approaches. From Cython, it takes the concept of speeding up the parts of the language that most need it (typically CPU-bound math); like PyPy and Pyston, it does so via LLVM. Functions compiled with Numba can be specified with a decorator, and Numba works hand-in-hand with NumPy to quicken the functions found. However, Numba doesn't perform JITing; the code is compiled ahead of time.

Python creator Guido van Rossum is adamant that many of Python's performance issues can be traced to improper use of the language. CPU-heavy processing, for instance, can be hastened through a few methods touched on here -- using NumPy (for math), using the multiprocessing extensions, or making calls to external C code and thus avoiding the Global Interpreter Lock (GIL), the root of Python's slowness. But since there's no viable replacement yet for the GIL in Python, it falls to others to come up with short-term solutions -- and maybe long-term ones, too.








우분투 설치는 여기 참고 => http://freeprog.tistory.com/63

아래는 윈도우에서 설치 


2016년 2월 싸이트 링크 기준 

Python 설치 (python-2.7.6.msi) 


NumPy 설치 (numpy-1.7.1-win32-superpack-python2.7.exe)


Matplotlib 설치 (matplotlib-1.3.1.win32-py2.7.exe)

SciPy 설치  (scipy-0.16.1-win32-superpack-python2.7. exe) 


추가항목


- Easy_install 설치 (http://amornatura.tistory.com/95 참고)

- pip 설치  (http://amornatura.tistory.com/95 참고)

- pyparsing 설치 






Scala 와 Python 의 비교를 통해서 이 언어들의  기초적인 언어 스타일링에 대해서 빠르게 훑어보도록 하겠습니다.



                                             Scala vs  Python  



Scala 


스칼라(Scala)는 객체 지향 프로그래밍 언어와 함수형 프로그래밍의 요소가 결합된 다중패러다임 프로그래밍 언어이다. C++ 가 C의 요소를 가져오긴 했지만 객체지향을 지향하듯이 스칼라도 함수형으로 개발하는것을 지향한다. 스칼라의 이름은 <skah-lah>라고 발음하며 'Scalable Language'에서 따왔다. 적은 양의 코드로도 방대한 규모의 시스템을 작성할 수 있다는 특징이 있다.[2] 자바의 자바 가상 머신 에서 실행 할 수 있으며 자바의 API도 그대로, 혹은 스칼라의 형식에 맞춰 약간 수정한 형태로 사용 할 수 있다. 대중화를 위한 굉장히 큰 장점이다.스칼라의 주요 특징은 함수도 객체라는것과 숫자도 객체 즉 모든 것이 객체인것이 자바와는 가장 크게 다른 점이다.



Python :

파이썬도 절차지향,객체 지향, 함수형 프로그래밍의 요소가 결합된 다중패러다임 프로그래밍 언어이다

파이썬[1](Python)은 1991년[2] 프로그래머인 귀도 반 로섬(Guido van Rossum)[3] 이 발표한 고급 프로그래밍 언어로, 플랫폼 독립적이며 인터프리터식, 객체지향적, 동적 타이핑(dynamically typed) 대화형 언어이다. 파이썬이라는 이름은 귀도가 좋아하는 코미디 〈Monty Python's Flying Circus〉에서 따온 것이다.


파이썬은 비영리의 파이썬 소프트웨어 재단이 관리하는 개방형, 공동체 기반 개발 모델을 가지고 있다. C언어로 구현된 C파이썬 구현이 사실상의 표준이다. 표준 파이썬은 아무래도 느린감이 있지만 분산,병렬로 어느정도 카바 가능하다. 엄청나게 속도 크리티컬한 프로그램에선 쓸 수 없지만 pypy 등 속도를 향상시킨 파이썬 버전을 이용하여 속도라는 토끼도 잡을 수 있다. 개인적으로 그렇게 쓸 바엔 C++ 이나 RUST 쓰겠다. 




                                      이 표는 좀 오래된것 같군요. 몇가지가 빠진듯..Flask 같은..



   

1. 기본 구조 및 HelloWorld 


Scala) 


object HelloWorld {

  def main(args: Array[String]) {

    println("Hello, world!")

  }

}


HelloWorld.scala 로 저장



Python) 


class HelloWorld:

        def f(self):

                print "Hello, world!"

hw = HelloWorld()

hw.f()


print "HelloWorld"  라고 그냥 해도 됨. 클래스 안 만들고 말이죠.


Helloworld.py 로 저장.



Scala 의 main 함수는 static이 아니다. Scala에는 정적 멤버(함수,필드 모두) 라는 개념이 존재하지 않는다.
object선언은 싱글턴 객체를 생성하는데, 정적개념이 필요하면 싱글턴객체 안에 넣으면 된다. 


Python 은 구조상 특이점은 { }가 없다는것과 들여쓰기를 통한 단락의 구분과 : (콜론) 의 사용이다. 하위 레벨의 코드는 들여쓰기가 한 단계 깊어지고 상위레벨은 콜론으로 끝나야한다. 자바나 c++ 에서의 This 를 명시적으로 self 로 사용하는게 이채롭다. 



2. 주석 스타일 


Scala) 


// 한 줄 주석


/* 

여러 줄 주석  

*/




Python) 


# 한 줄 주석


‘’’ 

여러 줄 주석

‘’’


Scala 는 자바와 같고  

Python 은 여러 줄 일 경우 따옴표 3개 혹은 쌍따옴표 3개를 배치하면 된다.  



3. 기본 자료형  


Scala) 


Byte   8 bit . Range from -128 to 127

Short 16 bit . Range -32768 to 32767

Int        32 bit . Range -2147483648 to 2147483647

Long   64 bit

Float 32 bit IEEE 754 single-precision float

Double 64 bit IEEE 754 double-precision float

Char         16 bit unsigned Unicode character.

String A sequence of Chars

Boolean Either the literal true or the literal false

Unit         Corresponds to no value

Null         null or empty reference

Nothing The subtype of every other type;

Any          The supertype of any type; 

AnyRef  The supertype of any reference type




Python) 


Numbers (int, float etc.)

String

Dictionary

Tuple

List


a=’76.3’

b=float(a)     # 숫자로 형변환 

c = str(b)     # 문자로 형변환 


strLesson = ‘This is Python strings lesson’

StrLessonTriple = """This

is

string

Lesson"""   




4. 기본 자료구조  


Scala) 


val 변경불가
var 변경가능

 

val scor    =  Map(“Alice” → 10, “Bob” → 3)

val scores = scala.collection.mutable.Map()

scoes(“Bob”) = 10

scores += (“Bob”->1, “Fred”->7)




Python) 


Dictionary

Tuple

List

   


dict = {‘Mike’: 1233456,’John’: 567890}


list_mixed = [1, ‘this’, 2, ‘is’, 3, ‘list’, 4, ‘chapter’]

list_list      = [1, ‘this’, [ 5, ‘hell’], 9’]


tuple_strings = (‘this’, ‘is’, ‘tuple’, ‘lesson’)

tuple_mixed = (1, ‘this’, 2, ‘is’, 3, ‘tuple’, 4, ‘chapter’)


print “=” * 50





5. 연산자 


Scala) 


인식자 

변수,함수, 클래스등의 이름을 총체적으로 인식자라고부른다. 추가적으로 일련의 연산자문자도 사용가능 

val √ = scala.math.sqrt _

√ (2)

val ‘val’ = 42


삽입 연산자 (a identifier b)

a to 10

a.to(10)

1->10

1.->(10)


단항 연산자 (a identifier)

1 toString

1.toString() 


할당연산자  (a operator=b)

a+=b

a= a+b


apply/  update / unapply 

함수호출문법을 함수아닌값에도사용가능 

f(arg1,arg2, …)

f.apply(arg1,arg2,...)

f(arg1,arg2, …) = value

f.update(arg1,arg2,... value) 


unapply는 어떤 객체에서 값을 추출한다고 보면된다.

Case Fraction(a,b) =>   하면 Fraction 객체안의 값이 옵션으로 리턴됨. Option[(Int,Int)]




Python) 


1) 산술 연산자 : +, -, *, **, /, //, %


2) 관계 연산자 : <, >, <=, >=, ==, !=, <>


3) 논리 연산자 : not, and, or

    - 0, 0.0, 0L, 0.0+0.0j, (), {}, [], None, ""은 모두 거짓으로 간주

    - 나머지는 모두 참

    - 'and'와 'or'이 포함된 논리식은 식의 결과 값을 판정하는데 최종적으로 기여한 객체의 값을 식의 값으로 리턴


4) 비트 단위 연산자 : <<, >>, &, |, ^, ~


3. 수치 연산 함수

  1) 내장 수치 연산 함수

    - abs(x) : x의 절대값

    - int(x) : x를 int(정수)형으로 변환

    - long(x) :  x를 long형으로 변환

    - float(x) : x를 float형(실수형)으로 변환

    - complex(re, im) : 실수부 re와 허수부 im를 가지는 복소수

    - c.conjugate() : 복소수 c의 켤레 복소수

    - divmod(x, y) : (x//y, x%y) 쌍

    - pow(x, y) : x의 y승

  2) math 모듈 : math(실수 연산), cmath(복소수 연산)



5. 조건문 


Scala) 


var result = ""

if(marks >= 50)

  result = "passed"

else

  result = "failed"


------------------------------

result match {

  case "A" | "B" => println("Congratulations!")

  case "C" => println("There is room ..")

  case _ => println("We are ...")

}




Python) 



var = 100

if var == 200:

   print "1 - Got a true expression value"

   print var

elif var == 150:

   print "2 - Got a true expression value"

   print var

elif var == 100:

   print "3 - Got a true expression value"

   print var

else:

   print "4 - Got a false expression value"

   print var


Python 에는 switch 문이 없다. 



6. 반복문 


Scala) 


object Test {

   def main(args: Array[String]) {

      var a = 0;

      // for loop execution with a range

      for( a <- 1 to 10){

         println( "Value of a: " + a );

      }

   }

}

----------------------------------   

  var a = 0;

  val numList = List(1,2,3,4,5,6);


  for( a <- numList ){

     println( "Value of a: " + a );

  }

   



Python) 



for i in a:

  print I


# 0~3까지 범위

for i in range(4):

  print I


# 지정한 하한/상한의 범위에서만. (1씩 증가)

for i in range(1000, 1010):

  print I


# 지정한 하한/상한의 범위에서만. (2씩 증가)

# range()의 3번째 파라이터가, 건너뛸 숫자

for i in range(1, 14, 2):

  print I


# 지정한 숫자에서만

for i in 123, 341, 0, 666:

  print I


myList = ['cat', 'dog', 'rabbit']

 

for a in myList:

    print(a)




7. 배열 


Scala) 



var z = new Array[String](3)


z(0) = "Zara"

z(1) = "Nuha"

z(2) = "Ayan"


var z = Array("Zara", "Nuha", "Ayan")

var myList = Array(1.9, 2.9, 3.4, 3.5)

var myMatrix = ofDim[Int](3,3)


import Array._

object Test {

   def main(args: Array[String]) {

      var myMatrix = ofDim[Int](3,3)

      

      // build a matrix

      for (i <- 0 to 2) {

         for ( j <- 0 to 2) {

            myMatrix(i)(j) = j;

         }

      }


      var myList1 = Array(1.9, 2.9, 3.4, 3.5)

      var myList2 = Array(8.9, 7.9, 0.4, 1.5)


      var myList3 =  concat( myList1, myList2)


      var myList1 = range(10, 20, 2)

      var myList2 = range(10,20)

      




Python) 



MyList=[1,2,3,4,5,6]


MyList[2]=100


MyList[2:5]  #  from myList[2] to myList[4]. 


MyList[5:]     #  List[5] to the end of the list 


MyList[:5]     #  not including myList[5]


mi=MyList.index(m) 


myList=[i for i in range(10)]


myList=[]

for i in range(10):

 myList.append(1)  or myList[i]=1


b=[[0]*3 for i in range(3)]


B[0][0]=1


myArray=[[0 for j in range(3)] for i in range(3)]



8. 문자열 


Scala) 


var greeting = "Hello world!";

or

var greeting:String = "Hello world!";


var palindrome = "Dot saw I was Tod";

var len = palindrome.length();


"My name is ".concat("Zara");


object Test {

   def main(args: Array[String]) {

      var str1 = "Dot saw I was ";

      var str2 =  "Tod";

      println("Dot " + str1 + str2);

   }

}


object Test {

   def main(args: Array[String]) {

      var floatVar = 12.456

      var intVar = 2000

      var stringVar = "Hello, Scala!"

      var fs = printf("The value of the float variable is " +

                   "%f, while the value of the integer " +

                   "variable is %d, and the string " +

                   "is %s", floatVar, intVar, stringVar)

      println(fs)

   }

}




Python) 



food = "Python's favorite food is perl"

say = '"Python is very easy." he says.'

food = 'Python\'s favorite food is perl'


>>> head = "Python"

>>> tail = " is fun!"

>>> print(head + tail)

Python is fun!


>>> a = "python"

>>> print(a * 2)

Pythonpython


>>> a = "Life is too short, You need Python"

>>> a[3]

'e'


>>> a[0:4]

'Life'


>>> a[5:7]

'is'


>>> a[19:]

'You need Python'


>>> print("I eat %d apples." % 3)

I eat 3 apples.


>>> number = 10

>>> day = "three"

>>> print("I eat %d apples. so I was sick for %s days." % (number, day))

I eat 10 apples. so I was sick for three days.



9. 예외 


Scala) 


import java.io.FileReader

import java.io.FileNotFoundException

import java.io.IOException


object Test {

   def main(args: Array[String]) {

      try {

         val f = new FileReader("input.txt")

      } catch {

         case ex: FileNotFoundException => {

            println("Missing file exception")

         }

         case ex: IOException => {

            println("IO Exception")

         }

      } finally {

         println("Exiting finally...")

      }

   }

}



Python) 


        try:

...         result = x / y

...     except ZeroDivisionError:

...         print "division by zero!"

...     else:      ( 예외가 실행되지 않으면 실행)

...         print "result is", result

...     finally:     (예외가발생하던 말던 실행)

...         print "executing finally clause"



    try:

...     raise NameError, 'HiThere'

... except NameError:

...     print 'An exception flew by!'

...     raise



10. 클래스 


Scala) 


import java.io._


class Point(val xc: Int, val yc: Int) {

   var x: Int = xc

   var y: Int = yc

   def move(dx: Int, dy: Int) {

      ...

   }

}



class Time {

  private[this] var h = 12

  private[this] var m = 0

      

  def hour: Int = h

  def hour_=(x: Int){ h = x }

      

  def minute: Int = m

  def minute_=(x: Int){ m = x }

}




Python) 




class Service:

...     secret = "영구는 배꼽이 두 개다"

...     def __init__(self, name):

...         self.name = name

...     def sum(self, a, b):

...         result = a + b

...         print("%s님 %s + %s = %s입니다." % (self.name, a, b, result))


>>> pey = Service("홍길동”)

>>> pey.sum(1, 1)



11. 함수 


Scala) 



object Test {

   def main(args: Array[String]) {

        println( "Returned Value : " + addInt(5,7) );

   }

   def addInt( a:Int, b:Int ) : Int = {

      var sum:Int = 0

      sum = a + b


      sum

   }

}



Python) 



>>> def fib(n):    # write Fibonacci series up to n

...     "Print a Fibonacci series up to n"

...     a, b = 0, 1

...     while b < n:

...         print b,

...         a, b = b, a+b

... 

>>> # Now call the function we just defined:

... fib(2000)

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597


>>> def fib2(n): # return Fibonacci series up to n

...     "Return a list containing the Fibonacci series up to n"

...     result = []

...     a, b = 0, 1

...     while b < n:

...         result.append(b)    # see below

...         a, b = b, a+b

...     return result

... 

>>> f100 = fib2(100)    # call it

>>> f100                # write the result

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]



12. Import  방법 


Scala) 


Import clauses


An import clause has the form import p.I where the import expression I determines a set of names of members of p which are made available without qualification. For example:

The clause makes available without qualification..

import p._ all members of p (this is analogous to import p.* in Java).

import p.x the member x of p.

import p.{x => a} the member x of p renamed as a.

import p.{x, y} the members x and y of p.

import p1.p2.z the member z of p2, itself member of p1.



Python) 


import 모듈이름


>>> import mod1 

>>> print(mod1.sum(3,4))

7


mod1.py에 다음의 함수를 추가 시켜 보자.

def safe_sum(a, b): 

    if type(a) != type(b): 

        print("더할수 있는 것이 아닙니다.")

        return 

    else: 

        result = sum(a, b) 

    return result


>>> import mod1 

>>> print(mod1.safe_sum(3, 4))

7


>>> from mod1 import sum         // 모듈내의 기능을 바로 사용할수있게한다. 

>>> sum(3, 4) 

7


from mod1 import *



13. 콘솔 입출력   


Scala) 



object ScannerTest {

  def main(args: Array[String]) {

    var ok = true

    while (ok) {

      val ln = readLine()

      ok = ln != null

      if (ok) println(ln)

    }

  }

}


object ScannerTest {

  def main(args: Array[String]) {

    for (ln <- io.Source.stdin.getLines) println(ln)

  }

}


object Test {

   def main(args: Array[String]) {

      print("Please enter your input : " )

      val line = Console.readLine

      

      println("Thanks, you just typed: " + line)

   }

}



Python) 



>>> a = input() 

Life is too short, you need python 

>>> a 

Life is too short, you need python 

>>>


>>> number = input("숫자를 입력하세요: ") 

숫자를 입력하세요:


>>> a = 123 

>>> print(a)

123 

>>> a = "Python" 

>>> print(a) 

Python 

>>> a = [1, 2, 3] 

>>> print(a) 

[1, 2, 3]



14. 파일  입출력   


Scala) 


import java.io._


object Test {

   def main(args: Array[String]) {

      val writer = new PrintWriter(new File("test.txt" ))


      writer.write("Hello Scala")

      writer.close()

   }

}


import scala.io._


object ReadFile extends Application {

  val s = Source.fromFile("some_file.txt")

  s.getLines.foreach( (line) => {

    println(line.trim.toUpperCase)

  })

}



Python) 



f = open("C:/Python/새파일.txt", 'w')


f = open("새파일.txt", 'w')


for i in range(1, 11): 

    data = "%d 번째 줄입니다.\n" % i 

    f.write(data) 


f.close()


f = open("새파일.txt", 'r') 

line = f.readline() 

print(line)

f.close()


f = open("새파일.txt", 'r')


while 1: 

    line = f.readline()

    if not line: break 

    print(line)


f.close()


f = open("새파일.txt", 'r') 

lines = f.readlines()


for line in lines: 

    print(line)


f.close()




15. 컨테이너 (컬렉션) 


Scala) 


// Define List of integers.

val x = List(1,2,3,4)


// Define a set.

var x = Set(1,3,5,7)


// Define a map.

val x = Map("one" -> 1, "two" -> 2, "three" -> 3)


// Create a tuple of two elements.

val x = (10, "Scala")


// Define an option

val x:Option[Int] = Some(5)


object Test {

   def main(args: Array[String]) {

      val capitals = Map("France" -> "Paris", "Japan" -> "Tokyo")

      

      println("show(capitals.get( \"Japan\")) : " +  

                                          show(capitals.get( "Japan")) )

      println("show(capitals.get( \"India\")) : " +  

                                          show(capitals.get( "India")) )

   }

   

   def show(x: Option[String]) = x match {

      case Some(s) => s

      case None => "?"

   }

}



 var s = Some("abc")          // Scala can infer the type

    var t: Option[String] = None // Type must be explicit


def chooseFile(): Option[File] = { ... }



The most general way to use an Option is with a match:


    chooseFile() match {

      case Some(f) => // Do something with file f

      case None =>    // Do something when there is no file

    } 


You can check if an Option value is defined by comparing it with None, or by using the isDefined or isEmpty method:


    if (t isDefined) println(t)

    if (t isEmpty) println("Nothing here!")

You can extract the value of an Option, but only if you provide some default value for the None case:


    val w = t.getOrElse("Nothing here!")



Python) 


dict = {‘Mike’: 1233456,’John’: 567890}


list_mixed = [1, ‘this’, 2, ‘is’, 3, ‘list’, 4, ‘chapter’]

list_list      = [1, ‘this’, [ 5, ‘hell’], 9’]


tuple_strings = (‘this’, ‘is’, ‘tuple’, ‘lesson’)

tuple_mixed = (1, ‘this’, 2, ‘is’, 3, ‘tuple’, 4, ‘chapter’)







16. 상속 


Scala) 


class ScientificCalculator(brand: String) extends Calculator(brand) {
  def log(m: Double, base: Double) = math.log(m) / math.log(base)
}

Python) 


class Person:

    def __init__(self, name, age, gender):

        self.Name = name

        self.Age = age

        self.Gender = gender

    def aboutMe(self):

        print("저의 이름은 " + self.Name + "이구요, 제 나이는 " + self.Age + "살 입니다.")

         

class Employee(Person):

    def __init__(self, name, age, gender, salary, hiredate):

        Person.__init__(self, name, age, gender)

        self.Salary = salary

        self.Hiredate = hiredate

    def doWork(self):

        print("열심히 일을 합니다.")

    def aboutMe(self):

        Person.aboutMe(self)

        print("제 급여는 " + self.Salary + "원 이구요, 제 입사일은 " + self.Hiredate + " 입니다.")

 




17. 쓰레드 

Scala) 


scala> val hello = new Thread(new Runnable {

  def run() {

    println("hello world")

  }

})

hello: java.lang.Thread = Thread[Thread-3,5,main]


scala> hello.start

hello world 

------------------------------


import java.net.{Socket, ServerSocket}

import java.util.concurrent.{Executors, ExecutorService}

import java.util.Date


class NetworkService(port: Int, poolSize: Int) extends Runnable {

  val serverSocket = new ServerSocket(port)


  def run() {

    while (true) {

      // This will block until a connection comes in.

      val socket = serverSocket.accept()

      (new Handler(socket)).run()

    }

  }

}


class Handler(socket: Socket) extends Runnable {

  def message = (Thread.currentThread.getName() + "\n").getBytes


  def run() {

    socket.getOutputStream.write(message)

    socket.getOutputStream.close()

  }

}


(new NetworkService(2020, 2)).run


---------------------------------------


import java.net.{Socket, ServerSocket}

import java.util.concurrent.{Executors, ExecutorService}

import java.util.Date


class NetworkService(port: Int, poolSize: Int) extends Runnable {

  val serverSocket = new ServerSocket(port)

  val pool: ExecutorService = Executors.newFixedThreadPool(poolSize)


  def run() {

    try {

      while (true) {

        // This will block until a connection comes in.

        val socket = serverSocket.accept()

        pool.execute(new Handler(socket))

      }

    } finally {

      pool.shutdown()

    }

  }

}


class Handler(socket: Socket) extends Runnable {

  def message = (Thread.currentThread.getName() + "\n").getBytes


  def run() {

    socket.getOutputStream.write(message)

    socket.getOutputStream.close()

  }

}


(new NetworkService(2020, 2)).run



Python) 


from thread import start_new_thread


def heron(a):

    """Calculates the square root of a"""

    eps = 0.0000001

    old = 1

    new = 1

    while True:

        old,new = new, (new + a/new) / 2.0

        print old, new

        if abs(new - old) < eps:

            break

    return new


start_new_thread(heron,(99,))

start_new_thread(heron,(999,))

start_new_thread(heron,(1733,))


c = raw_input("Type something to quit.")


--------------------

import time

from threading import Thread


def sleeper(i):

    print "thread %d sleeps for 5 seconds" % i

    time.sleep(5)

    print "thread %d woke up" % i


for i in range(10):

    t = Thread(target=sleeper, args=(i,))

    t.start()


--------------------


class PrimeNumber(threading.Thread):

    prime_numbers = {} 

    lock = threading.Lock()

    

    def __init__(self, number): 

        threading.Thread.__init__(self) 

        self.Number = number

        PrimeNumber.lock.acquire() 

        PrimeNumber.prime_numbers[number] = "None" 

        PrimeNumber.lock.release() 

 

    def run(self): 

        counter = 2

        res = True

        while counter*counter < self.Number and res: 

            if self.Number % counter == 0: 

               res = False 

            counter += 1 

        PrimeNumber.lock.acquire() 

        PrimeNumber.prime_numbers[self.Number] = res 

        PrimeNumber.lock.release() 

threads = [] 

while True: 

    input = long(raw_input("number: ")) 

    if input < 1: 

        break 

 

    thread = PrimeNumber(input) 

    threads += [thread] 

    thread.start() 

 

for x in threads: 

    x.join()


18.  클로저  (외부의 변수에 자유로이 접근하라~) 


Scala) 


object Test {

   def main(args: Array[String]) {

      println( "muliplier(1) value = " +  multiplier(1) )

      println( "muliplier(2) value = " +  multiplier(2) )

   }

   var factor = 3

   val multiplier = (i:Int) => i * factor

}


C:/>scalac Test.scala

C:/>scala Test

muliplier(1) value = 3

muliplier(2) value = 6




19.  패턴 매칭  ( 스마트한 Switch 문 ) 


Scala) 

object Test {

   def main(args: Array[String]) {

      println(matchTest(3))


   }

   def matchTest(x: Int): String = x match {

      case 1 => "one"

      case 2 => "two"

      case _ => "many"

   }

}


C:/>scalac Test.scala

C:/>scala Test

many




20.  트레잇   ( 다중상속 가능 객체 , 공통적으로 사용되는 것들이 현실에 존재함..) 


Scala) 


 trait Equal {

  def isEqual(x: Any): Boolean

  def isNotEqual(x: Any): Boolean = !isEqual(x)

}


class Point(xc: Int, yc: Int) extends Equal {

  var x: Int = xc

  var y: Int = yc

  def isEqual(obj: Any) =

    obj.isInstanceOf[Point] &&

    obj.asInstanceOf[Point].x == x

}


object Test {

   def main(args: Array[String]) {

      val p1 = new Point(2, 3)

      val p2 = new Point(2, 4)

      val p3 = new Point(3, 3)


      println(p1.isNotEqual(p2))

      println(p1.isNotEqual(p3))

      println(p1.isNotEqual(2))

   }

}




21.  정규표현식 


Scala) 



import scala.util.matching.Regex


object Test {

   def main(args: Array[String]) {

      val pattern = new Regex("(S|s)cala")

      val str = "Scala is scalable and cool"

      

      println((pattern findAllIn str).mkString(","))

   }

}





Python) 


import re

programming = ["Python", "Perl", "PHP", "C++"]


pat = "^B|^P|i$|H$"


for lang in programming:

    

    if re.search(pat,lang,re.IGNORECASE):

        print lang , "FOUND"

    

    else:

        print lang, "NOT FOUND"



The output of above script will be:


Python FOUND

Perl FOUND

PHP FOUND

C++ NOT FOUND



22.  함수형 고계함수들


 Scala) 

val nums = List(1, 2, 3, 4, 5)

//map
val nums_map = nums.map(x => x * 10)
println(nums_map)//List(10, 20, 30, 40, 50)

//reduce
val nums_reduce = nums.reduce( _ + _ )
println(nums_reduce)//15

//filter
val nums_filter = nums.filter( x => x < 3)
println(nums_filter)//List(1, 2)

//fold
val nums_fold = nums.fold(1){ (sum , x) => sum + x}
println(nums_fold)//16

//group
val nums_trans = nums.groupBy(x => x < 3)
println(nums_trans) //Map(false -> List(3, 4, 5), true -> List(1, 2))


Python) 

nums = [1, 2, 3, 4, 5]


#map
nums_map = map(lambda x : x * 10, nums)
print(nums_map)

#reduce
nums_reduce = reduce(lambda x , y : x + y , nums)
print(nums_reduce)

#filter
nums_filter = filter(lambda x : x < 3 , nums)
print(nums_filter)

#fold
nums_fold = reduce(lambda x , y : x + y, nums, 1)
print(nums_fold)

#group
from itertools import groupby
for key, igroup in groupby(nums, lambda x: x < 3):
print key, list(igroup)

# True [1, 2]
# False [3, 4, 5]


+ Recent posts