Numpy는 Python에서 벡터, 행렬 등 수치 연산을 수행하는 선형대수 라이브러리이다.

Numpy에서는 모든 배열의 값이 기본적으로 같은 타입이어야 한다. 때문에 서로 다른 데이터들로 구성되어있는 array 일 경우 같은 자료형의 데이터로 맞추거나 자료형 맞추는것이 불가능 한 경우는 오류가 발생한다

(Numpy에서 array를 행렬로 봐야함)


list를 array로 변경

import numpy as np
data1 = [0,1,2,3,4,5]
a1 = np.array(data1)
a1

->
array([0, 1, 2, 3, 4, 5])
data2 = [0.1, 5, 4, 12, 0.5]
a2 = np.array(data2)
a2

->
array([ 0.1,  5. ,  4. , 12. ,  0.5])
a1.dtype

->
dtype('int32')
#int형 32비트
a2.dtype

->
dtype('float64')

 


arange() - 특정 범위 내에서 일정한 간격의 데이터 배열 생성

arange(start, stop, step, dtype) -> start, step, dtype 생략 가능 (dtype 생략 시 다른 매개변수로부터 type을 추론한다)

np.arange(0, 10, 2)

->
array([0, 2, 4, 6, 8])
np.arange(1, 10)

->
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(5)

->
array([0, 1, 2, 3, 4])

 


reshape() - 다차원 변환

np.arange(12).reshape(4,3)

->
array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11]])

 


#shape -> 배열 각 축의 크기

b1 = np.arange(12).reshape(4,3)
b1.shape

->
(4, 3)
#4행3열의 배열
b2 = np.arange(5)
np.arange(5)
->
array([0, 1, 2, 3, 4])


b2.shape
->
(5,)
# 5개의 열을 가지는 배열

 


linspace() - 일정한 간격의 데이터를 가지는 배열 만들기

np.linspace(start, stop, num, endpoint=True) -> 마지막 endpoint=True 또는 False로 줄 수 있는데 Default는 True이다. True일 경우 stop값을 포함하고 False일 경우는 포함하지 않는다는 옵션이다.

np.linspace(1, 10, 10)
->
array([ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.])
np.linspace(1, 10, 10, endpoint=False)
->
array([1. , 1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1])
np.linspace(0, np.pi, 20)
->
array([0.        , 0.16534698, 0.33069396, 0.49604095, 0.66138793,
       0.82673491, 0.99208189, 1.15742887, 1.32277585, 1.48812284,
       1.65346982, 1.8188168 , 1.98416378, 2.14951076, 2.31485774,
       2.48020473, 2.64555171, 2.81089869, 2.97624567, 3.14159265])

 


eye() - 단위 행렬 만들기

np.eye(3) #단위 행렬(특수 배열)
->
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])

 


zeros() - 모두 0으로 된 배열 생성

np.zeros(10)
->
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((3,4))
->
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])

 


astype() - 데이터프레임 타입 바꾸기

str_a1 = np.array(['1.567', '0.123', '5.123', '9', '8'])
num_a1 = str_a1.astype(float)
num_a1

->
array([1.567, 0.123, 5.123, 9.   , 8.   ])

 


sum() - 합계, mean() - 평균, std() - 표준편차, var() - 분산

arr3 = np.arange(5)
arr3
->
array([0, 1, 2, 3, 4])

[arr3.sum(), arr3.mean(), arr3.std(), arr3.var()]
->
[10, 2.0, 1.4142135623730951, 2.0]

 

cumsum(), cumprod()

 

반응형

파일을 생성하거나 읽고 쓰는 경우 아래와 같이 현재 위치를 원하는 폴더로 지정해 놓아야 한다

(필자는 Python 저장 경로는 c드라이브의 pywork라는 폴더로 설정했다)

cd C:\pywork

 

myFile.txt파일을 생성하고 write('w')할 수 있는 객체 f 생성 후 내용 작성

f = open('myFile.txt', 'w')
f.write('This is my first file.')
f.close()

 

myFile.txt를 read('r')할 수 있는 객체 f 생성 후 내용 읽기

f = open('myFile.txt', 'r')
file_text = f.read()
f.close()
print(file_text)

->
This is my first file.

 

 

위와 같은 방법으로 파일 생성 후 다른 내용을 담아 보았다

f = open('two_times_table.txt', 'w')
for num in range(1,6):
    format_string = "2 x {0} = {1}\n".format(num, 2*num)
    f.write(format_string)
f.close()
f = open("two_times_table.txt")
line = f.readline()
while line:
    print(line, end = "")
    line = f.readline()
f.close()

->
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

 

# lines = f.readlines() -> list형식으로 담김

f = open("two_times_table.txt")
lines = f.readlines()
f.close()
print(lines)

->
['2 x 1 = 2\n', '2 x 2 = 4\n', '2 x 3 = 6\n', '2 x 4 = 8\n', '2 x 5 = 10\n']

 

 

f = open("two_times_table.txt")
lines = f.readlines()
f.close()
for line in lines:
    print(line, end="")
    
->
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

 

 

파일을 담은 객체를 그대로 사용 (코드 간소화)

f = open("two_times_table.txt")
for line in f:
    print(line, end="")
f.close()

->
2 x 1 = 2
2 x 2 = 4
2 x 3 = 6
2 x 4 = 8
2 x 5 = 10

 

with as 키워드 사용

파일을 다루는 처리를 할때는 필수적으로 파일 오픈(open) 파일 닫기(close) 과정을 거치게 되는데 실수로 close하지 않는 경우가 종종 발생한다. 이런 경우를 대비해 with as 구문을 사용하여 해당 구문이 끝나면 자동으로 닫히게 되어서 이러한 실수를 줄일 수 있다

with open('myTextFile3.txt', 'w') as f:
    for num in range(1, 6):
        format_str = "3 x {0} = {1}\n".format(num, 3*num)
        f.write(format_str)
with open('myTextFile3.txt', 'r') as f:
    for line in f:
        print(line, end="")
        
->
3 x 1 = 3
3 x 2 = 6
3 x 3 = 9
3 x 4 = 12
3 x 5 = 15
반응형

Python 파일(.py) 저장

 

먼저, 저장하고 싶은 경로에 폴더를 생성한다(C드라이브에 pywork폴더)

그리고 아래와 같이 상단에 %%writefile C:\pywork\my_area.py 라는 명령문을 입력한다

%%는 아나콘다 시스템 명령에 사용된다

%%writefile C:\pywork\my_area.py
    
PI = 3.14
    
def square_area(a):
    return a ** 2 #정사각형 넓이

def circle_area(r):
    return PI * r ** 2 # 원의 넓이
    
->
Writing C:\pywork\my_area.py

따라서 위처럼 코드를 작성하면 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

PI = 3.14
    
def square_area(a):
    return a ** 2 #정사각형 넓이

def circle_area(r):
    return PI * r ** 2 # 원의 넓이

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

이 내용을 담은 my_area.py파일이 pywork폴더에 생성된다.

 

 

 

 

폴더(directory) 생성

mkdir C:\pywork\image; C:\pywork\image\io_file

# image폴더 안에 io_file폴더 생성

반응형

random

import random
random.random()

->
0.4330038659050862
import random

dice1 = random.randint(1,6) #임의의 정수가 생성됨
dice2 = random.randint(1,6)
print('주사위 두 개의 숫자:{0}, {1}'.format(dice1, dice2))

->
주사위 두 개의 숫자:5, 3
import random

num1 = random.randrange(1, 10, 2) # 1~9 중 임의의 홀수 선택
num2 = random.randrange(0, 100, 10) # 0~99
print('num1: {0}, num2: {1}'.format(num1, num2))

->
num1: 3, num2: 80
import random

menu = ['비빔밥', '된장찌개', '볶음밥', '불고기', '스파게티', '피자', '탕수육']
random.choice(menu)

->
'된장찌개'
import random
random.sample([1,2,3,4,5], 2) # 모집단에서 두 개의 인자 선택

->
[2, 1]

 

 

datetime

import datetime

set_day = datetime.date(2019, 3, 1)
print(set_day)

->
2019-03-01
import datetime

day1 = datetime.date(2019, 4, 1)
day2 = datetime.date(2019, 7, 10)
diff_day = day2 - day1
print(diff_day)

->
100 days, 0:00:00
import datetime

today = datetime.date.today()
special_day = datetime.date(2021, 4, 12)
print(special_day - today)

->
-106 days, 0:00:00
import datetime

set_time = datetime.time(15, 30, 45)
print(set_time)

->
15:30:45
import datetime

set_time = datetime.time(15, 30, 45)
print(set_time)

->
15:30:45
import datetime

set_dt = datetime.datetime(2018, 10, 9, 10, 20, 0)
print(set_dt)

->
2018-10-09 10:20:00
from datetime import date, time, datetime # datetime이라는 패키지 안에 있는 date, time, datetime 모듈

print(datetime.now())

->
2021-07-27 15:14:08.782388

 

calendar

import calendar

print(calendar.calendar(2021))

->
                                  2021

      January                   February                   March
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
             1  2  3       1  2  3  4  5  6  7       1  2  3  4  5  6  7
 4  5  6  7  8  9 10       8  9 10 11 12 13 14       8  9 10 11 12 13 14
11 12 13 14 15 16 17      15 16 17 18 19 20 21      15 16 17 18 19 20 21
18 19 20 21 22 23 24      22 23 24 25 26 27 28      22 23 24 25 26 27 28
25 26 27 28 29 30 31                                29 30 31

       April                      May                       June
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
          1  2  3  4                      1  2          1  2  3  4  5  6
 5  6  7  8  9 10 11       3  4  5  6  7  8  9       7  8  9 10 11 12 13
12 13 14 15 16 17 18      10 11 12 13 14 15 16      14 15 16 17 18 19 20
19 20 21 22 23 24 25      17 18 19 20 21 22 23      21 22 23 24 25 26 27
26 27 28 29 30            24 25 26 27 28 29 30      28 29 30
                          31

        July                     August                  September
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
          1  2  3  4                         1             1  2  3  4  5
 5  6  7  8  9 10 11       2  3  4  5  6  7  8       6  7  8  9 10 11 12
12 13 14 15 16 17 18       9 10 11 12 13 14 15      13 14 15 16 17 18 19
19 20 21 22 23 24 25      16 17 18 19 20 21 22      20 21 22 23 24 25 26
26 27 28 29 30 31         23 24 25 26 27 28 29      27 28 29 30
                          30 31

      October                   November                  December
Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su
             1  2  3       1  2  3  4  5  6  7             1  2  3  4  5
 4  5  6  7  8  9 10       8  9 10 11 12 13 14       6  7  8  9 10 11 12
11 12 13 14 15 16 17      15 16 17 18 19 20 21      13 14 15 16 17 18 19
18 19 20 21 22 23 24      22 23 24 25 26 27 28      20 21 22 23 24 25 26
25 26 27 28 29 30 31      29 30                     27 28 29 30 31

 

 

 

 

 

 

 

 

반응형

split() - 문자열 나누기

coffee_menu_str = "에스프레소, 아메리카노, 카페라테, 카푸치노"
coffee_menu_str.split(',')

-> ['에스프레소', ' 아메리카노', ' 카페라테', ' 카푸치노']
" 에스프레소 \n\n 아메리카노 \n 카페라테 카푸치노 \n\n".split()

-> ['에스프레소', '아메리카노', '카페라테', '카푸치노']
"에스프레소 아메리카노 카페라테 카푸치노 말차프라페".split(maxsplit=2)

-> ['에스프레소', '아메리카노', '카페라테 카푸치노 말차프라페']
phone_number = "+82-01-2345-6789" #국가 번호가 포함된 전화번호
split_num = phone_number.split("-", 1) #국가 번호와 나머지 번호 분리

print(split_num)
print("국내전화번호: {0}".format(split_num[1]))

->['+82', '01-2345-6789']
국내전화번호: 01-2345-6789

 


strip() - 문자열 앞뒤의 해당 문자 제거 (주의 : 앞뒤만)

test_str = "aaabbPythonbbbaa"
temp1 = test_str.strip('a') # 문자열 앞뒤의 'a' 제거
temp1

->'bbPythonbbb'

temp1.strip('b')

-> 'Python'
test_str_multi = "##***!!!##.... Python is powerful.!... %%!#..   "
test_str_multi.strip('*.#! %')

-> 'Python is powerful'
"\n This is very \n fast. \n\n".strip()

-> 'This is very \n fast.'

 


split(), strip() 활용

coffee_menu = " 에스프레소, 아메리카노,    카페라테   ,   카푸치노   "
coffee_menu_list = coffee_menu.split(',')

coffee_list = [] # 빈 리스트 생성
for coffee in coffee_menu_list:
    temp = coffee.strip() # 문자열의 공백 제거
    coffee_list.append(temp) # 리스트 변수에 추가
print(coffee_list) # 최종 리스트 출력

-> ['에스프레소', '아메리카노', '카페라테', '카푸치노']

 


find() - 문자열 찾기

tr_f = "Python code."

print("찾는 문자열의 위치:", str_f.find("Python"))
print("찾는 문자열의 위치:", str_f.find("code"))
print("찾는 문자열의 위치:", str_f.find("n"))
print("찾는 문자열의 위치:", str_f.find("easy")) #easy라는 문자열 존재 하지 않음 -> -1 반환

->
찾는 문자열의 위치: 0
찾는 문자열의 위치: 7
찾는 문자열의 위치: 5
찾는 문자열의 위치: -1
str_f_se = "Python is powerful, Python is easy to learn."

print(str_f_se.find("Python", 10, 30)) #시작 위치(start)와 끝 위치(end) 지정
print(str_f_se.find("Python", 35)) #찾기 위한 시작 위치(start) 지정

->
20
-1

 


startswith(), endswith() - 시작과 끝의 문자열이 해당 문자열인지 확인

str_se = "Python is pwerful, Python is easy to learn."

print("Python으로 시작?:", str_se.startswith("Python"))
print("is로 시작?:", str_se.startswith("is"))
print(".로 끝?:", str_se.endswith("."))
print("learn으로 끝?:", str_se.endswith("learn"))

->
Python으로 시작?: True
is로 시작?: False
.로 끝?: True
learn으로 끝?: False

 

 

 


replace() -  문자열 대체하기

str_a = 'Python is fast. Python is friendly. Python is open.'
print(str_a.replace('Python', 'IPython'))
print(str_a.replace('Python', 'IPython', 2))

->
IPython is fast. IPython is friendly. IPython is open.
IPython is fast. IPython is friendly. Python is open.

 

 


isalnum(), isspace()

print('acb1234'.isalnum()) #특수 문자나 공백이 아닌 문자와 숫자로 구성됨
print('    acb1234'.isalnum()) #문자열에 공백이 있음
print('    '.isspace()) #문자열이 공백으로만 구성됨
print('  1  '.isspace()) #문자열에 공백 외에 다른 문자가 있음

->
True
False
True
False

 

 

 

반응형

리스트(list)

요소를 삭제하거나 변경 가능(mutable(가변성)) ->append, del, remove, pop ...

서로 다른 type의 데이터를 담을 수 있다

list안에 list로 element를 표현할 수 있다.

list_data = [0,1,2,3,4,5,6,7,8,9]
del list_data[6]
print(list_data) -> [0, 1, 2, 3, 4, 5, 7, 8, 9]

 

insert() - 특정한 위치(인덱스)에 원소를 삽입

myFriends = ['James', 'Robert', 'List', 'Mary']
myFriends.insert(1, 'Pau)
print(myFriends) -> ['James', 'Paul', 'Robert', 'List', 'Mary']

 

remove() - 리스트 내 특정 원소를 삭제

pop() - 리스트 내 특정 인덱스의 원소를 삭제

a = [10,20,30,40,50,60,70,80,90,100]
a.pop(3) #del a[3] 와 동일
a.remove(90)
print(a) -> [10, 20, 30, 50, 60, 70, 80, 100]

 

List Sliding

[start:stop:step]
start : 시작index번호
stop : 끝나는 index번호(단, 포함하지 않음)
step : index간 step(간격)

list_data = [0,1,2,3,4,5,6,7,8,9]
print(list_data[:3])
print(list_data[7:])
print(list_data[::2])
print(list_data[::3])
print(list_data[1::2])
print(list_data[1:5:3])

[0, 1, 2]
[7, 8, 9]
[0, 2, 4, 6, 8]
[0, 3, 6, 9]
[1, 3, 5, 7, 9]
[1, 4]

 

append() - 리스트의 뒤에 새로운 원소를 삽입

a = [1, 2, 3]
a.append(4)
a
-> [1, 2, 3, 4]
a.append([5,6])
a
-> [1, 2, 3, 4, [5, 6]]

 

extend() - 리스트의 뒤쪽에 다른 리스트를 삽입

(extend(x)에서 x는 리스트만 올 수 있음, 원래의 a 리스트에 x 리스트를 더함)

a = [1,2,3]
a.extend([4,5])
a
-> [1, 2, 3, 4, 5]
b = [6, 7]
a.extend(b)
a
-> [1, 2, 3, 4, 5, 6, 7]

 

sort() - 리스트를 오름차순으로 정렬

list2 = [1, 5, 13, 8, 3, -7, 9, 11]
list2.sort()
print(list2)
-> [-7, 1, 3, 5, 8, 9, 11, 13]
list2.sort(reverse=True)
print(list2)
-> [13, 11, 9, 8, 5, 3, 1, -7]

 

index() - 리스트 내 특정 원소의 인덱스를 반환

a = [1,2,3]
a.index(3)
-> 2
a.index(1)
-> 0

 

count() - 리스트 내 특정 원소가 몇 개 포함되어 있는지 반환

a = [1,2,3,1]
a.count(1)
2

 


튜플(tuple)

list와 비슷하지만 요소를 삭제하거나 변경 불가능한 면에서 다르다 (immutable(불변성))

 

 # 투플의 요소는 변경 불가

tuple5[1] = 5
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-73-35d2428361b3> in <module>
----> 1 tuple5[1] = 5 # 투플의 요소는 변경 불가

TypeError: 'tuple' object does not support item assignment

 

count()

tuple7 = ('a','a','a','b','b','c','d')
tuple7.count('a')
-> 3

 

len() - 길이 

t1 = (1, 2, 'a', 'b')
len(t1)
-> 4

 


셋(set)

Set은 python 2.3부터 지원한 자료형으로, 집합에 관련된 것을 쉽게 처리하기 위해 만든 자료형이다

#중복 값을 갖지 못함

set1 = {1,2,3}
set1a = {1,2,3,3}
print(set1)
print(set1a)
-> {1, 2, 3}
-> {1, 2, 3}

 

set 활용 / 형변환

a = [1,2,3,4,5,5,5]
b = tuple(a)
c = set(a)
type(a)
-> list
b
-> (1, 2, 3, 4, 5, 5, 5)
c
-> {1, 2, 3, 4, 5}
type(c)
-> set

 


딕셔너리(dict)

데이터가 다양해지고 속성과 값들의 표현들이 많아져 단순 List나 tuple로 데이터를 표현하기가 힘들기 때문에 데이터들의 대응관계(속성과 값)를 나타낼 때는 딕셔너리(Dictionary)를 사용하는 것이 좋다

 

특정 key값에 대한 value값 뽑기

dict_data2 = {1:10, 2:20, 3:30, 4:40, 5:50}
print(dict_data2)
print(dict_data2[4])
-> {1: 10, 2: 20, 3: 30, 4: 40, 5: 50}
-> 40

 

value값에 list와 tuple을 넣을 수 있다. 하지만 key에는 tuple만 사용할 수 있다.

(list는 값이 변할 수 있기 때문에 key값으로 사용할 수 없다.)

mixed_dict = {1:10, 'dict_num' : {1:10, 2:20}, "dict_list_tuple" : {"A" : [11,12,13], "B" : (21,22,23)}, "dict_string" : "이것은 책입니다."}
mixed_dict
-> {1: 10,
 'dict_num': {1: 10, 2: 20},
 'dict_list_tuple': {'A': [11, 12, 13], 'B': (21, 22, 23)},
 'dict_string': '이것은 책입니다.'}

 

key-value 값 추가

country_capital = {"영국":"런던", "프랑스":"파리", "스위스":"베른","호주":"캔버라"}

country_capital["독일"]="베를린"
country_capital
-> {'영국': '런던', '프랑스': '파리', '스위스': '베른', '호주': '캔버라', '독일': '베를린'}

 

value값 변경

country_capital["호주"]="캔버라~"
country_capital
-> {'영국': '런던', '프랑스': '파리', '스위스': '베른', '호주': '캔버라~', '독일': '베를린'}

 

keys() - key값 뽑기

fruit_code = {"사과":101, "배":102, "딸기":103, "포도":104, "바나나":105}

print(fruit_code.keys())
-> dict_keys(['사과', '배', '딸기', '포도', '바나나'])

 

values() - value값 뽑기

print(fruit_code.values())
-> dict_values([101, 102, 103, 104, 105])

 

item() - Key와 Value의 쌍을 튜플로 묶은 값을 dict_items 객체로 반환

fruit_code.items()
-> dict_items([('사과', 101), ('배', 102), ('딸기', 103), ('포도', 104), ('바나나', 105)])
list(fruit_code.items())
-> [('사과', 101), ('배', 102), ('딸기', 103), ('포도', 104), ('바나나', 105)]

 

update() - 값 변경 또는 추가

(update받는 dict쪽에 해당 key값이 없으면 key-value가 추가되고 key값이 존재하면 대응되는 value값이 수정된다)

fruit_code = {"사과":101, "배":102, "딸기":103, "포도":104, "바나나":105}
fruit_code2 = {"오렌지":106, "수박":107}

fruit_code.update(fruit_code2)
fruit_code

-> {'사과': 101, '배': 102, '딸기': 103, '포도': 104, '바나나': 105, '오렌지': 106, '수박': 107}

 

key-value 삭제

del fruit_code2['수박']
fruit_code2
-> {'오렌지': 106}

 

in

a = {'name':'Jim', 'phone':'01012341234', 'birth': '0521'}
'name' in a
True
'email' in a
False
반응형

자바스크립트를 사용할 때 변수를 선언하기 위해 var를 많이 사용한다. 하지만 var는 많은 단점을 가지고 있기 때문에 사용을 지양하는 것이 좋다. 바로 hoising 같은 개념 때문인데 이와 관련해서는 이전에 포스팅해 놓은 아래 글을 참고 바란다.

https://ckprk.tistory.com/74?category=971162 

 

[javascript] var hoisting

hoisting이란 변수, 함수 선언을 최상단으로 끌어 올린다는 것이다. 즉 런타임시 어떤 변수를 출력하는데 변수선언이 되어있지 않음에도 불구하고 오류가 나지 않는다는 것이다. 예를 들어보자 con

ckprk.tistory.com

 

 

자 그럼 var, let, const 를 비교해보자

var name = "Sarah";
console.log(name); //Sarah
  
var name = "Jim"
console.log(name); //Jim

위 코드를 보면 var를 통해 name이라는 변수이름을 재사용하여 재정의 하고있다. 이렇게 var는 변수를 재정의, 재할당이 모두 가능하다는 특징을 가지고 있다.

 

 

let name = "Sarah";
console.log(name);
  
let name = "Jim"
console.log(name);

//Uncaught SyntaxError: Identifier 'name' has already been declared.

위 코드는 let을 통해 재선언을 하고있는데 주석처리된 에러를 보면 알 수 있듯이 name이라는 변수는 이미 선언이 되어있어서 재선언이 불가능하다

 

const name = "Sarah";
console.log(name);
  
const name = "Jim"
console.log(name);

//Uncaught SyntaxError: Identifier 'name' has already been declared.

const를 사용하여 변수선언 할 때도 let과 마찬가지로 재선언이 불가능하다

 

그러면 var와 const의 차이는 무엇일까?

var는 아래와 같이 재할당이 가능하고 const는 불가능하다는 것이다.

let name = "Sarah";
console.log(name); //Sarah
  
name = "Jim"
console.log(name); //Jim
const name = "Sarah";
console.log(name); //Sarah
  
name = "Jim"
console.log(name); //Uncaught TypeError: Assignment to constant variable.

 

쉽게 말해 let은 다른언어에서와 마찬가지로 일반적인 변수선언에 사용되고 const는 자바에서의 final 상수와 같이 값의 변경이 불가능하다

 

정리하면,

var : 재선언 가능 / 재할당 가능

let : 재선언 불가능 / 재할당 가능

const : 재선언 불가능 / 재할당 불가능

반응형

커넥션 풀(Connection Pool)이란 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool)속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 풀에 반환하는 기법을 의미한다.

필자는 tomcat-dbcp 라이브러리에서 제공하는 dbcp 방식을 포스팅 해보겠다.

 

먼저 준비과정이 필요하다

DB에 연동하여 사용하는 것이므로 이클립스에서 프로젝트 안에 WEB-INF라는 디렉터리안에 lib디렉터리가 보일 것이다. 여기에 각자 사용하는 DB시스템의 jar파일을 복사해 넣어야 한다. 필자는 mariadb client용 2.7.2 버전을 사용하므로 아래와 같이 넣었다.

그리고 두개의 xml파일이 필요하다

첫번째는 프로젝트를 생성하면 자동으로 생성되어지는 web.xml파일이다. 이 파일은 한마디로 jsp파일을 실행하기전에 준비작업 즉, 초기화하는 용도로 주로 사용된다.(tomcat container가 해당 애플리케이션에서 가장 먼저 찾아 읽는 파일이 web.xml 이다.)

 

web.xml을 더블클릭하고 아래와 같이 입력하면된다. (태그 부분만 추가로 넣어주면 된다.)

(<display-name>태그에 어플리케이션 명(프로젝트 명)이 와야함)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>dbcp</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
    <resource-ref>
         <description>Connection</description>
         <res-ref-name>jdbc/MariaDB</res-ref-name>
         <res-type>javax.sql.DataSource</res-type>
         <res-auth>Container</res-auth>
    </resource-ref>
  
</web-app>

*****************************************************************************************************************************

  <resource-ref> // 이 애플리케이션에서 참조하려는 자원이 무엇인가를 뜻하는 태그
         <description>Connection</description> //단순 설명란
         <res-ref-name>jdbc/MariaDB</res-ref-name> // 원하는 자원을 참조할 이름은(객체) jdbc/MariaDB
         <res-type>javax.sql.DataSource</res-type> // 자원의 타입은 javax.sql.DataSource
         <res-auth>Container</res-auth> // Container(tomcat container)에게 이 권한이 있다는 것 (tomcat Container에서 제공하는 dbcp 라이브러리를 사용하겠다는 의미)
    </resource-ref>

******************************************************************************************************************************

 

그리고 META-INF디렉터리에 또 하나의 xml파일을 만들어 넣어주어야 하는데 

META-INF에 마우스 올려놓고 우클릭 -> new -> other 로 들어가면 아래와 같은 창이 뜰 것이다

Next 누르고 파일명을 아래와 같이 설정하여 finish 누르면 

파일이 META-INF디렉터리에 생길것이다 그리고 아래와 같이 입력하여 저장하면 된다.

<Context>
  <Resource name="jdbc/MariaDB"
  auth="Container"
  type="javax.sql.DataSource"
  username="root"
  password="m1234"
  driverClassName="org.mariadb.jdbc.Driver"
  url="jdbc:mariadb://localhost:3306/test"
  maxActive="500"
  maxIdle="100"/>
</Context>

(url="jdbc:mariadb://localhost:3306/test" -> mariadb의 test db를 사용)

 

위와 같이 mariadb jar파일과 두개의 xml파일이 준비되었다면 커넥션 풀을 사용할 수 있다.

 

아래는 커넥션 풀을 사용하는 jsp코드 예시이다

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="javax.sql.*"%>
<%@ page import="javax.naming.*"%>

<%
	Connection conn = null;
	String sql = "select * from student order by num";

	try {
		Context init = new InitialContext();
		Context env = (Context) init.lookup("java:comp/env");
		DataSource ds = (DataSource) env.lookup("jdbc/MariaDB");
		conn = ds.getConnection();
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		ResultSet rs = pstmt.executeQuery();
		while(rs.next()){
			out.println("<h3>" + rs.getInt(1) + ", "
					+ rs.getString(2) + "</h3>");
		}
		rs.close();
	} catch (Exception e) {
		out.println("<h3>데이터 가져오기 실패.</h3>");
		e.printStackTrace();
	}
%>


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

위처럼 jsp파일이 수십개 된다고 생각해보자 그 수십개의 jsp파일이 모두 db와 연동하여 데이터를 처리해야한다면 그 때마다 db에 접속하는 반복적인 코드들이 모든 파일에 들어가야 할 것이다. 하지만 커넥션 풀을 사용하면 풀안에 담긴 커넥션들 중에 적당한 한개의 커넥션을 할당받아 사용하고 수행 완료하면 반환하는 과정을 거치기 때문에 관리하기 용이하다. 

 

반응형

+ Recent posts