Sister Nosilv story

프로그래밍기초 Intro to Python 총정리

by 노실언니

[ 계속 도움받은 사전같은 사이트 ]

3. Data model  [ ] [ ]

2. Lexical analysis [ ] [ ]

7. 단순문(Simple statements)  [ ] [ ]

8. 복합문(Compound statements) [ ] [ ]

 

프로그래밍기초Course

  📺플밍기초 in Python📺 - 🎖수료증

*Link : 📺인강  📝정리노트

10년 안에 프로그래밍을 모르면 문맹이 되는 시대가 올 것입니다. 인공지능, 로봇, 사물인터넷, 가상현실, 스마트카 등 다가오는 미래 산업에 프로그래밍을 빼고 말할 수 있는 것은 없습니다. 그렇다면, 어떤 언어로 시작하는 게 좋을까요? 코드잇에서는 파이썬을 가장 추천합니다. 파이썬은 실리콘벨리를 비롯 세계 유수 기업에서 가장 많이 쓰는 언어이며, 미국 대학 상위 39개 컴퓨터 학과에서 선호하는 언어 1위이기도 합니다. 데이터 사이언스, 웹 개발 등 어디 하나 빠지지 않고 쓰이지요. 파이썬과 함께 프로그래밍의 세계에 첫 걸음을 내딛어 보세요.

Python을 배우면서 프로그래밍 자체도 배워보자

총 INDEX
총 Keyword

Topic 1. 프로그래밍 시작하기

프로그래밍의 진입 장벽이 너무 높게 느껴진다면? 파이썬으로 프로그래밍을 시작하세요!

- 처음에는 설치 과정 : 필요한 개발 환경을 세팅

- 그 다음은 파이썬의 기본적인 개념들 : 자료형, 변수, 함수에 대해서 최대한 쉽게 알려드릴 건데요.

이것만 하고 나면 “프로그래밍 생각보다 별 거 아니네?” 하는 생각이 들 것입니다.

 

Topic 2. 프로그래밍 핵심 개념 in Python

이제부터 코딩이 왜 강력한 도구인지 알게 될 것입니다.

우리는 코딩을 왜 할까요? → 사람이 힘들어하는 것을 기계에게 대신 시키려고! [정밀 반복 계산, etc.]

프로그래밍의 세계는 넓고 깊지만, 결국 모두 몇 가지 핵심 개념에서 시작됩니다.

-'자료형'을 알면 데이터를 어떤 형태로 저장하고 활용하는지 이해할 수 있습니다.

-'추상화'를 알면 코드를 더 간결하고 근사하게 작성할 수 있습니다. 프로그래밍을 하나의 예술로 본다면,이게 바로 그 예술의 영역이라고 할 수 있죠.

-'제어문'을 알면 조건에 따라 동작을 나눌 수 있고, 반복적인 일을 처리할 수 있습니다. 컴퓨터를 반복적이고 어려운 일을 처리하는 똑똑한 비서로 활용할 수 있는 거죠.

이 토픽을 공부하고 나면, 세상에 많은 프로그램들이 대충 어떻게 돌아가는지 파악할 수 있습니다. 그리고 컴퓨터를 이용해서 어떤 문제를 해결하면 좋을지 아이디어가 마구 샘솟기 시작할 거라고 확신합니다.

 

Topic 3. 프로그래밍과 데이터 in Python

앞서 배운 정수형, 소수형, 문자열, 불린형 외에도 굉장히 많은 자료형이 있습니다. 그 중 가장 유용하게 사용할 수 있는 두 가지를 알려드리려고 합니다.

- 먼저 '리스트'라는 자료형이 있습니다.

리스트는 여러 값들을 하나로 묶어 주는 자료형입니다.

여러 값을 한꺼번에 다룰 수 있다는 장점이 있고, 여러 값을 원하는 순서대로 보관할 수 있다는 장점도 있습니다.

- 그 다음은 '사전'입니다. 사전도 리스트처럼 여러 값을 보관하는 자료형인데요.

순서대로 보관하는 것이 아니라, 마치 진짜 사전에서 단어를 찾듯이 값을 '검색'할 수 있다는 것이 특징입니다.

추가적으로 리스트, 사전, 문자열 등 파이썬 자료형의 비밀 몇 개를 알려드릴 건데요.

많은 분들이 잘 모르는 고급 정보니까 잘 배워 두시길 바랍니다!

 

Topic 4. Python 응용하기

프로그래밍 문법만 익히고 실제로 활용을 못하는 사람들이 대다수입니다. 원래 프로그래밍은 이론만 갖고 느는 게 아닌데 말이죠. 다양한 상황에 응용을 해 봐야 새로운 상황에 적용하는 능력이 생깁니다.

이 토픽에서는 파이썬을 이용해서 간단한 데이터 분석도 해 보고, 로또 시뮬레이션 프로그램이나 단어장 프로그램을 만들어 볼 것입니다. 그러면서 창의력과 응용력을 모두 기를 수 있습니다.

또한 그냥 기본 문법을 넘어서서, 파이썬을 더 확장성 있게 사용하기 시작할 건데요. 대표적으로는 새로운 모듈을 불러와서 쓰는 것과 유저에게 인풋을 받는 방법을 배워 볼 것입니다.


 

1. 추상화 Abstraction

⑴ 변수와 객체 [연결]

추상화 Abstraction & 참조 Reference

① 변수 → 객체:

[: Entity독립체(포괄적)Data데이터(컴퓨터)Object객체(추상물) ][: Identifier식별자≒Variable변수]👨🏻‍💻

[體]

Entity독립체(포괄적) : 다른 것에 기대지 않고 홀로 서 있는 형체나 상태

Data데이터(컴퓨터) : 프로그램 내 존재하는 표현 가능한 모든 독립체(entity)

Object객체(추상물) [넓은의미] 파이썬이 Data데이터추상화 한 것 ∴파이썬의 모든 것이 객체

          [좁은의미] Class가 정의한 type대로 만들어져 메모리주소를 할당받은 구체적 실체인 Instance

               * instance의 일반적 의미인 '사례'도 특정 논리 틀에 찍혀나온 '썰'

[名]

└ Name이름 : Names refer to objects

└ Identifier식별자 : Object's name - Programmer can access object by using identifier

Variable변수 : [넓은의미] 객체를 가리키는 식별자 : Name ≒ Identifier ≒ Variable

        ↳ 모든 변수는 함수/클래스 객체를 가리킬 수 있음

         ∴ 변수를 다른 이름의 함수객체와 연결하는 것이 시스템적으로 구현가능하긴 함

       [좁은의미] 가리키는 객체를 바꿀 수 있고, 함수, 클래스 객체가 아닌 객체를 가리키는 식별자

        ↳ 우리가 배운 일반적인 int, float, string, bool, list, tuple, dict, set, ··· 형 객체를 가리키는 식별자

         이 의미로 변수를 인식하는 것이 더 명확하고 실전적인 듯 - 왜냐고? 소통때문에

         Ex. 클래스 객체를 가리키는 변수가 있지만, 그걸 클래스 변수라고 하지 않음.

          그거보다 클래스가 가지는 변수가 더 소통에 필요하니 걔를 클래스 변수라고 하는 식

변수는 비교하는 대상(객체/상수/변수클래스)에 따라, 다른 의미(연결성/변화가능성/역할)가 강조된다

* 객체도 변수도 넓은 의미를 알고는 있되, 생각은 좁은 의미로 적재적소에 하기

 

* 잡생각

🌸

내가 그의 이름을 불러주기 전에는

그는 다만

일련의 0과 1에 지나지 않았다.

 

내가 그의 식별자를 불러주었을 때

그는 나에게로 와서

객체가 되었다.

- 🌸 추상'화' 🌸 -

아 암튼, 컴퓨터와 소통하는 유저는 [名]을 사용함으로써 컴퓨터 속 [體]에 접근가능하다라는 말이 당연한 말이라구

 

② Object의 성분:

[Data → (추상≒추출) → Object객체]의 추출물 ⊃ Identity Type Value

└ [주소] Identity : 메모리 내 주소

└ [] Type : 특정 객체들만이 가지는 특징으로 Type에 의해 객체의 동작 및 처리방식이 달라짐 ← 'Class'

└ [] Value : ㄹㅇ 값 ← Type이 해당 객체가 담을 수 있는 값 결정

* 주소, 형, 값은 객체 생성 후 바꿀 수 없음

* 넓은 의미의 객체를 생각하면, 이 모든 추출물들도 객체다.

* object[體] ← class[틀]: Class → Type 정의하고, 그 형에 맞는 객체를 만듦(instance)

 

③ 성분파악&비교작업:

* id( ) 함수 → Return [ 입력받은 객체의 Identity를 '정수'로 표현한 값 ]

* < is > 이항연산자 → Return [ 두 객체의 Identity가 같은지를 비교한 후 True or False ]

* < == > 이항연산자 → Return [ 두 객체의 Value가 같은지를 비교한 후 True or False ]

* type( ) 함수 → Return [ 입력받은 객체의 Type/Class]

 

⑵ 변수와 상수 [변화-반의]

변수와 상수의 차이점

Identifier ∋ { 변수, 상수 }

- 변수variable → object : 가리키는 객체가 변할 수 있음

- 상수CONSTANT → object : 가리키는 객체가 변할 수 없음 & 전부 대문자

  ↳ 이 둘의 차이를 인터프리터는 모름 → 강제성 없는 프로그래머들만의 룰  ∴ 모르고 바꾸지 않도록 주의해야 함

* 일상에서 변수/상수는 반의어 관계인데, 파이썬 시스템 상에서는 변수 '중에서'

 가리키는 객체를 바꿀 수 없도록 하고 싶을 때! 유저들끼리 대문자 표식으로써 정한 것이 상수

 

⑶ 변수와 함수&클래스 [📦역할-차원]

* Variable변수

[넓은의미] 객체를 가리키는 식별자 : Name ≒ Identifier ≒ Variable

 ↳ 모든 변수는 함수/클래스 객체를 가리킬 수 있음

  ∴ 변수를 다른 이름의 함수객체와 연결하는 것이 시스템적으로 구현가능하긴 함

[좁은의미] 가리키는 객체를 바꿀 수 있고, 함수, 클래스 객체가 아닌 객체를 가리키는 식별자

 ↳ 우리가 배운 일반적인 int, float, string, bool, list, tuple, dict, set, ··· 형 객체를 가리키는 식별자

  이 의미로 변수를 인식하는 것이 더 명확하고 실전적인 듯 - 왜냐고? 소통때문에...?

 

① 영역의 차이:

변수, 함수, 클래스의 영역구분 (넓은 의미의 변수 VS 좁은 의미의 변수일 때,)

[Name] Variable변수 ⊃⊅ Function함수 Class클래스

 ↳ [名] 함수, 클래스는 넓은 의미의 변수이다.

[Object] Object객체 ⊅ Variable변수

         ⊃⊅ Function함수 Class클래스

 ↳ [體] 변수는 '변수→객체'관계가 명확하다.

 ↳ [名 & 體] 함수/클래스는 이름과 객체 둘 다를 함수/클래스라 부른다.

   └ 추측이유? 해당 [함수名]이 해당 [함수객體]를 가리키는 것은 실전적으로 당연하니까(상수처럼),

        함수/클래스는 역할이 중요하지, 이름과 객체를 구분짓는 건 안 중요한 것 같다.

        변수는 해당 [변수]가 가리키는 [객체]가 '변'하는 것이 중요하지만!

 

② 역할의 차이:

변수, 함수, 클래스 간 역할의 차이

* [변] 가진

 [함] → 명령을 가졌고 + () 실행하는

 [클]   → 제조법을 가졌고 + () 제조하고 + . 제조한 애도 뭘 가진

 

③ 정의&사용 방식의 차이:

변수, 함수, 클래스 간 정의&사용방식의 차이

 

⑷ 변수의 사용범위 Scope

[Remark]

- Parameter ⊂ Local variable

- 전역변수[global] 함수영역(local) 사용가능하나 즉시변경X → global □

- 전역변수[global] & 지역변수[local] 동명이인이 존재할 수 있으나, 안 하는게 좋겠죠

 

⑸ Optional parameter

[예시] def name(a, b, c=1, d='a')

- Parameter : Local variable

- 必 Positional p. : 함수호출 시, 必 argument를 입력해야 함

- () Optional p. : 함수호출 시, argument를 입력 안하면 default값이 자동으로 파라미터에 할당됨

★ Optional은 무조건 Positional보다 에 있어야 함 ★

 

~ 1. 추상화 Abstraction 끝 ~

# [변수] with ①객체, ②상수, ③함수클래스, ④Scope, ⑤Optional parameter


 

2. 자료형 Datatype

[ 자료형 총정리 ] 분류 * 특징 * 활용

- Data type [python_docs][wiki]: 컴파일러나 인터프리터에게 알려주는 해당 object의 의미/특징

  이에 따라, 값을 저장하는 방식, 객체를 동작/처리(ex.연산, 형변환 등)하는 방식, 객체에 담을 수 있는 value가 달라진다.

  Class가 type을 정의할 수 있다.

  └ 자료형이 궁금한 경우 : type(■) → return <class 'name'>

  └ 형변환 Conversion : 워너비자료형(■) → return NEW obj(같은value 다른type) 외운다기보다

  └ Static & Dynamic typing : 언어분류기준 中 컴퓨터적 구조 명시必 or not

* 자료형을 잘 알면 전체 학습량의 50%을 습득한 셈이라고 하셨는데, 이제와서 보니 당연하다.

 '객체, 객체의 동작/처리방식'이라는 이 두루뭉실한 영역이 해당 언어의 전부같이 느껴진다.

 반대로, 자료형을 완벽하게 아는 건 그리 쉽지않다는 점에서 안도하게 된다.

 컴파일러쪽으로 갈 게 아니라면? 완벽히 알기보다, 잘 사용할 수 있으면 되는 것 같다.

그래, 자료형 공부하다 머리가 빠개지는 건 정상이야!

 

⑴ 내장-자료형 분류

- 자료형 분류기준 : ① 독방/Container ②값 변경시, 변수→객체 도킹스타일

 ① Limited number of items → This criterion is related to 'Iterable' & 'Container'

  └ 1obj(Container) ⊃ N item [Str List Tuple Dict Set ···]: 🎁 속 특정 item에 접근하기 위한 유일한 지표 필요

   유일한 지표 : Int_index(Str List Tuple), Key_index(Dict), 값 그 자체(Set) | 그래서, set빼고 인덱싱 가능

   Int/Key-index차이 : Int_index-순서대로, 자동으로 생성되는 정수형 지표 / Key_index-내맘대로 self생성

  └ Iterable: 인자로 🎁를 받으면 스스로 하나씩 꺼내쓰는 상황(for, zip(), map(), ···)의 🎁

 ② [changing whole VS some items] x [Mutable VS Immutable]

  └ Changing whole : [New Object in New memory address]도킹 ← variable

          ∴ [근본] variable의 도킹상태 💔'changed'

  └ Changing some items:

    1) Mutable : [New Object in New memory address]도킹 ← 前/後 기존 item들과 도킹

          ∴ [근본] variable의 도킹상태 ❤️'intact'

    2) Immutable : Mutable의 방식 불가

          ∴ 함수/메소드/연산자를 통해 whole change방식으로 전환하여 값을 수정해야함

[ 변수→객체 Binding 총정리 ] = x Alias/Copy x 값변경

[Remark]

- 나는 '도킹'이라고 했는데, Name → obj를 binding이라고 하는 것 같음.

 '도킹'이 뭔가 츼킹-츼킹 변신로봇같고 미래지향적이어서 더 쫚쫚 붙음............

- 자료형 분류 도식화를 두 번 했음. 배우는 과정 중에 / 코스 다 배우고서 재정리하는 맘으로 한번

 그래서 내용이 막 겹치는데, 각자의 단순/세심 매력이 있는 것 같아서(?) 안 지우고 냅둠

 

⑵ 형변환

형변환은 상식적으로

[Remark]

- float → int 반올림 아니고, 버림

- '1'→ int 가능 VS [1], {1} → int 불가

- '12.34' → int 직항 안 됨, 경유해야 함 : str"12.34" → float → int

- 인덱싱 → item형 / 슬라이싱 → 🎁type 형변환할 때 주의

- Container items 중복제거 → set형변환

- input()으로 받은 값은 무조건 str형이니까 필요하면 → 형변환

- dict는 형변환 할 때 key만

- 내장타입이 아닌 그냥 object도 형변환가능 → 따로 섹션(③)만들어서 설명

 

⑶ 그 외 자주보는 iterable

#range #zip #.items #file.txt

[공통점] 우리가 배운 내장타입은 아니지만, 배운 내장타입으로 형변환 가능

    print(★)해선 원하는 값이 안 나옴 : ① for a in ★ 하거나, ② 형변환(str제외) 필요

 

- ① range(시작a, 끝의 다음b, 공차d) : 첫 항a, 공차 d, b는 포함하지 않는 등차수열 객체

   * 공차가 - 인 감소형 등차수열의 경우에도 단순하게 a출발 b닿지않는 끝, 헷갈려하지말기

    ∵ 딱딱한 공식처럼 b를 끝+1이라고 생각하면 헷갈림

- ② zip(iterable한 여러obj) :

   '병렬적', item을 각각 객체별 하나씩 꺼내 tuple로 묶은 것을 item으로 가지는 객체

- ③ 사전객체.items/keys/values() :

   dict객체에서 key/value만 모은 객체 혹은 그 둘{key: val} 모두를 tuple(key, val)로 묶어 모은 객체

   * 2 arguments - zip(A, B) 한정 → dict 형변환 가능

- ④ txt파일객체 : txt파일의 한 줄을 반복의 단위로 하는 객체 → 추후, 입출력 정리에서 자세히 설명

 

~ 2. 자료형 Datatype 끝 ~

# [자료형] 中 내장형 분류: ① Container ② Mutable, 間 형변환, 中 자주보는 iterable형


 

3. String literals

⑴ Str. literal ⊂ literal ⊂ token

Literal ∋ String, Byte, Numeric

▶ 실재하는 token : 의미를 가지는 글자단위로써 file을 구성하는 조각 ∋ String literals

  실재하는 Literals : Notations(표기) for constant values of some built-in types.

▶ 추상화를 거쳐 실체화 된 object ∋ String type object

  ┕ String literalsString type object's value

 

⑵ 기본 형태와 포멧팅

String literals 의 모든 것 : 형식 & 포멧팅

- 기본 형태 : 통째로 [ ', ", 삼중', 삼중" ]에 감싸짐 → 그 덩어리가 string/bytes literals란 의미

String/Bytes literals can be enclosed in matching [', ", triple quotes]. → must가 아니라 can ?

- \ (backslash) : '덩어리' 內에서, 특정 문자(character)를 문자 그대로가 아닌(escape)

       → 해당 문자가 가진 특별한 기능을 발동시켜줌

- 문자열포멧팅 : 여러가지 객체, 변수들이 첨가된 '문자열String'을 만드는 일

      이 때, 객체나 변수들이 들어갈 위치 및 표현방식을 정할 수 있다.

      ① f '덩어리' 속, 변수를 담은 {치환필드}들 삽입 : {객체/위치/표현방식} 한큐처리

      ② '덩어리' 속, INDEX가 적힌 {치환필드}들 삽입.format(객체들) : 인덱스에 맞춰(객체들) → {위치/표현방식}

      ③ '덩어리' 속, %들 삽입 : 순서대로 (객체들) → % 위치/표현방식

 

~ 3. String literals 끝 ~

# [문자열 객체의 값 Value]  ① quote 포장   ② 다른 value들을 literal로 쓰는 법


 

4. 구문Statement & 식Expression

 문장은 ‘자신이 말하고자 하는 바’를 담은 최소완결체이다.

문장은 마음을 주고 받을 수 있는 소통의 단위이기때문에, 언어사용의 즐거움을 느낄 수 있는 시작점이다.

그래서, 언어는 문장단위로 배운다. 그 중요한 단어예문으로 익히는 것이 효과적이다.

 파이썬도 언어다.

Statement는 문장, 컴퓨터에게 명령하고 컴퓨터가 Execution하는 소통단위이다.

 

⑴ Token

File → Token

[ 실제 프로그램이 읽히는 과정 ]

1. A file is broken into tokens by 'lexical analyzer'.

2. A Python program that become the stream of tokens is read by a 'parser'

 * 실재하는 token : 의미를 가지는 글자단위로써 file을 구성하는 조각

 

[ Token 종류 ]

NEWLINE(논리적 줄 구분) INDENT & DEDENT(문장 간 수준 구분)

식별자(identifier) 키워드(keyword) 리터럴(literal) 연산자(operator) 구분자(delimiter)

Token 中 keyword : "cannot be used as ordinary identifiers"

Token 中 operator (연산자)

Token 中 delimiter (구분자)

* 출처:Python.org/3/reference/lexical_analysis.html

 

⑵ Expression 정의 & 종류

- Expression : → Obj

 └ Expression return Object : 식은 객체뱉음

 └ Statement에 사용할 수 있는 블럭 ← Expression

 └ Expression 구성요소 : Atom ∋{ identifiers, literals, enclosures } & Operator

 └ Identifiers Bound object : 식 中 식별자는 자신과 연결된 객체를 뱉음

 └ Literals Object whose value is the literals : 식 中 리터럴은 자신을 value로 갖는 객체를 뱉음

 └ Enclosures are forms enclosed in [{( ··· )}] Object : 식별자나 리터럴들이 괄호로 포장된 형태

 └ Operator Object whose value is the result of operations using Atoms : 연산결과를 value로 갖는 객체를 뱉음

 └  ∴ Operation ⊂ Expression

* Literals are notations for constant values of some built-in types.

 

* Arithmetic conversions <the numeric arguments are converted to a common type>

* 완전 모르겠어서 누락한 것 : 어웨이크, 일드, 람다

 

⑶ Statement 정의 & 종류

- Statement :

 └ 평서문, 의문문, 청유문···등의 실제문장형식처럼, 대입문, 반복문, 조건문···등의 형식이 존재하는 문장

 └ Statement ⊃ Simple(단순문:a single logical line) & Compound(복합문)

   └ Compound Statement ∋ one or more 'clause'(절)

   └ Clause 절 ∋ 'header머리 + suite덩어리'

     └ Header [컨트롤타워] → Keyword로 시작해서 :로 끝남

     └ Suite [실행부] → Header에 의해 제어되는 영역 : 같은 줄 or 개행 후, 동일한 들여쓰기 수준 정렬

Compound Statement

* 정리는 단순/복합을 떠나, 종속적이지 않은 단위로 정리

* 인터넷 검색으로 찾았지만 읽어도 무슨 말인지도 모르겠고, 아직 안 배운 것도 재낌

 

① Assignment ↔ Delete

할당 & 삭제 : Identifier - Object 간 연결 & 연결끊기

Assign 할당 - Name-Object Namespace BIND → =

Delete 제거 - Name-Object Namespace BIND 제거 → del

* 객체는 제거되지않음 → 어떤 것과도 bind 되어있지 않을 때, garbage collect될 뿐?

 

② Import module

▶ from □ import □ as □

Import문

[ 자주 사용하는 모듈 ] math, decimal, random, datetime, os

 

Standard library(표준라이브러리) : 파이썬 설치 시 딸려오는, 개발자들이 자주 쓰는 기능들을 담은 모듈의 모음

▶ [한글 설명서]

* Built-in : 함수/상수/타입/예외 → 우린 이미 Built-in 된 것들을 사용해왔음!

 

Module. math

Mathematical functions : This module provides access to the mathematical functions defined by the C standard.

math.log(진수x [,밑])

└ 1 argument, Return 자연로그값 (= ln x )

└ 2 arguments, Return 로그값 (= log밑 진수)

밑변환 log(x)/log(a) 연산을 하므로, 정확도가 떨어짐

math.log2(진수x)

└ 1 argument, Return 밑이 2인 로그값

usually more accurate than log(x, 2)

math.log10(진수x)

└ 1 argument, Return 상용로그값 (= log x)

usually more accurate than log(x, 10)

import math
# 함수 : log(진수[, 밑]) → return (float)지수
print(math.log(256, 4))             # 4.0
print(math.log2(256)/math.log2(4))  # 4.0 : log4(256) 밑변환 되네
print(math.log10(100))              # 2.0
print(math.log2(2**99))             # 99.0

math.sqrt(x)

└ 1 argument, Return the square root of x (=x의 양의 제곱근, 제곱근x)

import math
# 함수 : sqrt(x) → 제곱근x (float)
print(math.sqrt(1024))            # 32.0
print(type(math.sqrt(4)))         # <class 'float'>

math.sin(x)

└ 1 argument, Return the sine of x radians

math.cos(x)

└ 1 argument, Return the cosine of x radians

math.tan(x)

└ 1 argument, Return the tangent of x radians

import math
# 함수 : sin/cos/tan(rad) → float
print(math.sin(0))                # 0.0
print(math.cos(math.pi))          # -1.0 : 코사인180도
print(math.tan(math.pi*(1/4)))    # 0.9999999999999999 : 원래는 1인데

math.pi

└ Constant 파이(π)-The mathematical constant π = 3.141592…, to available precision.

math.e

└ Constant 자연상수e-The mathematical constant e = 2.718281…, to available precision.

import math
# 상수 : 파이 ∏, 자연상수 e → (float)
print(math.e)   # 2.718281828459045
print(math.pi)  # 3.141592653589793
print(type(math.e), type(math.pi))  # <class 'float'> <class 'float'>

 

Module. random

Generate pseudo-random numbers - Almost all module functions depend on the basic function random(), which generates a random float uniformly in the semi-open range [0.0, 1.0)

[실수] Real-valued distributions

random.random()

└ 0 argument, Return the next random floating point number [0.0, 1.0) = 0.0 ≤ N < 1.0

import random   # 랜덤한 숫자를 생성하기 위한 다양한 함수들을 담은 module
# 1. random() → return 0.0 ≤ ■ < 1.0인 랜덤한 float 객체
print(type(random.random()))     # <class 'float'>
print(random.random())           # 0.2623734691109664
print(f"{random.random():.2f}")  # 0.71

random.uniform(a, b)

└ 2 argument, Return a random floating point number (a ≤ N ≤<b for a ≤ b, and b ≤ N ≤<a  for b < a)

└ 끝 값을 범위에 포함시킬지의 여부a+(b-a)*random()방정식에 따른 부동소숫점반올림에 의해 결정됨

import random   # 랜덤한 숫자를 생성하기 위한 다양한 함수들을 담은 module
# 2. uniform(a, b) → return a ≤ ■ ≤ b인 랜덤한 float 객체
print(type(random.uniform(-10, 10)))    # <class 'float'>
print(random.uniform(-10, 10))          # 7.090006906596596
print(f"{random.uniform(-10, 10):.2f}") # -7.15

[정수] for integers

random.randint(a, b)

└ 2 arguments, Return a random integer N (a ≤ N ≤ b)

import random   # 랜덤한 숫자를 생성하기 위한 다양한 함수들을 담은 module
# 3. randint(a, b) → return a ≤ ■ ≤ b인 랜덤한 int 객체
print(type(random.randint(-100, 100)))  # <class 'int'>
print(random.randint(-100, 100))        # -91
print(random.randint(-100, 100))        # 17

 

Module. decimal

support for fast correctly-rounded decimal floating point arithmetic-float형보다 더 빠르고 정확한 십진수 부동소수점 산술을 지원함

[클래스-객체의 type을 정의하고(어트리뷰트:변수/상수/함수=메소드), 해당 클래스의 객체(인스턴스)를 생성할 수 있음]

decimal.Decimal(■=str···)

└ 1 arguments, 값이 ■인 decimal.Decimal클래스의 인스턴스(객체)를 생성

└ 메소드 : 해당객체.quantize(exp, rounding=None, context=None)

  └ Return quantize(정량화)시킨 새 Decimal 객체-rounds a number to a fixed exponent (원하는 소숫점자리까지 Round it)

  └ 1st argument-exp : exponent(지수)-소수점의 위치 / Decimal형 객체입력-해당 객체의 소수점자리까지

  └ (2nd argument-rounding) : round방식설정1순위 / rounding=■ & 없는 경우, context의 rounding값 / 예 : rounding=ROUND_UP

  └ (3rd argument-context) : round방식설정2순위 / 없는 경우, current context의 설정 값

import decimal
# 반올림한 새로운 객체생성
print(decimal.getcontext().rounding)            # ROUND_HALF_UP : 일반 반올림
a = decimal.Decimal('123.456789')
print(a.quantize(decimal.Decimal('1.')))        # 123 : current context 대로
print(a.quantize(decimal.Decimal('.1'), rounding='ROUND_UP'))       # 123.5 : 올림
print(a.quantize(decimal.Decimal('.01'), rounding='ROUND_DOWN'))    # 123.45 : 내림
print(a.quantize(decimal.Decimal('.001')))      # 123.457 : current context 대로

decimal.getcontext()

└ 역할 : 현재 설정 확인 및 변경 → 자세한 설명서

└ 0 arguments, Return 현재 상황이 담긴 객체-the current context for the active thread

└ print(■)→ Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])

└ 변경방법 : 해당객체.변경항목 = 변경값

 └ 변경값 : rounding = 'ROUND_HALF_UP'반올림/'ROUND_UP'올림/'ROUND_DOWN'내림/'ROUND_HALF_EVEN'(.5 → 짝수), etc.

import decimal
a = decimal.getcontext()    	# Alias - 간편?
print(a)    # 설정확인 : Context(prec=28, rounding=ROUND_HALF_EVEN, Emin= ···)
print(type(a.rounding))         # <class 'str'>
a.rounding = 'ROUND_HALF_UP'    # 반올림으로 설정변경 & str형으로 입력해야함
# round() VS Decimal형 객체.quantize()
print(round(13.5))  # 14 : ROUND_HALF_EVEN방식→올림 : 반올림인데,
print(round(13.4))  # 13 : ROUND_HALF_EVEN방식→버림 : 0.5인 경우는 (반)
print(round(12.5))  # 12 : ROUND_HALF_EVEN방식→버림★: 결과가 짝수이도록 올/내리는 방식

import decimal
a = decimal.Decimal('13.5')  # Decimal클래스의 객체(instance)생성
b = decimal.Decimal('12.5')  # 인수는 int/float/str/tuple형 다 되는데, str 추천
print(type(a))               # <class 'decimal.Decimal'>

print(decimal.getcontext().rounding)    # 현 설정 : ROUND_HALF_EVEN
c = a.quantize(decimal.Decimal('1.'))   # 현 설정대로 rounding한 새로운 객체
d = b.quantize(decimal.Decimal('1.'))   # 현 설정대로 rounding한 새로운 객체
print(c)        # 14 ← 13.5
print(d)        # 12 ← 12.5 ★

decimal.getcontext().rounding = 'ROUND_HALF_UP'     # 설정변경 : 일반 반올림
c = a.quantize(c)   # c의 소숫점자리대로 + 현 설정대로 rounding한 새로운 객체
d = b.quantize(d)   # d의 소숫점자리대로 + 현 설정대로 rounding한 새로운 객체
print(c)        # 14 ← 13.5
print(d)        # 13 ← 12.5 ★

Module. os

This module provides a portable way(이식가능한 방법) of using operating system dependent functionality(운영체제에 종속된 기능).

os.getlogin()

└ Return (str) 현 프로세스의 제어 터미널에 로그인한 사용자 '이름'-the name of the user logged in on the controlling terminal of the process.

os.getcwd()

└ Return (str) 현 작업 디렉토리-a string representing the current working directory.

import os       # 운영체제를 조작하기위한 모듈
# getlogin() → 현재 로그인 되어있는 계정
print(os.getlogin())    # 계정명 출력
# 현재 파일이 있는 경로 출력
print(os.getcwd())      # C:\ 블라블라 출력
print(type(os.getlogin()), type(os.getcwd()))   # <class 'str'> <class 'str'>

 

Module. datetime

날짜와 시간을 다룰 수 있는 클래스 & 산술 - This module supplies classes for manipulating dates and times.

+ Aware objects-can locate itself relative to others, represent a specific moment in time without interpretation.

+ Naive objects-up to the program, easy to understand and work with.

[클래스-객체의 type을 정의하고(어트리뷰트:변수/상수/함수=메소드), 해당 클래스의 객체(인스턴스)를 생성할 수 있음]

[* Object of these type is immutable]

datetime.date(year, month, day : int형)

└ 날짜(연, 월, 일)만 다루는 객체를 정의하는 클래스

└ 3 arguments, 해당 값들을 attribute로 가진 datetime.date클래스의 인스턴스(객체) 생성

└ 클래스 메소드 : date.today()

  └ Return 현재 날짜값들을 attribute로 가진 datetime.date클래스의 인스턴스(객체)

└ 인스턴스 메소드 : 특정객체.replace(year=self.year, month=self.month, day=self.day)

  └ Return 해당 객체의 특정 attribute를 바꾼 새로운 datetime.date클래스의 인스턴스(객체)

└ 인스턴스 메소드 : 특정객체.strftime(format="···")

  └ Return 해당 객체의 날짜관련attribute를 명시한 포맷에 맞춘 문자열(string from time)

datetime.time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

└ 시간(시, 분, 초, ···)만 다루는 객체를 정의하는 클래스

└ All optional arguments, 해당 값들을 attribute로 가진 datetime.time클래스의 인스턴스(객체) 생성

└ 인스턴스 메소드 : 특정객체.replace(hour=self.hour, minute=self.minute, second=self.sec···)

  └ Return 해당 객체의 특정 attribute를 바꾼 새로운 datetime.time클래스의 인스턴스(객체)

└ 인스턴스 메소드 : 특정객체.strftime(format="···")

  └ Return 해당 객체의 시간관련attribute를 명시한 포맷에 맞춘 문자열(string from time)

datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)

└ 날짜와 시간을 모두를 다루는 객체를 정의하는 클래스

└ 3↑ arguments, 해당 값들을 attribute로 가진 datetime.datetime클래스의 인스턴스(객체)를 생성

└ 클래스 메소드 : datetime.now(tz=None)

  └ Return 현재 날짜와 시간을 attribute로 가진 datetime.datetime클래스의 인스턴스(객체)

└ 클래스 메소드 : datetime.combine(date, time, tzinfo=self.tzinfo)

  └ Return 입력한 date객체와 time객체의 각 attribute값을 결합한 datetime.datetime클래스의 인스턴스(객체)

└ 인스턴스 메소드 : 특정객체.strftime(format="···")

  └ Return 해당 객체의 날짜시간관련attribute를 명시한 포맷에 맞춘 문자열(string from time)

  * 포맷코드 : 연%Y,y 월%B,b,m 일%d 요일%A,a,w 오전오후%p 시%H(24h),I(12h) 분%M 초%S

  └  Appropriate representation : %c → Tue Aug 16 21:30:00 1988  %x → 08/16/88  %X→21:30:00

  └ * 메소드 사용하지않고, 문자열포멧팅 "문자와 포멧코드".format(시간관련 인스턴스)로 하는 것도 괜찮은데...

import datetime

now = datetime.datetime.now()     # 현재 연월일시분초를 담은 datetime.datetime 인스턴스

print("Today is " + now.strftime("%A(%B %dth)"))        # Today is Thursday(June 10th)
print("Today is {0:%A}({0:%B} {0:%d}th)".format(now))   # Today is Thursday(June 10th)
print(now.strftime("%c"))   # Thu Jun 10 15:40:40 2021 = 요일 월 일 시:분:초 연
print(now.strftime("%x"))   # 06/10/21  = 월/일/연
print(now.strftime("%X"))   # 15:40:40  = 시:분:초

└ 지원하는 연산 : datetime = datetime ± timedelta

└ 지원하는 연산 : timedelta = datetime - datetime

datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0:int, float, +, -)

└ 두 객체(date, time, datetime클래스)의 차이기간을 의미하는 객체(인스턴스)를 다루는 클래스

└ All optional arguments, 해당 값들을 attribute로 가진 datetime.timedelta클래스의 인스턴스(객체) 생성

└ 지원하는 연산 : datetime = datetime ± timedelta

└ 지원하는 연산 : timedelta = datetime - datetime

import datetime

# .datetime(연, 월, 일, 시, 분, 초)
print(type(datetime.datetime(2021, 5, 28))) # <class 'datetime.datetime'>
print(datetime.datetime(2021, 5, 28))       # 2021-05-28 00:00:00
print(datetime.datetime(2021, 5, 28, 15, 28, 9))    # 2021-05-28 15:28:09

# 객체의 attribute :
today = datetime.datetime.now()
print(type(today.year))         # <class 'int'>
print(today.year)               # 2021
print(type(today.microsecond))  # <class 'int'>
print(today.microsecond)        # 543286

# 객체의 method : .datetime.now() → return 현재
print(type(datetime.datetime.now()))        # <class 'datetime.datetime'>
print(datetime.datetime.now())              # 2021-05-28 15:29:08.860917 : 시간단위
first_delta = datetime.timedelta(
	days=48,
	seconds=16,
	microseconds=10,
	milliseconds=19000,
	minutes=1,
	hours=2,
	weeks=3
    )
  second_delta = datetime.timedelta(weeks=1, hours=3, minutes=4, seconds=5)

  # datetime객체끼리 빼기 → 시간차를 나타내는 timedelta객체
  dday = datetime.datetime(2021, 6, 1)
  today = datetime.datetime.now()
  print(type(dday - today))               # class 'datetime.timedelta' 시간차
  print(dday - today)                     # 3 days, 8:28:28.426436

  # datetime객체+-timedelta객체 → datetime객체
  print(datetime.datetime.now())                  # 2021-05-28 15:44:54.264421
  print(type(datetime.datetime.now() + second_delta))   # class 'datetime.datetime'

  # 설정하지 않은 항목은, default to 0

 

③ 다른 영역의 변수 사용

▶ 전역변수 : global

▶ 둘러싼 지역의 변수 : nonlocal

▶ 변수목록(Namespace) : locals()

 

포함관계도 아닌 완전 다른 local의 변수는 참조불가

 

locals( ) → 해당 영역에 존재하는 { NAME : 값 } 목룍

 

④ Pass

pass

아무 일도 일어나지 않음 NULL → SUITE를 빈칸으로 두고 싶을 때, 사용

 

⑤ 함수/클래스 정의

함수, 클래스 정의문

def 함수명(parameters):SUITE

class 클래스명():SUITE

 

⑥ 조건부실행

if:

if-elif-else 문

<조건식ⓒ> 순차적 연산 : <조건식ⓒ<의 결과값이 True인 경우 → 해당 SUITE 실행 & 구문종료

if <ⓒ> : SUITE

elif <ⓒ> : SUITE  ··· 생략가능 & 여러 개 OK

else : SUITE  ··· 생략가능 & only one

 

⑥ 반복

while , for:

+ continue : 현 Loop cycle 즉각 중단 & 다음 Loop cycle 실행

+ break : 현 Loop cycle 즉각 중단 & 탈출

  * finally절이 있는 경우, loop 탈출 전 실행 함

while 과 for

while <ⓒ> : SUITE  ··· <조건ⓒ>가 True인 동안, SUITE 반복

else : SUITE     ··· (생략가능: <조건ⓒ>가 False일 때, SUITE실행) & Loop out

 

forin 🎁 :   ··· 🎁 속 item 하나하나씩 꺼내서 → □ 담기 & SUITE 실행 

else : SUITE     ··· (생략가능: 모든 🎁의 item 소진 시, SUITE실행) & Loop out

 

⑦ 예외처리

try : - exceptas □: else :- finally :

예외처리문

try : SUITE         ··· SUITE 실행 → Err발생?-① or 정상?-②

except as : SUITE     ··· ① try절 SUITE가 ⓐ라는 에러를 일으키는 경우, SUITE 실행 + 여러 절 OK

else :           ··· ② try절 SUITE가 에러를 일으키지 않는 경우, SUITE 실행 (생략가능)

finally : SUITE        ··· try절이 에러를 일으켰든 말든 마지막으로 무조건 실행 (생략가능)

 

⑧ 컨텍스트 자동종료

with EXPRESSION as TARGET:
	SUITE

with open('폴더명/파일명', 'r=읽기 or w=쓰기', 'encoding=인코딩방식') as 결과물명:
	SUITE

[기존-불편] open(□)으로 파일을 여는 경우, △.close()로 수동으로 닫아줘야 함

[해결-편함] with open(□)··· :SUITE  - with문이 끝날 때, 자동으로 닫음

 

⑷ 식 VS 구문

Expression vs Statement

[식:준비] Expression  #Auto Return object     #퍼즐조각

[문:실행계획] Statement  #No return responsibility #퍼즐판   

 

KEY POINT → Is it automatically return a value?

 🟢 Expression → so 'expression' need follow-up executable procedure.

     → 식은 자동으로 뭔가를 반환하기때문에, 그 반환물을 사용하는 후속절차 필요

 ❌ Statement → so if you want to execute return, use 'return'keyword to make 'return statement'.

     → Statement는 특정한 문장(=return문)을 사용하지 않는 이상, 자동으로 반환하지 않음

 

- Assignment Expression :=  vs Statement =

 └ Expression := 할당 및 반환

 └ Statement = 할당

print(a = 3)    # Err   = statement
print(a := 3)   # 3     := operator → print(할당 및 반환)
print(a += 1)   # Err   += statement
print(a + 1)    # 4     + operator  → print(연산 및 반환)

* 거창하게 단어 VS 구문으로 비유를 하긴했지만, 실질적으로 반환하냐/마냐 차이...

* 그래도, Expression과 statement구분에 너무 집착하지 않아도 될 이유?

  → 언어마다 쬠 달라서?'C define the = operator as an expression, rather than a statement as is Python's way.'

 

 참고:

Stackoverflow - Does anyone have a good definition of expressions and statements and what the differences are?

PEB572 - Differences between assignment expressions and assignment statements

클리앙 - [현프-1] 표현식, 표현식 문, 그리고 표현식 문 기반 언어

 

~ 4. 구문Statement & 식Expression 끝 ~

# [구문→문장] # [식→단어] : 정의/분류 & 차이


 

5. 입력/출력

⑴ 사용자 입력

- Function : input('■')

1. [출력] '■' 인자(string type) 콘솔 출력 : 입력을 안내하는 용도로 사용

2. [인풋] 사용자로부터 입력받기 - 사용자는 입력 후 Enter

3. [리턴] return (str) 입력받은 값을 value로 하는 str형 객체

+ Function 전체종료 : exit()

 

⑵ 콘솔 출력

- Function : print(expression)

≠ return : Keyword → Object - 반환문의 키워드일 뿐, 콘솔과 관련없음

 

~ 5. 입력/출력 끝 ~

# [입력] input('str') & # [출력] print(···)


 

6. 읽기/쓰기

with open('폴더명/파일명', 'r=읽기 or w=쓰기', 'encoding=인코딩방식') as 결과물명:
	SUITE

[안은문장] with EXPRESSION as TARGET:

 [안긴문장] open(file, mode='r', buffering=-1, encoding=None, ···)  *kor설명

 └ return, 파일과 상응하는 객체:Open file and → return a corresponding file object(=file-like objects, streams)

 └ ① file : 열려는 파일의 주소(path-like object) → 예:같은 폴더-'파일명.종류' 다른 폴더-'폴더명/파일명.종류'

 └ ② mode : 해당 파일을 여는 방식 - 기본모드 'r' & 't'

[mode 설명] * 출처: https://docs.python.org/3/library/functions.html#open & https://twpower.github.io/17-with-usage-in-python

 └ ④ encoding : 텍스트 모드('t')가 들어가는 경우, 파일을 인코딩/디코딩하는 방식 - 기본값 'ASCII' → 자주 쓰는 값'UTF-8'

 └ 관련함수 : 특정객체.read()

  └ Return (str) 해당 객체의 내용 전체를 변환한 문자열-읽은 영역 휘발

with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    print(txt.read())
    """
        1일: 815400
        2일: 798000
        3일: 269200
             :
    """
    print(type(txt.read()))  # <class 'str'> : 다 읽고 남은 ''을 확인한 것
# 두 명령을 바꾸면, 아무것도 출력되지않음 → type 확인할 때, 다 읽고 휘발되어서

 └ 관련함수 : 특정객체.readline()

  └ Return (str) 해당 객체를 한 줄씩을 변환한 문자열-읽은 영역 휘발

with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    print(type(txt.readline()))  # <class 'str'> : '1일: 815400\n' 확인
    print(txt.readline())        # 2일: 798000\n
    print(txt.readline())        # 3일: 269200\n

 └ 관련함수 : 특정객체.readlines()

  └ Return (list) 해당 객체의 한줄한줄을 각각의 item으로 한 리스트-읽은 영역 휘발

with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    print(txt.readlines())        # ['1일: 815400\n', '2일: 798000\n', '3일: ···]
    print(type(txt.readlines()))  # <class 'list'> : list=[] 확인
# 두 명령을 바꾸면, txt.readlines() → list=[] 왜냐하면, type확인할 때 다 읽고 휘발됨

- 읽는 용도로 wrap된 객체를 사용하면, 사용한 줄만 휘발되는 것이 신기했다 → .readline()의 존재의의가 느껴짐

 

⑴ 파일읽기 → open('mode=r')

- 1. 읽기에 필요한 '치킨집 매출.txt' 만들어보기

# [치킨집 매출 리스트 만들기]
import random

for i in range(1, 31, 1):
    print(f"{i}일: {random.randint(1000,9999)*100}")

- 2. 읽는 용도로 wrap된 객체, 콘솔에 출력하기

└ [문제] 개행(enter, \n)의 중복 : 문서 자체의 개행뿐만 아니라 print()도 개행을 하는 바람에 두 줄 띄어짐

# 1. 그냥 print :
with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    for line in txt:         # 한 줄 : "문자열1··\n"
        print(line)          # + print의 개행
"""
1일: 815400

2일: 798000

3일: ···
"""

└ [해결1.] 문서 자체의 개행 제거 → 문자열.rstrip() : "", "\n", "\t"같은 모든 공백(whitespace)제거

# 2. 문자열.공백제거() - 공백 中 우측만 제거
with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    for line in txt:		  # 한 줄 : "문자열1··\n"
        print(line.rstrip())  # 오른쪽 공백제거
"""
1일: 815400
2일: 798000
3일: ···
"""

└ [해결2.] print()의 개행 제거 → end=""

# 3. print 개행 무시 :
with open('data/chicken.txt', 'r', encoding='UTF-8') as txt:
    for line in txt:		 # 한 줄 : "문자열1··\n"
        print(line, end="")  # print()의 공백제거
"""
1일: 815400
2일: 798000
3일: ···
"""

사용한 것 정리+α

문자열.lstrip/rstrip/strip()

왼쪽/오른쪽/양쪽에 존재하는 whitespace( "", "\n", "\t")를 제거해주는 메소드

└ Return, (str) 해당 문자열의 공백을 제거한 새로운 문자열

문자열.split('□')

해당 문자열을 □을 기준으로 나눈 후, 각각을 item으로 하는 리스트를 생성하는 메소드

└ 0 argument Return, (list) 해당 문자열을 모든 종류의 공백을 기준으로 나눈 리스트

└ 1 argument Return, (list) 해당 문자열을 □을 기준으로 나눈 리스트

my_string = "1, 2, 3"           # 숫자 + 컴마 + 공백
print(my_string.split(","))     # 컴마로 나눔 → item = 숫자 / 공백 + 숫자
# ['1', ' 2', ' 3']
print(my_string.split(", "))    # 컴마 + 공백 으로 나눔 → item = 숫자
# ['1', '2', '3']

full_name = "Kim, Yuna"
print(full_name.split(","))         # ['Kim', ' Yuna']
print(full_name.split(", "))        # ['Kim', 'Yuna']
name_data = full_name.split(", ")
print(name_data[1], name_data[0])   # Yuna Kim

white_space = "  \n\n  1  \t  2  \n  3 4 5  \n\n"     # whitespace의 향연
list1 = white_space.split()         # 인자를 넘겨주지않으면, 모든 공백기반으로 나눔
# ['1', '2', '3', '4', '5']
print(list1[0] + list1[4])              # 211   → items = 숫자모양의 문자str
print(int(list1[0]) + int(list1[4]))    # 6     → 형변환 int(■)

end="□"

└ print(■)에 사용할 수 있는 인자 : print()의 개행을 하지말고, □를 붙일 것

 

⑵ 파일쓰기 → open(mode='w').write()

wrap된객체.write('ㅁ')

해당 객체에 입력받은 값을 기록해주는 메소드

- 손수 개행('\n')을 해주어야 함

- 기존 파일에 덧붙이고 싶은 경우, open('mode=a').write → append(덧붙임, 첨부)

 

~ 6. 읽기/쓰기 끝 ~

# [읽기, 쓰기w] for □ in ★에 사용 .read() 전체 .readline() 한줄씩 .readlines() 리스트


 

7. Style guide:PEP8

PEP8 Style Guide for Python Code

[ A Foolish Consistency is the Hobgoblin of Little Minds : 융통성을 가지자 ]

- 가독성은 중요하고 가이드라인은 가독성을 강화하기위해 만들어졌지만, 그렇지 않을 때도 있고 되려 상황을 악화시킬 때도 있다.

- 그러니, 상황에 맞게 최선의 판단을 하기 !

 

⑴ 들여쓰기

- 들여쓰기 수준의 단위, 4 spaces = 1 tab

- 들여쓰는/내어쓰는 이유 → 의미의 연속 : ① Header-Suite [하나의 구문] ② [하나의 logical line]이지만, 물리적으론 긴 경우

 └ ② 한 줄 당, '약 79자' = 물리적 한계 → 하나의 logical line을 형성하나, 물리적으로 너무 길면 개행 & 들여쓰기

 └ 구분자(delimiters: 괄호, 따옴표, 쉼표 등), 연산자 단위로 개행 : Opening 구분자/쉼표/이항연산자 개행 

 └ 그냥 개행 + 들여쓰면 안되는 경우, backspace(\) 필요 : \ + 개행 + 들여쓰기

# Opening 구분자 개행 - 4칸 들여쓰기
foo = long_function_name(
    var_one, var_two,
    var_three, var_four)
    
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    
my_list = [
    1, 2, 3,
    4, 5, 6
    ]
    
my_list = [
    1, 2, 3,
    4, 5, 6
]
# Opening 구분자 개행 - an extra level of indentation

# ♥ Correct:
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

if (this_is_one_thing
        and that_is_another_thing):
    do_something()
    
# ▼ Wrong: Header를 평소처럼 4칸 개행하면, Suite절과 구분이 안 감
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)
# 쉼표 개행

# ♥ Correct: 여는 구분자 '(' 와 vertical 개행수준 맞추기
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# ▼ Wrong: 단순하게 4칸 들여쓰면, 첫 줄의 함수 인자들이 눈에 안 띄어서 가독성 저하
foo = long_function_name(var_one, var_two,
    var_three, var_four)
# 이항연산자 개행
# ♥ Correct: 이항연산자를 시작으로 하는 vertical 정렬
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

# ▼ Wrong: 연산자와 엮인 두 항의 관계가 눈에 잘 띄지 않음 = 가독성 저하
income = (gross_wages +
          taxable_interest +
          (dividends - qualified_dividends) -
          ira_deduction -
          student_loan_interest)
# Docstring의 개행 : 마지막 줄엔 닫는 따옴표만 존재
def foo():
    """A multi-line
    docstring.
    """

def bar():
    """
    A multi-line
    docstring.
    """
# 그냥 개행 + 들여쓰기하면 안 됨 → \ 사용
with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

 

⑵ import

- 위치 : [파일 최상단] 주석 및 docstrings - import - global variables/constants

- import는 하나 당 한 줄, from으로 묶으면 여러 개 한 줄

- Standard library / third party / local application/library로 그룹화 가능 → 그룹은 '빈 줄'로 구분

# ♥ Correct:
import os
import sys

from subprocess import Popen, PIPE

# ▼ Wrong:
import sys, os

 

⑶ 공백:whitespace

- 괄호 전/후 공백 無

- comma(,) semicolon(;) colon(:) 후 공백

  └ ★ comma(,) semicolon(;) colon(:) 다음이 바로 괄호이면, 후 공백 삭제

  └ ★ Slicing의 colon(:)은 이항연산자처럼 작동, 전/후 공백 or 전/후 공백 無

- 이항연산자 전/후 공백 + 연산순위에 따른 공백삭제OK

- = 전/후 공백 + ★ keyword or optional parameter지정의 경우, 전/후 공백 無

- 하나의 절, 문은 한 줄에 쓸 수 있더라도 개행 분리 必

# 괄호 전/후 공백無

# ♥ Correct:
spam(ham[1], {eggs: 2})
spam(1)
dct['key'] = lst[index]
foo = (0,)

# ▼ Wrong:
spam( ham[ 1 ], { eggs: 2 } )
spam (1)
dct ['key'] = lst [index]
foo = (0, )
# , ; : 후 공백 & 이항연산자 전/후 공백
# ♥ Correct:
x = 1
y = 2
long_variable = 3

if x == 4: print x, y; x, y = y, x

# ▼ Wrong:
x             = 1
y             = 2
long_variable = 3

if x == 4 : print x , y ; x , y = y , x
# Slicing에 쓰이는 : 전/후 공백 or 양쪽 공백 無 
# ♥ Correct:
ham[1:9], ham[1:9:3], ham[:9:3], ham[1::3], ham[1:9:]
ham[lower:upper], ham[lower:upper:], ham[lower::step]
ham[lower+offset : upper+offset]
ham[: upper_fn(x) : step_fn(x)], ham[:: step_fn(x)]
ham[lower + offset : upper + offset]

# ▼ Wrong:
ham[lower + offset:upper + offset]
ham[1: 9], ham[1 :9], ham[1:9 :3]
ham[lower : : upper]
ham[ : upper]
# 이항연산자 전/후 공백이지만, 연산先순위에 의한 공백삭제OK
# ♥ Correct:
i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)

# ▼ Wrong:
i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
# = sign이 keyword argument나 optional parameter을 만드는 경우, 양쪽 공백 無
# ♥ Correct:
def complex(real, imag=0.0):
    return magic(r=real, i=imag)
  
# ▼ Wrong:
def complex(real, imag = 0.0):
    return magic(r = real, i = imag)
# 하나의 절, 문은 전부 개행으로 분리
# ♥ Correct:
if foo == 'blah':
    do_blah_thing()
    
do_one()
do_two()
do_three()

# ▼ Wrong:
if foo == 'blah': do_blah_thing()

do_one(); do_two(); do_three()

for x in lst: total += x

while t < 10: t = delay()

try: something()
finally: cleanup()

do_one(); do_two(); do_three(long, argument,
                             list, like, this)

if foo == 'blah': one(); two(); three()

 

⑷ 주석

- 코드 수정에 따라 꾸준히 업데이트 할 것

- Inline 주석은 가독성을 해치므로 코드만 읽어도 알만한 obvious한 첨언은 지양하고, 도움되는 속뜻은 OK

 

⑸ 프로그래밍 상 추천

- ··· is not ··· 추천, not ··· is 보다

- try절:최대한 minimum하게, except절:err 명확하게 짚어주기, finally절: flow control문(return, continue, break)X

- string method가 더 빠름, module보다

- True, False와의 == 비교 X

  └ if x == True: → if x:

~ 7. Style guide 끝 ~


 

반응형

블로그의 정보

노력하는 실버티어

노실언니

활동하기