- @참고(NodeJs + Express 로 웹서버 구축하기): https://velog.io/@goody/NodeJs-Express-%EB%A1%9C-%EC%9B%B9%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0

 

1. NPM Project 시작하기

> npm init

2. NPM Projectdp express 의존성 추가하기

> npm install express --save //package.json에 해당 내용 save

3. Express 기반 웹서버 구동

- app.js 파일을 생성

// node_modules 에 있는 express 관련 파일을 가져온다.
var express = require('express')

// express 는 함수이므로, 반환값을 변수에 저장한다.
var app = express()

// 3000 포트로 서버 오픈
app.listen(3000, function() {
    console.log("start! express server on port 3000")
})

> node app.js

(Optional) 4. 서버의 변경을 감지해 재시작 해주는 nodemon 설치

> npm install nodemon -g //컴퓨터 전체에 global install

> nodemon app.js

window11 환경에서 위 명령어로 실행시

'nodemon'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.

라고 하여 아래와 같은 방식으로 package.json에 추가해주었다.

> npm install nodemon --save-dev

- package.json 에 추가

...
"scripts": {
   ...,
    "app": "nodemon ./app.js"
  },
...

> npm run app

5. URL Routing 처리

- app.js

// request 와 response 라는 인자를 줘서 콜백 함수를 만든다.
// localhost:3000 브라우저에 res.send() 내부의 문자열이 띄워진다.

app.get('/', function(req,res) {
    res.send("<h1>hi friend!</h1>")
})

- http://localhost:3000 접속

블로그 이미지

uchacha

개발자 일지

,

- @참고: https://zzsza.github.io/development/2020/07/19/opensource-analysis/

1. 큰틀 아키텍쳐를 살핀다.
- 기능의 흐름을 살핀다.
2. 메소드와 클래스를 살핀다.
- 메소드를 reuse 할 때도 도움됨

- @참고: https://coderlife.tistory.com/137
0. 문서를 살핀다. 목적, 어떻게 사용하는지..
- 해당 솔루션에 대한 기본 지식을 먼저 익히기
1. 일단 실행시킨다.
2. 코드를 본다.
- 나라면 어떻게 개발했을까 질문 던지기
- 분석하며 문서로 정리한다.
3. 문서를 보고 코드와 매칭시킨다.

- @참고: https://www.youtube.com/watch?v=h1Qj7LEIVVQ&t=35s
1. 코드를 보는 눈을 키운다.
- 프린트를 해서 코드의 흐름을 컴파일해라..
- 오픈소스 많이 보기

블로그 이미지

uchacha

개발자 일지

,

- @참고1(not working): https://kwebtoon.tistory.com/38

- @참고2: https://stackoverflow.com/questions/36329068/bouncycastle-error-jce-cannot-authenticate-the-provider-bc-with-jar-with-depe

 

원인

참고2 에 따르면 Bouncycastle 은 서명되어있어야 하기 때문에, fat jar 로 묶어버리면 서명검증을 할 수 없어서 안되는 것 같다.

 

해결

따라서 해결책으로 maven-shade-plugin으로 별개로 가져가도록 해결하는 것 같다.

 

블로그 이미지

uchacha

개발자 일지

,

@참고: https://stackoverflow.com/questions/11381068/class-not-found-exception-when-running-junit-test/13375775#13375775

 

상황

다른 분이 개발한 server를 eclipse로 가져와서 테스트를 실행하려는데 새로 생성한 helloworld 테스트든, 기존 테스트든 위와 같이 class 를 못찾겠다며 에러를 뿜었다.

maven build 하는 서버라 mvn test 로 command 라인에서는 잘 실행이 되어서 찾아보니 eclipse 에서 maven 으로 가져온 프로젝트의 셋업 문제라고 한다..

 

해결

1. project output folder 경로 찾기

>> Project properties -> Java Build Path -> Default output folder 내용 복사

e.g. test_server/target/classes

 

2. Run -> Run Configuration 으로 가기

 

3. unit test 항목의 run configuration 에서 Classpath 탭을 클릭한다.

 

4. 프로젝트의 User Entries 에 복사한 output folder 를 명시적으로 추가한다.

만약 프로젝트가 이미 포함되어 있더라도 

Advanced -> Add folder 를 통해 복사한 output folder 를 찾아 추가한다.

 

블로그 이미지

uchacha

개발자 일지

,

5.1. 정규 표현식 살펴보기

- 주민등록번호를 포함하고 있는 텍스트에서 주민등록번호의 뒷자리 부분만 * 문자로 변경하기: re 라이브러리 사용

* re 없이

data = """
park 800905-1049118
kim  700905-1059119
"""

result = []
for line in data.split("\n"):
	word_result = []
	for word in line.split(" "):
    	if len(word) == 14 and word[:6].isdigit() and word[6:7] == "-" and word[7:].isdigit():
        	word = word[:7] + "*******"
        word_result.append(word)
    result.append(" ".join(word_result))
print("\n".join(result))

 

* re 사용하면

import re

data = """
park 800905-1049118
kim  700905-1059119
"""

pattern = re.compile("(\d{6})[-]\d{7}")
print(pattern.sub("\g<1>-*******", data))

 

5.2. 정규 표현식 시작하기

- 메타 문자

[ ] [^] 
. ? * + { }
^ $ \
\A \Z \b \B
( ) |

 

표기 설명 예시
[ ] 문자 클래스로 [ ] 사이의 문자중 하나와 매칭 [a-zA-Z] : 알파벳 중 하나와 매칭
[0-9] : 숫자 중 하나와 매칭
[^] not. ^ 뒤의 문자가 아닌 문자와 매칭 [^0-9] : 숫자가 아닌 문자 중 하나와 매칭
\^ : '^' 문자와 매칭
. \n 을 제외한 모든 문자 중 하나와 매칭 a.b : 'a0b' 와 매칭
a[.]b : 'a.b' 와 매칭
? ? 앞의 문자가 있거나 없거나 가능 ab?c : 'ab', 'abc' 와 매칭
* * 앞의 문자가 0~무한대로 반복 가능 ca*t : 'ct', 'cat', 'caat' 와 매칭
+ + 앞의 문자가 1~무한대로 반복 가능 ca+t : 'cat', 'caat' 와 매칭
{m}, {m,} {,m} {m, n} { 앞의 문자가 m ~ n 번 반복 가능  ca{2}t : 'caat' 와 매칭
ca{2,5}t : 'caat', 'caaat', 'caaaaat' 와 매칭
^
$
^ 다음 문자로 시작하는 문자를 매칭
$ 앞의 문자로 끝나는 문자를 매칭
^a...s$ : 'abyss'
\
r
정규식 엔진 규칙의 '\' 문자에 대한 escape 
파이썬 리터럴 '\' 에 대한 escape
r'\\section' : '\section' 와 매칭
* r은 Raw String 으로 '\\\\section' 으로 쓰게 하는 파이썬 리터럴 규칙(얘를 무시하게 되어)과 정규식 엔진 규칙의 '\' 중복 적용으로 인한 복잡성을 줄인다.
\A \Z
\b \B
re.MULTILINE 옵션 사용시에도 전체 문자열의 처음(\A), 끝(\Z) 하고만 매칭
단어 구분자(Word boundary) 와 매칭(\b), 매칭 안됨(\B)
r'\bclass\b' : ' class ' 와 매칭
r'\Bclass\B' : 'declassified'의 'class'와 매칭
| or. A|B 라는 정규식이면 A 또는 B 'Crow|Servo' : 'Crow', 'Servo' 와 매칭
( ) ( | )
\1
문자열의 반복과 같은 정규식 작성시 그룹을 만들어줌
첫번째 그루핑된 문자열 재참조
'(ABC)+' : 'ABCABCABC'

\g<1> \g<phone> sub 메소드 사용 시 그룹핑된 문자열 재참조  
*?, +?, ??, {m,n}? Non-Greedy. 가능한 가장 최소의 문자열 매칭 '<.*?>' : '<html>'

 

- 자주 사용하는 문자 클래스

\d, \D : [0-9], [^0-9]

\s, \S : [ \t\n\r\f\v], [^ \t\n\r\f\v]

\w, \W: [a-zA-Z0-9_], [^a-zA-Z0-9_]

* ^ 보다는 - 얘가 우선 순위를 갖는 것 같다.

 

- re 모듈 사용하기

import re
p = re.compile('[a-z]+') # re.compile('[정규표현식]', re.[옵션]) 으로 옵션을 줄 수도 있다.
# p 는 패턴으로 정규식을 컴파일한 결과이다.

### - 패턴 객체의 대표적 검색 메소드
m = p.match("python") # 문자열 시작부분에서 정규식과 매치되는 부분을 찾는다.
m = p.search(data) # 문자열 전체중에 정규식과 매치되는 부분을 찾는다.
list = p.findall(data) # 정규식과 매치되는 모든 문자열을 리스트로 돌려준다.
miter = p.finditer(data) # 정규식과 매치되는 모든 문자열을 match 요소를 갖는 반복 가능한 객체로 돌려준다.
# match, search는 정규식과 매치될 때는 match 객체를, 매치되지 않았을 때는 None 을 돌려준다.

### - match 객체의 메소드
m.group() # 매치된 문자열을 돌려준다. 'python'
m.start() # 매치된 문자열의 시작 idx를 돌려준다. 0
m.end() # 매치된 문자열의 끝 idx를 돌려준다. 6
m.span() # 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 돌려준다. (0, 6)

* re.compile, p.match -> re.match 로 축약 가능하다.

import re
m = re.match('[a-z]+', "python")

 

- 패턴 컴파일 옵션: re.DOTALL, re.IGNORECASE, re.MULTILINE, re.VERBOSE

import re
p = re.compile('a.b', re.DOTALL) # a\nb 도 매치시킨다.
p = re.compile('[a-z]', re.IGNORECASE) # 대소문자 구분 없이 매치시킨다.

p = re.compile('^python\s\w+', re.MULTILINE) # 아래 data 에 대해 findall 시 ^ 를 각 줄마다 적용한다. 
data = ""python one
python two"""

charref = re.compile(r'&[#](0[0-7]+|[0-9]+|x[0-9a-fA-F]+);') # re.VERBOSE 옵션을 이용해서 아래와 같이 표현할 수 있다.
charref = re.compile(r"""
&[#]					# 숫자 엔터티의 참조 시작인 '&#' 문자 매칭 검사
(
	0[0-7]+				# 8진수 형태인 '036720' 과 같은 문자 매칭 검사
    | [0-9]+			# 또는 10진수 형태인 '80' 과 같은 문자 매칭 검사
    | x[0-9a-fA-F]+		# 또는 16진수 형태인 'xa82' 과 같은 문자 매칭 검사
)
;						# Trailing 세미콜론인 ';' 과 같은 문자 매칭 검사
""", re.VERBOSE)
charref.findall("&#012;&#983;&#x7845;")

 

5.3. 강력한 정규 표현식

- 그루핑된 부분의 문자열 뽑아내기: m.group(1)

# '이름 + " " + 전화번호' 찾기
p = re.compile(r"(\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group(0)) # 매치된 전제 문자열, park 010-1234-1234
print(m.group(1)) # 첫번째 그룹에 해당되는 문자열, park
print(m.group(2)) # 두번째 그룹에 해당되는 문자열, 010-1234-1234
print(m.group(3)) # 그룹이 중첩되는 경우 바깥쪽부터 안쪽 순으로 인덱스가 증가한다. 010

 

- 그루핑된 문자열 재참조하기: \1

import re
p = re.compile(r'(\b\w+)\s+\1')
print(p.search('Paris in the the spring').group()) # 'the the'
# * '\b\w+\s+' 에 매칭되는 건 'Paris ', 'in ', 'the ', 'the ', 'spring ' 이고, '(\b\w+)\s+\1' 에 매칭되는 건 'the the' 이다.

 

- 그루핑된 문자열에 이름 붙이기: (?P<그룹명> ), 재참조시 (?P=그룹이름)

import re
p = re.compile(r"(?P<name>\w+)\s+((\d+)[-]\d+[-]\d+)")
m = p.search("park 010-1234-1234")
print(m.group("name")) # 'park'

p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
m = p.search("Paris in the the spring")
print(m.group()) # 'the the'

 

- 전방 탐색(Lookahead Assertions): 정규식과 일치하는 문자열에서 특정 정규식을 제외하고 출력

* 긍정형 전방 탐색: (?=...) - ... 에 해당하는 정규식과 매치되어야 하며 조건에 맞아도 문자열이 소비되지 않는다.

* 부정형 전방 탐색: (?!...) - ... 에 해당하는 정규식과 매치되지 않아야 하며 조건에 맞아도 문자열이 소비되지 않는다.

# 프로토콜 가져오기
import re
p = re.compile('.+(?=:)')
m = p.search("http://google.com")
print(m.group()) # 'http'

# 파일 이름을 특정 확장자 제외하고 가져오기
p = re.compile('.+[.](?!bat$|exe$).+') # bat, exe 제외하기
m = p.search("build.bat") # None
m = p.search("memo.txt") # <re.Match object; span=(0, 8), match='memo.txt'>

 

- 문자열 바꾸기: sub

import re
p = re.compile('(blue|white|red)')
print(p.sub("colour", "blue socks and red shoes")) # 'colour socks and colour shoes'
print(p.sub("colour", "blue socks and red shoes", count=1))  # 'colour socks and red shoes'
print(p.subn("colour", "blue socks and red shoes")) # ('colour socks and colour shoes', 2)

# sub 메소드 사용 시 그루핑 문자 참조
p = re.compile(r'(?P<name>\w+)\s+(?P<phone>(\d+)[-]\d+[-]\d+)')
print(p.sub("\g<phone> \g<name>", "park 010-1234-1234")) # '010-1234-1234 park'
print(p.sub("\g<2> \g<1>", "park 010-1234-1234-1234")) # '010-1234-1234 park'

# sub 메소드의 매개변수로 함수 넣기 - 10진수를 16진수로 대체하기
def hexrepl(match):
	value = int(match.group())
    return hex(value)
    
p = re.compile(r'\d+')
print(p.sub(hexrepl, "Call 65490 for printing, 49152 for user code.")) # 'Call 0xffd2 for printing, 0xc000 for user code.'

 

- Non-Greedy: 만족하는 최소 문자 찾기

# Greedy
import re
s = "<html><head><title>Title</title>"
print(re.match('<.*>', s).group()) # '<html><head><title>Title</title>'

# Non-Greedy
print(re.match('<.*?>', s).group()) # '<html>'

 

블로그 이미지

uchacha

개발자 일지

,

4. 클래스 외

4.1. 클래스

- 클래스 선언

class Cookie:
	pass
    
a = Cookie()

 

- 메소드: 클래스의 함수

class FourCal:
	def setdata(self, first, second):
    	self.first = first
        self.second = second
        
a = FourCal()
a.setdata(3, 6)

print(a.first)

 

- 생성자: 위의 setdata는 객체에 초기값으로 설정해주는게 안전하므로 생성자에 정의할 수 있다.

class FourCal:
	def __init__(self, first, second):
    	self.first = first
        self.second = second
        
    def add(self):
    	result = self.first + self.second
        return result
        
a = FourCal(4, 2)
print(a.add())

 

- 클래스의 상속

class MoreFourCal(FourCal):
	def pow(self):
    	result = self.first ** self.second
        return result
        
a = MoreFourCal(4, 2)
a.pow()

* 메소드 오버라이딩 시 메소드의 이름을 가지고 메소드 구분을 한다. 즉 메소드 명이 같으면 파라미터 개수가 달라도 마지막 정의된 메소드로 오버라이딩 된다.

 

- 클래스 변수

class Family:
	lastname = "김"
    
print(Family.lastname)

* java의 static 변수와 같다.

 

4.2. 모듈

- 모듈 만들기

# mod1.py
PI = 3.141592

class Math:
	def solv(self, r):
    	return PI * (r ** 2)

def add(a, b):
	return a + b
    
if __name__ == "__main__": # 직접 파일 실행시 __name__ 이 "__main__" 이며, import 시 "mod1" 이다.
	print(add(1, 4))

 

- 모듈 불러오기

# main.py

import mod1
'''
from mod1 import add # add(3, 4) 와 같이 호출한다.
from mod1 import Math # math = Math() 와 같이 호출한다.
from mod1 import add, sub # 여러개인 경우 *
'''
print(mod1.add(3, 4))

* import 는

1. 파이썬 라이브러리가 저장된 디렉토리,

2. 현재 디렉토리에 있는 모듈,

3. sys.path.append([모듈이 저장된 디렉토리]) 설정 후의 모듈

4. export로 PYTHONPATH=[모듈이 저장된 디렉토리] 환경 변수 설정 후의 모듈

만 불러온다.

 

- 모듈에 별칭 주기: as

 

4.3. 패키지

 - 패키지와 모듈: 패키지는 디렉토리, 모듈은 파이썬 파일이라 할 수 있다.

 

- 패키지로 인식되고 싶은 디렉토리에 __init__.py 파일을 생성해 두며,

__init__.py 모듈은 해당 파일이 속한 디렉토리를 import 해 와서 사용 할 수 있다.

 

- 패키지 구조를 아래와 같이 구성할 때 game package를 참조하기 위해서는 export PYTHONPATH=C:/doit 을 통해 환경변수를 세팅해줘야 한다.

C:/doit/game/__init__.py
C:/doit/game/sound/__init__.py
C:/doit/game/sound/echo.py
C:/doit/game/graphic/__init__.py
C:/doit/game/graphic/render.py

 

- 패키지 안의 함수 실행하기

* import 시 실행 파일이 실행되는 위치를 기준으로 패키지 경로를 맞춘다.

# main.py

# echo 모듈 import
''' 방법1
import game.sound.echo
game.sound.echo.echo_test()
'''

''' 방법2
from game.sound import echo 
# from 패키지 import 모듈 시 * 로 사용하려면, __init__.py 에 __all__ = ['echo'] 를 정의한다.
echo.echo_test()
'''

# echo_test 함수 import
'''
from game.sound.echo import echo_test
echo_test()
'''

import시 __init__.py 외에는 최소 import 해야 하는 모듈까지 import 경로를 명시해주어야 한다.

 

- from a.b.c import d 또는 import a.b.c 시 a, b, c 는 반드시 모듈 또는 패키지여야 한다.

 

- relative 패키지: render.py 모듈이 echo.py 모듈을 사용하고 싶을 때

# render.py
from game.sound.echo import echo_test
# 또는 from ..sound.echo import echo_test
def render_test():
	print("render")
    echo_test()
    
# main.py
from game.graphic.render import render_test
render_test()

 

4.4. 예외 처리

- 오류 예외처리 기법: try .. except

# 방법1: try, except만 쓰는 방법
try:
	4 / 0
except:
	print("Can NOT divided by 0")
    
# 방법2: 발생 오류를 포함한 except 문
try:
	a = [1, 2]
    print(a[3])
	4 / 0
except ZeroDivisionError as e: # 여러개의 Exception 은 (ZeroDivisionError, IndexError) 와 같이 표현한다.
	print(e)
except IndexError as e:
	print(e)

 

- try .. finally

try:
	f = open("없는 파일", 'r')
finally:
	f.close() # FileNotFoundError 던지고, finally 구문을 실행한다.

 

- try .. except .. else

try:
	age = int(input("나이를 입력하세요: "))
except:
	print("입력이 정확하지 않습니다.")
else:
	if age <= 18:
    	print("미성년자는 출입금지입니다.")
    else:
    	print("환영합니다.")

 

오류 일부러 발생시키기: raise

class Bird:
	def fly(self):
    	raise NotImplementedError # 상속시 반드시 구현하도록 한다.

class Eagle(Bird):
	pass
    
eagle = Eagle()
eagle.fly() # NotImplementedError 가 발생한다.

 

- 예외 만들기

class MyError(Exception):
	def __str__(self):
    	return "허용되지 않는 별명입니다."
    
def say_nick(nick):
	if nick == "바보":
    	raise MyError()
    print(nick)
    
say_nick("바보") # MyError 가 발생하며 에러메세지는 __str__ 로 구현된다.

 

4.5. 내장 함수

abs(-1.2) # 1.2

max([1, 2, 3]) # 3
min([1, 2, 3]) # 1

hex(234) # 10진수 -> 16진수 문자열로 변환
oct(34) # 10진수 -> 8진수 문자열로 변환
int('0x1a', 16) # 16진수 -> 10진수로 변환

round(4.6) # 5, 반올림
round(5.678, 2) # 5.68, 소수 둣째짜리까지만 반올림하여 표시

sorted([3, 1, 2]) # [1, 2, 3]
sum([1, 2, 3])

zip([1, 2, 3], [4, 5, 6]) # 동일한 개수로 이루어진 자료형을 묶어준다.
'''
	list(zip([1, 2, 3], [4, 5, 6])) # [(1, 4), (2, 5), (3, 6)]
'''

range(1, 10, 2) # 시작, 끝, 숫자 사이 거리 순으로 인수를 받는다.

enumerate([반복 가능한 자료형]) # i, 내용 의 enumerate 객체
'''
	for i, name in enumerate(['body', 'foo', 'bar']):
    	print(i, name)
'''

filter([함수], [반복 가능한 자료형])
'''
	list(filter(lambda x: x>0, [1, -3, 2, 0, -5, 6]))
'''

map([함수], [반복 가능한 자료형])
'''
	list(map(lambda x: x*2, [1, 2, 3, 4]))
'''

isinstance(a, Person) # 인스턴스, 클래스를 인수로 받아 판단 결과를 True, False 로 돌려준다.

divmod(7, 3) # ([몫], [나머지])

eval('1+2') # 실행 가능한 문자열을 실행한 결과

 

4.6. 라이브러리

- sys

import sys
print(sys.argv) # 명령 프롬프트 창에서 python3 argv_test.py you need python 시 ['argv_test.py', 'you', 'need', 'python']과 같이 출력된다.
sys.exit()
sys.path # 파이썬 모듈들이 저장된 위치이다. ['', '/Users/user/vsc-workspace/python/_5_add_wing_of_python/_5_3_package', ... ]
sys.path.append("C:/doit/mymod")

 

- os

import os
os.environ # 현재 시스템의 환경변수 값이다. environ({'USER': 'user', '__CFBundleIdentifier': 'com.microsoft.VSCode', ...})
os.environ['PATH']
os.chdir("C:\WINDOWS") # 현재 디렉토리 위치 변경
os.getcwd() # 현재 디렉토리의 위치
os.system("ls") # 시스템 명령어 실행
f = os.popen("ls") # 시스템 명령어를 실행한 결과값을 읽기 모드 형태의 파일 객체로 돌려준다. print(f.read()) 와 같이 내용을 볼 수 있다.

* 하위 디렉터리 검색하기

import os
filenames = os.listdir(dirname) # 인자로 받은 디렉토리의 ls 값을 iterable 자료형으로 돌려준다.
full_filename = os.path.join(dirname, filename) # 인자로 받은 디렉토리와 파일이름 값을 경로 구분자를 사용하여 join한다.
ext = os.path.splitext(full_filename)[-1] # 해당 파일의 확장자를를 가져온다.
os.path.isdir(full_filename)

* 하위 디렉터리 검색을 쉽게: os.walk

import os
for (path, dirs, files) in os.walk("c:/"):
	for filename in files:
    	ext = os.path.splitext()[-1]
        if ext == ".py":
        	print("%s%s" % (path, filename))

 

- shutil: shutil.copy("src.txt", "dst.txt")

- glob: 디렉토리에 있는 파일 찾아 리스트로 만들기

import glob
glob.glob("c:/doit/mark*") # ['c:/doit\\marks1.py', 'c:/doit\\marks2.py', 'c:/doit\\marks3.py']

 

- time

import time
time.time() # UTC 를 사용하여 기준시부터 현재 시간까지를 초 단위로 돌려준다. 988458015.73417199
time.localtime(time.time()) # time.struct_time(tm_year=2013, tm_mon=5, tm_mday=21, tm_hour=16,
    tm_min=48, tm_sec=42, tm_wday=1, tm_yday=141, tm_isdst=0)
time.asctime(time.localtime(time.time())) # 'Sat Apr 28 20:50:20 2001'
time.ctime() # 'Sat Apr 28 20:56:31 2001'
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
time.strftime("%Y-%m-%d %H:%M:%S")
time.sleep(0.3) # 주워진 초만큼 시간 간격을 둔다.

* 시간에 관계된 것을 표현하는 포맷 코드

분류 포맷코드
%Y, %y 2001, 01
%m, %B, %b [01,12], January, Jan
%d [01,31]
%H, %l, %p [00,23], [01,12], AM
%M [01, 59]
%S [00, 59]
요일 %w, %A, %a [0(일요일),6], Monday, Mon
포맷팅 %c, %x, %X 06/01/01 17:22:21, 06/01/01, 17:22:21

 

- random

import random
random.random() # [0.0, 1.0) 범위의 실수인 난수 생성. 0.53840103305098674
random.ranint(1, 10) # [1, 10] 범위의 정수인 난수 생성. 6
random.choice(data) # data 리스트에서 무작위로 하나를 선택해서 돌려준다.
random.shuffle(data) # data 리스트의 항목을 무작위로 섞는다.

 

- webbrowser

import webbrowser
webbrowser.open("http://google.com")
webbrowser.open_new("http://google.com")

 

- threading

# thread_test.py
import time
import threading # 스레드를 생성하기 위해 threading 모듈이 필요하다.

def long_task():
	for i in range(5):
    	time.sleep(1)
        print("working:%s\n" % i)
        
print("Start")

threads = []
for i in range(5):
	t = threading.Thread(target=long_task) # 스레드를 생성한다.
    threads.append(t)
    
for t in threads:
	t.start() # 스레드를 실행한다.
    
for t in threads:
	t.join() # join으로 다음 코드는 스레드가 종료된 후 실행된다.
    
print("End")
블로그 이미지

uchacha

개발자 일지

,

3.1. 함수

- 돌려받을 값이 없는 함수를 변수에 대입하면 None 이 출력된다.

>>> a = add(3, 4)
>>> print(a)
None

 

- 매개변수 지정하여 호출하기: add(a=3, b=7)

 

- 미지수의 여러 입력값: def add_many(*args):

- 키워드 파라미터: def print_kwargs(**kwargs):

def print_kwargs(**kwargs):
	print(kwargs)
    
print_kwargs(a=1)
{'a': 1}

 

- 튜플값으로 return 하기

def add_and_mul(a,b):
	return a+b, a*b
    
result = add_and_mul(3, 4)
result1, result2 = add_and_mul(5, 6)

 

- 매개변수 초기값 설정하기: def say_myself(name, age, sex="F"):

def say_myself(name, age, sex="F"):
    print("My name is %s" % name)
    print("My age is %d" % age)
    if sex == "F":
        print("Female")
    elif sex == "M":
        print("Male")
    else:
        raise Exception("There not exist %s" % sex)

say_myself("배수지", 31)
say_myself("홍길동", 30, "M")

* 초기값 설정해 놓은 매개변수는 초기값 설정하지 않은 매개변수 뒤에 선언해야 한다.

* args, kwargs 는 관례적 이름이다.

 

- 함수 안 선언 변수의 효력 범위는 자바와 마찬가지로 함수 안에서만 사용될 뿐 바깥의 변수랑은 상관이 없다.

- global 명령어: 함수 밖 변수를 사용할 수 있게 해준다. 독립성을 위해 가급적 사용하지 않는게 좋다.

 

- lambda: 함수를 한줄로 간결하게 만들 때 사용한다.

add = lambda a, b: a+b
result = add(3, 4)

 

3.2. 사용자 입력과 출력

- input 함수: input(), input("숫자를 입력하세요: ")

 

- print 문: 큰따옴표(")로 둘러쌓인 문자열은 '+', 콤마(,) 는 '뛰어쓰기'

매개변수 end를 사용해 끝 문자를 지정할 수 있다.

>>> print("life" "is" "too short")
lifeistoo short
>>> print("life", "is", "too short")
life is too short
>>> for i in range(10):
	print(i, end=' ')

 

3.3. 파일 읽고 쓰기

- 파일 생성: open

f = open("새파일.txt", 'w') # 파일 열기 모드로 'r', 'w', 'a', 순서대로 읽기, 쓰기, 추가 모드를 사용할 수 있다.
f.close() # 파일 모드를 바꾸기 전에 close를 해야 제대로 작동한다.

현재 경로를 확인하기 위해 아래의 코드를 사용할 수 있다.

import os
path = os.getcwd()
print(path)

 

- 파일 쓰기: f.write("%d 번째 줄입니다.\n" % i)

- 파일 읽기: f.readline(), f.readlines(), f.read()

def readline():
    while True:
        line = f.readline()
        if not line:
   		    break
        print(line.strip()) # 줄바꿈(\n) 문자 제거
    
def readlines():
    lines = f.readlines()
    for line in lines:
    	print(line.strip())
 
def read():
    data = f.read()
    print(data)

path = "/Users/user/vsc-workspace/python/_4_io/_4_2_file_io/새파일.txt"
f = open(path, 'r')
readline()
readlines()
read()
f.close()

- 왼쪽부터 순서대로 한줄 읽기, 줄을 리스트 요소로 가져오기, 내용 전체 돌려주기 이다.

- with문과 함께 사용하기: with 블록을 벗어난 순간 열린 파일 객체 f 가 자동으로 close 된다.

with open("foo.txt", 'w') as f:
	f.write("Life is too short, you need python")

 

- sys 모듈로 매개변수 주기

import sys
args = sys.argv[1:]
for i in args:
	print(i)

'''
python3 sys1.py aaa bbb ccc
를 실행하면 argv[0] 인 sys1.py 이후부터 출력한다.
'''

 

블로그 이미지

uchacha

개발자 일지

,

2. 제어문

2.1. if 문

- 비교연산자: <, >, ==, !=, >=, <=

- 조건연산자: and, or, not

java 의 &&, ||, ! 과 매핑되는 연산자이다.

- 리스트, 튜플, 문자열에 대한 추가 조건문: x in s, x not in s

- 조건문의 수행 내용을 비우기: pass

- 조건문의 예는 아래와 같다.

pocket = ['paper', 'cellphone']
card = True
if 'money' in pocket:
	print('take a taxi')
elif card:
	print('take a taxi')
else:
	print('take a walk')

- 조건부 표현식: java의 삼항연산자와 매핑되는 표현식이다.

message = "success" if score >= 60 else "failure"

 

2.2. while 문

- console 입력값 받기: input(), input(["입력값에 대한 설명문"])

prompt = """
1. Add
2. Del
3. List
4. Quit

Enter number: """

number = 0
while number != 4:
	print(prompt)
    number = int(input())

- 반복문 제어: break, continue

 

2.3. for 문

- for 문에는 리스트, 튜플, 문자열이 가능하다.

a =[(1,2), (3,4), (5,6)]
for (first, last) in a:
	print(first + last)

- range 함수로 숫자 리스트를 만들어줄 수 있다.

>>> range(10)
>>> range(1, 11)

 

블로그 이미지

uchacha

개발자 일지

,