728x90

django : ORM(Object Relational Mapping) - SQL문을 작성하지 않음


--함수 작성 가이드 라인

  • 함수는 가능하면 짧게 작성할 것

  • 함수 이름에 함수의 역할, 의도가 명확히 드러날 것

 

SOP(Single Object Principal) -> 디자인 패턴(하나에 한가지 역할만 할 수 있도록 함)

 

  • 인자로 받은 값 자체를 바꾸지 말 것(임시변수 선언)

 

*함수는 언제 만드는가?

  • 공통적으로 사용되는 코드는 함수로 변환

  • 복잡한 수식 -> 식별 가능한 이름의 함수로 변환

  • 복잡한 조건 -> 식별 가능한 이름의 함수로 변환


 

--🌟Pythonic Code 작성하기🌟

  • 예시 : 여러 단어들을 하나로 붙일 때

>>>result = ''.join(colors)

 

  • 파이썬 스타일의 코딩기법

  • 파이썬 특유의 문법을 활용하여 효율적으로 코드를 표현함

  • 고급코드를 작성할수록 더 많이 필요해짐

 

  • 10 Tips for Pythonic Code (M.Kennedy, 2016)

( https://www.youtube.com/watch?v=_O23jIXsshs )

  • The Hitchhikier's Guide to Python

( https://python-guide-kr.readthedocs.io/ko/latest/ )

( https://docs.python-guide.org/writing/style/ )

 

**Split함수

  • String type의 값을 나눠서 List형태로 변환

 

**Join함수

  • String List를 합쳐 하나의 String으로 반환할 때 사용

# Split 과 Join 함수
my_str = 'java python kotlin'
my_list = my_str.split()
print(type(my_list), my_list)

my_str2 = ''.join(my_list)
print(my_str2)

my_str = 'java,python,kotlin'
my_list = my_str.split(',')
print(type(my_list), my_list)
my_str2 = ','.join(my_list)
print(my_str2)

# replace()
result = my_str.replace(',', '?')
print(result)

>>><class 'list'> ['java', 'python', 'kotlin']

javapythonkotlin

<class 'list'> ['java', 'python', 'kotlin']

java,python,kotlin

 

java,python,kotlin

java?python?kotlin

 

 

**List Comprehensions

  • 기존 List 사용하여 간단히 다른 List를 만드는 기법

  • 포괄적인 List, 포함되는 리스트라는 의미로 사용됨

  • 파이썬에서 가장 많이 사용되는 기법 중 하나

  • 일반적으로 for + append보다 속도가 빠름

# 일반적인 for + append
result = []
for val in range(10):
    if val % 2 == 0:
        result.append(val)
print(result)

# List Comprehensions
result2 = [val for val in range(10) if val % 2 == 0]
print(result2)

>>>[0, 2, 4, 6, 8]

[0, 2, 4, 6, 8]

 

result = [i+j for i in my_str1 for j in my_str2 if not (i == j)]
print(result)

>>>['HW', 'Ho', 'Hr', 'Hl', 'Hd', 'eW', 'eo', 'er', 'el', 'ed', 'lW', 'lo', 'lr', 'ld', 'lW', 'lo', 'lr', 'ld', 'oW', 'or', 'ol', 'od']

 

# 2차원 배열 만들기
words = 'Requiring an active virtual environment for pip'.split()
print(words)

my_list = [[w.upper(), w.lower(), w.title(), len(w)] for w in words]
print(type(my_list), my_list)
for word in my_list:
    print(word)

>>>['Requiring', 'an', 'active', 'virtual', 'environment', 'for', 'pip']

<class 'list'> [['REQUIRING', 'requiring', 'Requiring', 9], ['AN', 'an', 'An', 2], ['ACTIVE', 'active', 'Active', 6], ['VIRTUAL', 'virtual', 'Virtual', 7], ['ENVIRONMENT', 'environment', 'Environment', 11], ['FOR', 'for', 'For', 3], ['PIP', 'pip', 'Pip', 3]]

['REQUIRING', 'requiring', 'Requiring', 9]

['AN', 'an', 'An', 2]

['ACTIVE', 'active', 'Active', 6]

['VIRTUAL', 'virtual', 'Virtual', 7]

['ENVIRONMENT', 'environment', 'Environment', 11]

['FOR', 'for', 'For', 3]

['PIP', 'pip', 'Pip', 3]

 

 

**연습문제 122p 책 목록 선언

books = list()
books.append({'제목':'개발자의 코드', '출판연도':'2013.02.28', '출판사':'A출판 ', '쪽수':200, '추천유무':False})
books.append({'제목':'클린 코드', '출판연도':'2013.03.04', '출판사':'B출판 ', '쪽수':584, '추천유무':True})
books.append({'제목':'빅데이터 마케팅', '출판연도':'2014.07.02', '출판사':'A출판', '쪽수':296, '추천유무':True})
books.append({'제목':'구글드', '출판연도':'2010.02.10', '출판사':'B출판', '쪽수':526, '추천유무':False})
books.append({'제목':'강의력', '출판연도':'2013.12.12', '출판사':'C출판', '쪽수':248, '추천유무':True})

many_page_list = list()
recommand_list = list()
all_page_sum_value = int()
pub_name_set = set()

# 1. 250쪽이 넘는 책 목록 만들기
for book in books:
    # print(type(book), book['쪽수'])
    if book['쪽수'] > 250:
        many_page_list.append(book['제목'])
print(f'250쪽이 넘는 책 : {many_page_list}')

# 2. 추천유무가 True인 책 목록 만들기
for book in books:
    if book['추천유무']:
        recommand_list.append(book['제목'])
    all_page_sum_value += book['쪽수']
print(f'추천하는 책 : {recommand_list}')
print(f'전체 책의 쪽수 : {all_page_sum_value}')

# 3. 출판사 목록 만들기 (중복되는 이름은 제거합니다.)
for book in books:
    pub_name_set.add(book['출판사'].strip())
print(f'출판사 목록 : {pub_name_set}')

>>>250쪽이 넘는 책 : ['클린 코드', '빅데이터 마케팅', '구글드']

추천하는 책 : ['클린 코드', '빅데이터 마케팅', '강의력']

전체 책의 쪽수 : 1854

출판사 목록 : {'C출판', 'A출판', 'B출판'}

 

**위의 것에 List Comprehension적용

# List Comprehension 사용
many_page_list = [book['제목'] for book in books if book['쪽수'] > 250]
recommand_list = [book['제목'] for book in books if book['추천유무']]
all_page_sum_value = sum(book['쪽수'] for book in books)
pub_name_set = set([book['출판사'].strip() for book in books])

print(f'250쪽이 넘는 책 : {many_page_list}')
print(f'추천하는 책 : {recommand_list}')
print(f'전체 책의 쪽수 : {all_page_sum_value}')
print(f'출판사 목록 : {pub_name_set}')

>>>250쪽이 넘는 책 : ['클린 코드', '빅데이터 마케팅', '구글드']

추천하는 책 : ['클린 코드', '빅데이터 마케팅', '강의력']

전체 책의 쪽수 : 1854

출판사 목록 : {'C출판', 'A출판', 'B출판'}

 

 

 

**Enumerate

  • List의 element를 추출할 때 번호를 붙여서 추출

# enumerate 함수 - for loop 를 dict에 저장
for idx, w in enumerate(words):
    print(idx, w)
    
print(enumerate(words), type(enumerate(words)))
print(list(enumerate(words)))

word_dict = {idx: w for idx, w in enumerate(words, 1)}
print(word_dict)

>>>0 Requiring

1 an

2 active

3 virtual

4 environment

5 for

6 pip

<enumerate object at 0x7f9b2091a7c0> <class 'enumerate'>

[(0, 'Requiring'), (1, 'an'), (2, 'active'), (3, 'virtual'), (4, 'environment'), (5, 'for'), (6, 'pip')]

{1: 'Requiring', 2: 'an', 3: 'active', 4: 'virtual', 5: 'environment', 6: 'for', 7: 'pip'}

 

 

**Zip

  • 두 개의 list의 값을 병렬적으로 추출함

# zip 함수
my_list1 = [1, 2, 3]
my_list2 = [10, 20, 30]
my_list3 = [100, 200, 300]
print(zip(my_list1, my_list2, my_list3), type(zip(my_list1, my_list2, my_list3)))
print(list(zip(my_list1, my_list2, my_list3)))

for val in zip(my_list1, my_list2, my_list3):
    print(type(val), val, sum(val))
    
result = [sum(val) for val in zip(my_list1, my_list2, my_list3)]
print(result)

result_dict = {idx: sum(val) for idx, val in enumerate(zip(my_list1, my_list2, my_list3)) }
print(result_dict)

a, b, c = zip(my_list1, my_list2, my_list3)
print(a)
print(b)
print(c)

>>><zip object at 0x7f9b2091a880> <class 'zip'>

[(1, 10, 100), (2, 20, 200), (3, 30, 300)]

<class 'tuple'> (1, 10, 100) 111

<class 'tuple'> (2, 20, 200) 222

<class 'tuple'> (3, 30, 300) 333

[111, 222, 333]

{0: 111, 1: 222, 2: 333}

(1, 10, 100)

(2, 20, 200)

(3, 30, 300)

 


 

--람다식

  • 함수의 이름 없이 쓸 수 있는 익명함수

  • 수학의 람다 대수에서 유래함

def add(x, y):
    return x + y
    
print(add(10, 20))

add2 = lambda x, y: x + y
print(add2(10,20))

print((lambda x, y: x + y)(10, 20))
print((lambda x: x ** 2)(10))

>>>30

30

30

100

 

--Map함수

  • Sequence자료형 각 element에 동일한 function을 적용함

  • 두 개 이상의 list에도 적용 가능함, if filter도 사용가능

#map(함수, list)함수
double_val = lambda x: x ** 2
print(double_val(2))

my_list = [1, 2, 3, 4, 5]
# for loop 사용해서 함수호출
result_list = []
for val in my_list:
    # print(double_val(val))
    result_list.append(double_val(val))
print(result_list)

result = map(double_val, my_list)
print(type(result), result)

result = list(map(double_val, my_list))
print(result)

# my_list를 순회(iterate) 하면서 값을 제곱값을 반환하는 함수를 호출한다.
result = list(map(lambda x: x ** 2, my_list))
print(result)

>>>4

[1, 4, 9, 16, 25]

<class 'map'> <map object at 0x7f98191064f0>

[1, 4, 9, 16, 25]

[1, 4, 9, 16, 25]

 

# [1,2,3,4,5], [10,20,30,40,50] 두개의 리스트의 값을 더하기
# [11,22,33,44,55]
# lambda 함수와 map 함수 사용add = lambda x, y : x + y
print(add(1,10))
my_list1 = [1,2,3,4,5]
my_list2 = [10,20,30,40,50]
result = list(map(add, my_list1, my_list2))
print(result)

result = list(map(lambda x, y : x + y, my_list1, my_list2))
print(result)

# 짝수만 제곱하는 함수
double_even = lambda x: x ** 2 if x % 2 == 0 else x
print(double_even(4), double_even(5))
print(list(map(double_even, my_list1)))
print(list(map(lambda x: x ** 2 if x % 2 == 0 else x, my_list1)))

>>>11

[11, 22, 33, 44, 55]

[11, 22, 33, 44, 55]

16 5

[1, 4, 3, 16, 5]

[1, 4, 3, 16, 5]

 

 

--reduce함수

  • map function과 달리 list에 똑같은 함수를 적용해서 통합

# reduce함수
from functools import reduce
print(reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]))

>>>15

 

jsbin.com : javascript 작성하고 결과확인

 

--코드를 재사용할 수 있는 방법?

  1. copy & paste

  2. function 정의하고 호출

  3. 상속 적용

  4. AOP(Aspect Oriented Programming) - 관점지향 프로그래밍


 

--객체와 클래스

  • Object-Oriented Programming, OOP

  • 객체 : 실생활에서 일종의 물건, 속성(Attribute)와 행동(Action)을 가짐

  • OOP는 이러한 객체 개념을 프로그램으로 표현, 속성은 variable, 행동은 함수로 표현됨

  • 파이썬 역시 객체 지향 프로그램 언어

 

**Naming규칙

  • Snake_Case : "_"를 추가

  • CamelCase : 띄워쓰기 부분에 대문자 낙타의 등 모양, 파이썬 클래스명에 사용함

 

  • __init__은 객체 초기화 예약 함수(생성자)

  • __는 특수한 예약함수나 private변수에 사용됨

# 클래스 선언
# class MyClass extends Object {}, class MyClass {} - Java
# class MyClass(object): , class MyClass: - Python
# class MyClass(object):
class MyClass:
    # constructor 생성자 선언
    def __init__(self):
        # attribute(속성) 초기화
        self.num = 100
        
    # method(행위) 선언
    def read_number(self):
        return self.num
        
    # 부모 클래스(object)가 가진 __str__ 메서드를 재정
    def __str__(self):
        return f'MyClass의 속성 Num : {str(self.num)}'
        
# 객체를 생성
myobj1 = MyClass()
print(myobj1, type(myobj1))

print(myobj1.read_number())

>>>MyClass의 속성 Num : 100 <class '__main__.MyClass'>

100

 

__init__은 생성자

__str__은 객체주소대신 특정값을 반환하고 싶을 때 사용

 

class SoccerPlayer(object):
    # 생성자 함수 - 객체 생성될때 호출됨
    def __init__(self, name, position, back_number = 20):
        print('생성자 함수 호출됨')
        # 속성들
        self.name = name
        self.position = position
        self.back_number = back_number
        
    # back_number 속성을 변경하는 메서드
    def change_back_number(self1, new_number):
        print("선수의 등번호를 변경합니다 : From %d to %d" % (self1.back_number, new_number))
        self1.back_number = new_number
        
    # 객체주소 대신에 원하는 다른 속성값을 반환해주는 메서드
    def __str__(self):
        print('객체의 속성 값을 반환해주는 메소드')
        return "Hello, My name is %s. I play in %s in center Back Number %d" % (self.name, self.position, self.back_number)
        
jinhyun = SoccerPlayer("Jinhyun", "MF", 10)
print(jinhyun)

dooly = SoccerPlayer('둘리', 'GK')
print(dooly)

print("현재 선수의 등번호는 :", jinhyun.back_number)
jinhyun.change_back_number(5)
print("현재 선수의 등번호는 :", jinhyun.back_number)

>>>생성자 함수 호출됨

객체의 속성 값을 반환해주는 메소드

Hello, My name is Jinhyun. I play in MF in center Back Number 10

생성자 함수 호출됨

객체의 속성 값을 반환해주는 메소드

Hello, My name is 둘리. I play in GK in center Back Number 20

현재 선수의 등번호는 : 10

선수의 등번호를 변경합니다 : From 10 to 5

현재 선수의 등번호는 : 5

 

 

# 선수명, 선수 포지션, 선수 등번호
names = ['홍길동', '박지성', '손흥민', '둘리', '파이썬']
positions = ['DF', 'MF', 'GK', 'DF', 'WF']
back_numbers = [5, 10, 20, 30, 15]

# Class 없이 여러명의 선수정보를 2차원 배열에 저장하기
for na, po, ba in zip(names,positions,back_numbers):
	print(na, po, ba)
    
players = [[name, position, back_number] for name, position, back_number in zip(names, positions, back_numbers)]
print(players)
player1 = players[0]
# back_number를 변경(직관적이지 않음)
player1[2] = 20
print(player1)

# SoccerPlayer 클래스를 import
from mycode.oop.python_class import SoccerPlayer

player = SoccerPlayer('dooly', 'MF', 10)
print(player)
players_obj = [SoccerPlayer(name, position, back_number) for name, position, back_number in zip(names, positions, back_numbers)]
print(players_obj)
player1 = players_obj[0]
# back_number 변경
player1.change_back_number(30)
print(player1)

>>>홍길동 DF 5

박지성 MF 10

손흥민 GK 20

둘리 DF 30

파이썬 WF 15

[['홍길동', 'DF', 5], ['박지성', 'MF', 10], ['손흥민', 'GK', 20], ['둘리', 'DF', 30], ['파이썬', 'WF', 15]]

['홍길동', 'DF', 20]

Hello, My name is dooly. I play in MF in center Back Number 10

[<mycode.oop.python_class.SoccerPlayer object at 0x7fcb889069d0>, <mycode.oop.python_class.SoccerPlayer object at 0x7fcb88906a00>, <mycode.oop.python_class.SoccerPlayer object at 0x7fcb88906a60>, <mycode.oop.python_class.SoccerPlayer object at 0x7fcb88906ac0>, <mycode.oop.python_class.SoccerPlayer object at 0x7fcb88906b20>]

선수의 등번호를 변경합니다 : From 5 to 30

Hello, My name is 홍길동. I play in DF in center Back Number 30

 

# 실행했을 경우에만 메인메소드 호출, ctrl + shift + f10, python python_class.py
# import한 경우에는 main() 함수가 호출되지 않는다.
if __name__ == "__main__":
    main()

--terminal 창에서

(jsEnv) mhee4@Moonhees-MacBook-Pro python_programming_stu % cd mycode

(jsEnv) mhee4@Moonhees-MacBook-Pro mycode % cd oop

(jsEnv) mhee4@Moonhees-MacBook-Pro oop % python python_class.py

Hello, My name is Jinhyun. I play in MF in center Back Number 10

Hello, My name is 둘리. I play in GK in center Back Number 20

현재 선수의 등번호는 : 10

선수의 등번호를 변경합니다 : From 10 to 5

현재 선수의 등번호는 : 5

 

(jsEnv) mhee4@Moonhees-MacBook-Pro python_programming_stu % python

Python 3.8.5 (default, Sep 4 2020, 02:22:02)

[Clang 10.0.0 ] :: Anaconda, Inc. on darwin

Type "help", "copyright", "credits" or "license" for more information.

>>> from mycode.oop.python_class import SoccerPlayer

>>> player = SoccerPlayer('aaa','mf')

>>> player

<mycode.oop.python_class.SoccerPlayer object at 0x7f88418c5880>

>>> print(player)

Hello, My name is aaa. I play in mf in center Back Number 20

 

**캡슐화

class MyClass:
    # constructor 생성자 선언
    def __init__(self):
        # attribute(속성) 초기화
        self.num = 100
        # private 속성
        self.__name = 'dooly'

 

 

print(myobj1.__name)

 

>>Traceback (most recent call last):

File "/Users/mhee4/mypython/python_programming_stu/mycode/oop/MyClass.py", line 26, in <module>

print(myobj1.__name)

AttributeError: 'MyClass' object has no attribute '__name'

 

--getter, setter메소드를 만들어서 가져와야함

# getter method
@property
def name(self):
    return self.__name
    
# setter method
@name.setter
def name(self, new_name):
    if len(new_name) == 3:
        self.__name = new_name
    else:
        print('새로운 이름의 길이는 3이어야 합니다.')
# getter method 호출
print(myobj1.name)

# setter method 호출
myobj1.name = '길동'
print(myobj1.name)

>>>dooly

길동

 

 

 

 

728x90

+ Recent posts