Code

python0710

seunghyeoniya 2023. 8. 17. 08:34

main.py

# 숫자 list를 이용하여 제곱을 가한 list를 생성
square = [i for i in range(10000)] # 0부터 9999까지의 숫자를 가지는 list를 생성
temp = []

# 반복문을 이용한 변환
for x in square:
    temp.append(x * x) # append : 추가하는 method
print(temp)

# 함수를 이용한 변환
def f(x):
    return x * x # -> 문장이 한 줄이므로 한 줄 함수인 lambda(람다)로 치환할 수 있다.

# square의 모든 요소에 f 함수를 적용해서 변환한 결과를 temp에 대입
temp = list(map(f, square)) # map을 이용한 변환, map -> list 자료형 변환
print(temp)

# 함수의 내용이 한 줄이므로 lambda(람다)로 처리
temp = list(map(lambda x : x * x, square)) # map을 이용한 변환, map -> list 자료형 변환


profile = ["SeunghyeonBan", "age", "25"]
temp1 = []

def f(x):
    if len(x) > 10:
        return x[0:10] + "--"
    return x # -> 함수의 내용이 한 줄이 아니기 때문에 lambda(람다)로 표현할 수 없다.

temp1 = list(map(f, profile))
print(temp1)


ar = ["반승현", "임한별", "신용재", "허각", None]
# 결측치 여부를 확인
print(None in ar) # ar 안에 None이 있는지 탐색
def f1(x):
    return x != None
# 결측치 제거 후 list 재생성
ar = list(filter(f1, ar))
# ar = list(filter(lambda x : x!= None,ar)) # -> 한 줄이기 때문에 람다로 표현이 가능하다.
print(ar)

# 이름이 세 글자 이상인 데이터만 추출
def f2(x):
    return len(x) >= 3 # 허각은 이름이 두 글자이기 때문에 함수에 대입하면 False를 리턴한다.

ar = list(filter(f2, ar))
# ar = list(filter(lambda x : len(x) >= 3,ar)) # -> 한 줄이기 때문에 람다로 표현이 가능하다.
print(ar)

# 문자열 비교가 가능한지 확인
# print("가" > "나") # -> False
# print("가" < "나") # -> True
result = list(filter(lambda x: x[0] >= "아" and x[0] < "자", ar))
print(result)


# 데이터가 collection에 포함되어 있는지 확인 : in(반대가 not in)
ar = ["1", "2", "3"]
kwlist = ["2"]

num = len(kwlist) # kwlist의 길이 측정
for idx in range(num):
    print(kwlist[idx] in ar)

# ar에서 kwlist에 있는 것을 제외하고 새로운 list로 생성
new = [] # 객체를 받아들일 새로운 list 생성
def f3(x):
    for idx in range(num):
        if(x != kwlist[idx]):
            return x

new = list(filter(f3,ar))
print(new)


from functools import reduce
complex = reduce(lambda x, y : x*y,[1,2,3,4])
# 맨 앞의 두 객체인 1과 2의 계산결과와 세 번째 객체인 3의 계산(곱), 이 계산결과인 6을 마지막 객체인 4와 계산(곱)
print(complex)


key = ["초등학교", "중학교", "고등학교"]
value = ["연가초등학교", "연희중학교", "충암고등학교"]
print(list(zip(key,value)))
print(set(zip(key,value))) # set에는 순서가 존재하지 않는다.
print(dict(zip(key,value)))


# outer_data = "전역에 만든 데이터"
def outer():
    outer_data = "외부 함수의 데이터"
    def inner():
        inner_data = "내부 함수의 데이터"
        nonlocal outer_data # 함수 내부에 데이터를 생성하지 않고, 외부의 데이터를 사용하기 위해서 변수를 다시 정의한다.
        outer_data = "내부에서 외부 함수의 데이터 변경" # 위의 문장에서 local -> nonlocal로 자료형을 바꾸었기 때문에, nonlocal에 변경이 적용된다.
        print(outer_data)
    # print(inner_data) # -> inner_data는 inner함수 내에서 정의했기 때문에 블록 밖에서 사용하지 못한다.
    inner()
    print(outer_data)
outer()
# inner() # -> 중첩 함수인 inner함수는 함수가 만들어진 블록에서만 호출이 가능하다.


def outer():
    data = 0
    # 자신을 감싸고 있는 함수의 데이터를 수정하는 함수
    def inner():
        nonlocal data
        data = data + 1
        print(data)
    # 함수 내부에서 데이터를 수정하는 함수를 만들어 이를 리턴하는 함수를 closure이라고 합니다.
    return inner
closure = outer() # 함수를 호출해서 리턴하는 함수를 변수에 저장
closure()
closure()


def deco1(func): # ex. func = businessLogic
    print("공통관심사항")
    func()
# 이제부터 businessLogic 이라는 함수를 호출하면 deco1 라는 함수를 수행합니다.
# deco1에게 매개변수로 businessLogic 이라는 함수가 전달됩니다.
# 개발자가 작성한 코드 대신에 다른 코드를 불러내는 방식을 프록시 패턴이라고 합니다.
@deco1 # deco 함수를 수행시켜주세요.(at deco)
def businessLogic1():
    print("업무 로직")

businessLogic1 # 리턴할 것이 없어서 함수 호출할 때 괄호를 따로 쓰지 않아도 된다.

def deco2(func):
    func()
    print("로깅")

@deco2
def businessLogic2():
    print("업무 로직")

businessLogic2 # 리턴할 것이 없어서 함수 호출할 때 괄호를 따로 쓰지 않아도 된다.

# 고객의 니즈가 변경
# 업무 로직과는 관계가 없는 로깅을 출력하는 코드를 추가하기를 원하는 방향으로 변경
# 유지보수 과정이나 업무 로직과 관련이 없는 코드를 추가하거나 삭제하는 경우
# 업무 로직을 직접 수정하는 것은 예상치 못한 결과를 만들어 낼 수 있습니다.
# 이런 경우에는 업무 로직은 손을 대지않고 가능하도록 만드는 것이 좋습니다.


import time
def clock(func):
    # decorator가 적용된 함수가 호출되면 수행될 실제 함수
    def clocked(*args):
        start = time.time() # 현재 시간을 기록
        # 업무 로직 함수를 호출
        result = func(*args)
        end = time.time()
        elapsed = end- start # 함수의 수행시간
        print("수행 시간:", elapsed)
        # 매개변수 확인
        print("매개변수:", args)
        # 리턴 값
        print("리턴값", args)
        return result
    return clocked

import functools # functools.lru_cache를 사용하기 위해서 패키지를 import 해야 한다.
@functools.lru_cache # 해당 데코레이터를 사용해서 중복되는 함수를 가져오지 않으므로 속도가 빨라진다.
@clock
# 피보나치 수열을 구해주는 함수
# 첫번째와 두번째는 무조건 1
# 세번째부터는 이전 2개 항의 합
def fibonacci(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(6))


print(type(10)) # class 'int' -> instance로부터 만들어진 것이다.


# 클래스 생성
# class 클래스이름:
class Student:
    # 인스턴스가 있어야만 호출되는 메서드 생성
    # def 메서드이름(self, 매개변수): # 첫 번째 매개변수인 인스턴스 참조를 저장할 매개변수의 이름은 self를 주로 사용한다.
    def disp(self):
        print("인스턴스 생성")
    def setName(self, name):
        self.name = name  # 지역 변수가 아니라 인스턴스의 속성을 생성

# 인스턴스 생성
# 인스턴스 이름 = 클래스 이름(매개변수)
student = Student()
# -> 여러 번 사용할 때 편리하게 쓰기 위해서 Bound 호출을 선택하였다.
# -> 한 번만 사용하는 것이라면 Bound 호출이 아니라, Unbound 호출을 이용해 클래스를 곧바로 써도 된다.

# 메서드 호출 - bound 호출
student.disp()
# 메서드 호출 - Unbound 호출
Student.disp(student)

stu = Student()
stu.setName("파이터")
print(stu.name)

stu.score = 94 # 인스턴스에 score라는 속성이 있으면 수정, 없으면 생성
print(stu.score)


class Student:
    class_data = "클래스의 속성"

student = Student() # 인스턴스를 생성할 때는 이처럼 클래스이름을 호출한다.
print(Student.class_data) # 클래스이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스이름을 이용해서 클래스 속성에 접근

Student.class_data = "클래스 데이터 수정" # 클래스이름으로 클래스 속성 수정
print(Student.class_data) # 클래스이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스이름을 이용해서 클래스 속성에 접근

student.class_data = "인스턴스를 이용해서 클래스 데이터 수정" # 인스턴스이름으로 클래스 속성 수정
print(Student.class_data) # 클래스 이름을 이용해서 클래스 속성에 접근
print(student.class_data) # 인스턴스 이름을 이용해서 클래스 속성에 접근
# -> 클래스(Student)에는 class_data라는 속성이 존재하지만, 인스턴스(student)에는 존재하지 않아서 새로 생성된다. 따라서 출력 결과가 다르게 나타난다.


class Student:
    class_data = "클래스의 속성"
# 인스턴스를 생성해서 대입
stu1 = Student()
# 인스턴스를 생성해서 대입
stu2 = Student()
# stu1의 데이터를 대입 : stu1이 참조하고 있는 데이터의 참조를 stu3가 참조합니다.
stu3 = stu1

# 2개의 인스턴스가 동일한지 여부를 확인
print(stu1 == stu2) # 내부의 데이터가 같은지 확인
print(stu1 is stu2) # id가 같은지 확인
# -> 인스턴스는 속성이나 클래스에 대한 참조를 가져오는 것이기 때문에,
# stu1과 stu2는 서로 다른 인스턴스로 각각 다른 참조를 나타내기(가리키기) 떄문에 위의 두 결과에 대해서 False가 나오게 된다.

print(stu1 == stu3) # 내부의 데이터가 같은지 확인
print(stu1 is stu3) # id가 같은지 확인
# -> stu3은 stu1의 참조를 그대로 받아오므로 위의 두 결과에 대해서 True가 나오게 된다.


# 이름과 점수를 갖는 객체를 여러개 필요로 하는 경우
class Student:
    def getName(self):
        return self.name
    def setName(self, name):
        self.name = name
    def getScore(self):
        return self.score
    def setScore(self, score):
        self.score=score

stu1 = Student()
# setter를 이용한 속성 생성과 설정
stu1.setName("반승현")
stu1.setScore(99)
# getter를 이용한 속성 사용
print(stu1.getName())
print(stu1.getScore())
# 최근에 등장한 IDE는 대부분 getter와 setter를 만드는 유틸을 제공합니다.

#python

'Code' 카테고리의 다른 글

python0707  (0) 2023.08.07
python0706  (0) 2023.08.05