How We Coding

- 출처 : http://blog.naver.com/PostView.nhn?blogId=kimsung9k&logNo=110121881497


<비트 연산을 이용한 정수의 산술연산 >


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <cstdio>
#include <vector>
using namespace std;
 
long long plus( long long a, long long b )
{
    long long xor1 = a^b;
    long long and1 = a&b;
    and1 = and1 << 1;
    while( ( and1&xor1 ) != 0 )
    {
        long long txor = and1^xor1;
        long long tand = and1&xor1;
        long long uand = tand << 1;
        and1 = uand;
        xor1 = txor;
    }
    return xor1^and1;
}
 
long long minus( long long a, long long b )
{
    long long first = a^b;
    long long second = a^(a|b);
    first = first^second;
    return plus( first, plus( (~second), 1 ) );
}
 
long long mult( long long a, long long b )
{
    bool a_is_minus = false;
    bool b_is_minus = false;
    bool is_odd = false;
 
    if( a < 0 ){
        a_is_minus = true;
        a = ~minus( a,1 );
    }
    if( b < 0 ){
        b_is_minus = true;
        b = ~minus( b,1 );
    }
    if( (b&1== 1 )
        is_odd = true;
    long long mult_a = 0LL;
    forint i=1; i < 32; i=plus( i,1 ) ){
        b = b >> 1;
        if( (b & 1== 1 )
            mult_a = plus( mult_a, (a << i) );
    }
    if( is_odd )
        mult_a = plus( mult_a, a );
    if( a_is_minus^b_is_minus )
        mult_a = plus( ~mult_a, 1 );
    return mult_a;
}
 
int main()
{
    int a, b;
    scanf("%d%d"&a, &b);
    printf("%lld\n", mult(a, b));
    return 0;
}
 
 
cs


>> 매개변수와 리턴타입을 모두 long long 으로 변경하고, 46라인을 i < 32 로 변경하니, long long 까지 처리가 가능하였다.

>> a = 100000000, b = 100000000 을 입력으로 주면 10000000000000000 이 출력된다. 

< About split() 메서드 (String) >


 토큰 문자열을 주면 그거대로 쪼개져 스트링의 배열을 리턴한다고만 알고 있었다.


 그런데 "(123x456)" 이란 문자열이 있는데, 123 과 456 문자열만 따로 취하고 싶어서 split("x") 를 하는데 안쪼개진다.


 split("(") 도 안쪼개진다... 


 당황스러웠다. 그래서 구글링...!!


 알고보니 토큰 문자열은 정규식으로 이루어진 문자열이였다. 어쩐지 미리보기로 보이는 파라미터가 regex 였다 싶었는데...


 String[] s = imgSize.split("[^0-9]");


위와 같이 스플릿을 하면, 


s[1] 에는 123이, s[2] 에는 456 이 저장되게 된다.



참고 : http://mparchive.tistory.com/45

- 공백을 포함한 문자열 입력받기 


scanf("%[^\n]\n", s);


- 문자열 입력 조건을 통하여 처리하는 방법으로 문자열 조건은 [] 를 통하여 넣을 수 있다.

- ^ 는 제외를 의미. 즉 \n를 제외한 문자열을 입력받고 문자열의 끝은 \n 로 처리하는 문자열이란 뜻이 된다.



- 문자열 조건 관련 몇몇 예제


1)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[12345]s", str);
    printf("%s\n", str);
    return 0;
}
cs

>> 4567 을 입력하면 45가 출력된다.


2)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[^12345]s", str);
    printf("%s\n", str);
    return 0;
}
cs

>> 6745 를 입력하면 67이 출력된다.

>> ^ 는 []안의 문제를 제외한 나머지 문자만 인식한다.


3) 

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[0-9]s", str);
    printf("%s\n", str);
    return 0;
}
cs


>> 0-9 는 0123456789 를의미한다.

>> 123ab 를 입력하면 123이 출력된다.

>> 1a2b3c 를 입력하면 1만 출력된다.

>> ab123 을 입력하면 이상한 결과가 나온다...


4)

1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() 
{
    char str[100];
    scanf("%[a-zA-Z]s", str);
    printf("%s\n", str);
    return 0;
}
cs


>> 영문자만 입력을 받는다.



줄바꿈을 입력받지 않기 때문에, 편리한 방법이지만, 각 줄의 앞 뒤에 있는 공백은 무시하고 입력을 받아들이게 된다.

- 따라서 빈 줄은 입력받을 수 없다.

- 또한, 공백으로 시작하는 경우, 공백을 무시하고 문자부터 입력받게 된다.



참고1 : 백준 슬라이드


참고2 : http://blog.daum.net/_blog/BlogTypeView.do?blogid=09ehJ&articleno=18230445&categoryId=789155

동영상 강좌 : http://pythonkim.tistory.com/notice/77


# Day_03_05_slicing.py


- 다른 파일의 어떤 내용을 사용하고 싶을 때.


1
import Day_03_05_import
cs


>> Day_02_02_list.py 파일을 불러오기. (.py 는 생략)

>> 위 파일에서 선언한 변수, 함수를 모두 사용할 수 있다. 해당 파일의 내용을 복붙한것과 같은 효과..!!


>> 하지만 우리는 makeRandoms() 의 사용만 원한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import random
 
 
def makeRandoms():
    a = []
    for i in range(10):
        a.append(random.randrange(100))
    return a
 
 
= "unused"
 
 
def a():
    pass
 
 
def b():
    pass
 
 
def c():
    pass
cs



>> 우리가 불러올 파일이 이런식으로 구성되어 있다고 가정하자.

>> makeRandoms() 함수만을 가져다 쓰고 싶다.


>> 하지만 위와 같이 해당 파일을 통채로 import 하면 복붙의 효과이기 때문에

     변수 s, a(), b(), c() 도 가져오게 된다.



- 원하지 않는 내용들을 블럭지정 후 Edit - Indent Selection 을 통해 블럭 내용들을 한번에 탭키 처리 한다.

- 그리고 이것들을 사용하지 않기 위해 아래의 1번 라인을 추가 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
if __name__ == '__main__':
    s = "unused"
    
    
    def a():
        pass
    
    
    def b():
        pass
    
    
    def c():
        pass
cs


>> 파이썬에는 main() 가 존재하지 않는다. 그래서 이를 흉내낼 필요가 있다. 

>> 위와 같이 여러개의 파일이 같이 사용될 때 특히..!!

>> 그것을 흉내내는 변수가 __name__ 이다.


### __main__ 은 첫번째 실행되는 파일을 의미한다.

### __name__ : 파일별로 존재하는 파일 이름


- 현재 파일에 print(__name__) 을 추가하고, import 한 파일에도 print(__name__) 을 추가한 다음 내용을 확인해보자.


1
2
3
import Day_03_05_import
 
print(__name__)
cs


>> 실행결과


1
2
Day_03_05_import :  Day_03_05_import
__main__
cs


>> 1 : import 한 파일에서 실행된 print(__name__)

>> 2 : 현재 파일에서 실행된 print(__name__), 즉 첫 번째로 실행된 파일이다.



- import 한 파일의 함수 사용하기


1
2
3
Day_03_05_import.random.seed(1)
= Day_03_05_import.makeRandoms()
print(a)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs



- 슬라이싱


1
print(a[0:5])   # [17, 72, 97, 8, 32]
cs


>> [0, 5) 까지의 데이터들을 의미한다. 

>> : 을 이용한 문법을 슬라이싱 이라고 한다.


# 문제

# 뒤쪽 절반 출력하기.


1
print(a[len(a)//2:])
cs


>> print(a[len(a)//2:len(a)]) 도 가능하다.


- 생략

 

1
print(a[:]) # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> 이런식으로 생략이 가능하다.

>> : 앞의 생략은 맨 앞부터,  : 뒤의 생략은 맨 마지막 까지를 의미한다.



- 슬라이싱을 range() 처럼 사용할 수 있다.


1
2
print(a[::2])   # [17, 97, 32, 63, 57]
print(a[::3])   # [17, 8, 63, 60]
cs


>> 1 : 2칸씩 건너뛴 요소

>> 2 : 3칸씩 건너뛴 요소



- 홀수번째, 짝수번째 요소 출력하기


1
2
3
4
5
# 짝수번째 요소만 출력
print(a[::2])   # [17, 97, 32, 63, 57]
 
# 홀수번째 요소만 출력
print(a[1::2])  # [72, 8, 15, 97, 60]
cs


>> 5 : 1번째 요소부터 2칸씩 건너뛰기..!!



- 거꾸로 출력하기


1
print(a[::-1])  # [60, 57, 97, 63, 15, 32, 8, 97, 72, 17]
cs



1
2
3
4
5
print(a[len(a)-1:0:-1]) # [60, 57, 97, 63, 15, 32, 8, 97, 72]
 
print(a[len(a)-1:-1:-1])    # []
 
print(a[-1:-1:-1])          # []
cs


>> 1 : 마지막 요소만 제외하고 출력이 된다.

>> 3, 5 라인은 같은 코드이다.



- 거꾸로 홀수번째, 짝수번째 요소만 출력하기


1
2
3
4
# 거꾸로 홀수번째 요소만 출력하기
print(a[:]) # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(a[::-2])      # [60, 97, 15, 8, 72]
print(a[-2::-2])    # [57, 63, 32, 97, 17]
cs




- 얕은복사 review


1
2
3
4
5
6
7
= a
= a
a[0= -1
 
print(a)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(b)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(c)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> a[0] 를 변경했는데, b와 c도 변경됨



- 깊은복사 review


1
2
3
4
5
6
7
8
9
10
11
12
= a
= a
= a.copy()
= a[:]
a[0= -1
 
print(a)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(b)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(c)    # [-1, 72, 97, 8, 32, 15, 63, 97, 57, 60]
 
print(d)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
print(e)    # [17, 72, 97, 8, 32, 15, 63, 97, 57, 60]
cs


>> 3 : 이전에 공부한 깊은복사 방법

>> 4 : 슬라이싱을 이용한 깊은복사 // 슬라이싱은 안쪽에 있는 것을 뽑아내는 과정이기 때문에 항상 복사본을 만든다.



- 짝수번째 요소 출력하기


1
2
3
4
5
6
7
for i in range(0len(a), 2):
    print(a[i], end=' ')        # -1 97 32 63 57 
print()
 
for i in a[::2]:
    print(i, end=' ')           # -1 97 32 63 57 
print()
cs


>> 예전에는 1-3과 같이 하였으나, 이젠 5-7과 같이 하면 된다.




'Language > Python' 카테고리의 다른 글

<3-3> JSON  (0) 2018.03.05
<3-2> Set 과 Dictionary  (0) 2018.03.02
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

- 실수형 값을 출력할 때, printf() 함수에서 서식문자를 %lf 혹은 %f 로 준다고 배었고, 

   기본적으로 소숫점 아래 6자리로 알고 있다. 소수점을 조정하려면 10 번 라인처럼 해야하는데,

   %g 라는 서식문자를 사용하면 그럴 필요가 없다...!!!!



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
int main()
{
    double f=3.14;
 
    printf("%lf\n", f);
    // 3.140000
   
    printf("%.2lf\n", f);
    // 3.14
 
    printf("%g\n", f);
    // 3.14
 
    return 0;
}
cs


<3-3> JSON

Language/Python2018. 3. 5. 22:34

동영상 강의 : http://pythonkim.tistory.com/notice/77


# Day_03_03_json.py


- 파이선에서는 json 모듈이 있다.


1
import json
cs


http://www.jsontest.com 에 접속해보자


- JSON : JavaScript Object Notation 의 약자.


>> Object 를 문자열로 변환하고, 그 문자열을 다시 Object 로 복원하는 방법.


-


1
j1 = '{"ip": "8.8.8.8"}'

cs

 

>> dictionary 를 포장하고 있는 문자열.

>> 우리는 이것을 dictionary 로 변환할 수 있다. dictionary 가 들어있기 때문..!!


-

1
2
3
4
5
6
7
import json
 
j1 = '{"ip": "8.8.8.8"}'
d1 = json.loads(j1)
print(d1)           # {'ip': '8.8.8.8'}
print(type(d1))     # <class 'dict'>
print(d1['ip'])     # 8.8.8.8
cs



>> 4 : json.loads() 를 통해 json 형태의 문자열을 읽어올 수 있다.

>> json.load() 는 파일로부터 읽어올 때 사용한다.



# 문제

# j2를 해석해서 value 를 출력하기


1
2
3
4
5
6
7
8
9
10
11
12
j2 = '''{
   "Accept-Language": "en-US,en;q=0.8",
   "Host": "headers.jsontest.com",
   "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
   "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
}'''
 
d2 = json.loads(j2)
print(type(d2))     # <class 'dict'>
 
for k, v in d2.items():
    print(k, v)
cs


>> 실행결과

1
2
3
4
Accept-Language en-US,en;q=0.8
Host headers.jsontest.com
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
cs



- json.dumps()


1
2
3
j3 = json.dumps(d2)
print(type(j3))
print(j3)
cs


>> 실행결과


1
2
<class 'str'>
{"Accept-Language": "en-US,en;q=0.8", "Host": "headers.jsontest.com", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"}
cs


>> object 를  str 로 변환한다.




- 이전에 만든 kma.csv 파일을 열어보자. (기본적으로 엑셀과 연동이 된다.)

>> 인코딩 문제로 글자가 깨지는 경우


1
= open('Data/kma.cvs''w', encoding='utf-8')
cs


>> 여기에서 인코딩을 지우면 된다고 하는데, 맥에서는 안된다...


...




# Day_03_04_json_kma.py



1
2
3
4
5
6
7
8
9
10
import json
import requests
 
url = 'http://www.kma.go.kr/DFSROOT/POINT/DATA/top.json.txt'
recvd = requests.get(url)
 
print(recvd.text)
 
text = bytes(recvd.text, 'iso-8859-1').decode('utf-8')
print(text)
cs


>> 실행결과


1
2
[{"code":"11","value":"서울특별시"},{"code":"26","value":"부산광역시"},{"code":"27","value":"대구광역시"},{"code":"28","value":"인천광역시"},{"code":"29","value":"광주광역시"},{"code":"30","value":"대전광역시"},{"code":"31","value":"울산광역시"},{"code":"41","value":"경기도"},{"code":"42","value":"강원도"},{"code":"43","value":"충청북도"},{"code":"44","value":"충청남도"},{"code":"45","value":"전라북도"},{"code":"46","value":"전라남도"},{"code":"47","value":"경상북도"},{"code":"48","value":"경상남도"},{"code":"50","value":"제주특별자치도"}]
[{"code":"11","value":"서울특별시"},{"code":"26","value":"부산광역시"},{"code":"27","value":"대구광역시"},{"code":"28","value":"인천광역시"},{"code":"29","value":"광주광역시"},{"code":"30","value":"대전광역시"},{"code":"31","value":"울산광역시"},{"code":"41","value":"경기도"},{"code":"42","value":"강원도"},{"code":"43","value":"충청북도"},{"code":"44","value":"충청남도"},{"code":"45","value":"전라북도"},{"code":"46","value":"전라남도"},{"code":"47","value":"경상북도"},{"code":"48","value":"경상남도"},{"code":"50","value":"제주특별자치도"}]
cs


>> text 데이터는 딕셔너리 리스트의 형태이다..!!


>> 인코딩이 깨지는 것에 대한 해결책은 9번 라인으로 해결.

>> 4 라인의 url 을 브라우저에서 직접 실행시 json 형식의 내용을 그대로 확인할 수 있다. (맥에서는 여전히 깨져서 나온다..ㅜ)



< JSON 에서의 기본 규칙 >

- 맨 처음 나오는 것은 최상위 객체로 배열(파이썬에서는 리스트) 아니면 사전의 형태.

- int 값을 json 으로 전달할 수 없다.



# 문제

# 코드와 도시 이름만 출력해 보기.


1
2
3
4
5
6
items = json.loads(text)
print(items)
print(type(items))   # <class 'list'>
 
for item in items:
    print(item['code'], item['value'])
cs


>> 실행결과


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[{'code': '11', 'value': '서울특별시'}, {'code': '26', 'value': '부산광역시'}, {'code': '27', 'value': '대구광역시'}, {'code': '28', 'value': '인천광역시'}, {'code': '29', 'value': '광주광역시'}, {'code': '30', 'value': '대전광역시'}, {'code': '31', 'value': '울산광역시'}, {'code': '41', 'value': '경기도'}, {'code': '42', 'value': '강원도'}, {'code': '43', 'value': '충청북도'}, {'code': '44', 'value': '충청남도'}, {'code': '45', 'value': '전라북도'}, {'code': '46', 'value': '전라남도'}, {'code': '47', 'value': '경상북도'}, {'code': '48', 'value': '경상남도'}, {'code': '50', 'value': '제주특별자치도'}]
<class 'list'>
11 서울특별시
26 부산광역시
27 대구광역시
28 인천광역시
29 광주광역시
30 대전광역시
31 울산광역시
41 경기도
42 강원도
43 충청북도
44 충청남도
45 전라북도
46 전라남도
47 경상북도
48 경상남도
50 제주특별자치도
cs

 




'Language > Python' 카테고리의 다른 글

<3-4> __name__, 리스트 슬라이싱  (0) 2018.03.08
<3-2> Set 과 Dictionary  (0) 2018.03.02
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

동영상 강의 : http://pythonkim.tistory.com/notice/77



# Day_03_02_dict.py


- set 과 dictionary


1
2
3
4
5
= {}
print(type(a), a)  # <class 'dict'> {}
 
= {1}
print(type(b), b)   # <class 'set'> {1}
cs


>> 중괄호를 이용한 컬렉션은 두가지 : set 과 dictionary

>> dictionary 가 set 보다 백만배 중요하다고 한다.



- dictionary 의 초기화


1
2
= {1:2}
print(type(c), c)   # <class 'dict'> {1: 2}
cs




- Set


1
2
3
4
5
= {123123123}
print(type(d), d)   # <class 'set'> {1, 2, 3}
 
= [123123123]
print(type(e), e)   # <class 'list'> [1, 2, 3, 1, 2, 3, 1, 2, 3]
cs


>> set은 중복된 데이터를 허용하지 않는다.

>> 반면, list 는 중복된 데이터를 허용한다.



# 문제

# 리스트에 들어있는 중복된 데이터를 제거하기


1
2
3
4
5
= [123123123]
print(type(e), e)   # <class 'list'> [1, 2, 3, 1, 2, 3, 1, 2, 3]
 
= list(set(e))
print(e)            # [1, 2, 3]
cs


>> set(e) 의 결과는 set 이므로 list 로 캐스팅.



- Dictionary


- 초기화


1
2
= {'color''red''price'100}
print(d)            # {'color': 'red', 'price': 100}
cs


>> key: value 의 쌍으로 구성된다.



- 초기화 2


1
2
3
4
= dict(color='red', price=100)
print(d)            # {'color': 'red', 'price': 100}
print(d['color'])   # red
print(d['price'])   # 100
cs


>> 위와 아래의 차이점은 거의 없다고 보면 된다.

>> 아래의 방법으로 초기화 하는 것을 선호한다고 한다. dict() 함수를 이용해서 dictionary 만드는 방법

>> key 값에 ' ' 를 생략하면 자동으로 포함이 된다.

>> 리스트는 요소들의 순서가 보장되지만, 딕셔너리는 순서를 보장하지 않는다.


>> 3, 4 : dictionary 요소 접근



 - dictionary 에서 데이터 삽입


1
2
3
4
5
6
# 데이터 삽입
d['title'= 'pen'
print(d)        # {'color': 'red', 'price': 100, 'title': 'pen'}
 
d['title'= 'bread'
print(d)        # {'color': 'red', 'price': 100, 'title': 'bread'}
cs


>> 2 : insert

>> 4 : update (title 이란 키값이 이미 존재하므로..!!)

>> dictionary 는 키값의 중복을 허용하지 않는다..!!



-

1
2
3
print(d.keys())     # dict_keys(['color', 'price', 'title'])
print(d.values())   # dict_values(['red', 100, 'bread'])
print(d.items())    # dict_items([('color', 'red'), ('price', 100), ('title', 'bread')])
cs



# 문제

# keys, values, items 를 for문과 연결해서 처리해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
for k in d.keys():
   print(k, d[k])
print('-'*10)
 
for v in d.values():
    print(v)
print('-'*10)
 
for i in d.items():
    print(i, i[0], i[1])
print('-'*10)
 
for k, v in d.items():
    print(k, v)
cs


>> 2 : 키값을 통해 value 를 알 수 있다.

>> 5 : value 만으로는 아무것도 할 수 없다.

>> 9 : i 의 결과는 튜플이다. 그렇기 때문데, 13-14와 같은 형태로 이용을 한다.


>> 실행결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
color red
price 100
title bread
----------
red
100
bread
----------
('color', 'red') color red
('price', 100) price 100
('title', 'bread') title bread
----------
color red
price 100
title bread
cs

  


- enumerate()


1
2
for i in enumerate(d.items()):
    print(i)
cs


>> 인덱스를 포함시킨 튜플의 형태가 된다.


>> 실행결과

1
2
3
(0, ('color', 'red'))
(1, ('price', 100))
(2, ('title', 'bread'))
cs



- 튜플의 괄호 없애기


1
2
for i in enumerate(d.items()):
    print(i[0], i[1][0], i[1][1])
cs


>> 실행결과

1
2
3
0 color red
1 price 100
2 title bread
cs



-

1
2
3
4
5
# for i, k, v in enumerate(d.items()):
#     print(i, k, v)
 
for i, (k, v) in enumerate(d.items()):
    print(i, k, v)
cs


>> 1 은 에러 : 하나의 인덱스와 하나의 튜플을 던져주므로 4와 같이 받아야 한다. (튜플의 요소는 2개인 상태)



- 딕셔너리를 통채로 전달해서 키값을 출력하는 방법


1
2
for k in d:
    print(k)
cs


>> 실행결과


1
2
3
color
price
title
cs


>> 이러한 이유로 d.keys() 를 사용하지 않는다.

'Language > Python' 카테고리의 다른 글

<3-4> __name__, 리스트 슬라이싱  (0) 2018.03.08
<3-3> JSON  (0) 2018.03.05
<3-1> 파일 입출력  (0) 2018.02.23
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15

< 예제코드 >


- 7라인에서 n 에 20을 대입한다면...?


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
   int i, n;
   scanf("%d"&n);
   int *arr;
   arr = (int *)malloc(sizeof(int* n);
 
   printf("%d\n"sizeof(arr));
   arr[1= 1;
   arr[198= 2;
   printf("(%d, %d)\n", arr[1], arr[198]);
 
   for(i=0; i<200; i++)
       printf("%d: %d\n", i, arr[i]);
 
   free(arr);
 
   return 0;
}
cs


>> 7 라인에서 n에 20을 입력한다.

>> 하지만 놀랍게도(?) 14 라인의 실행결과는 (1, 2) 이다. segmentation fault 가 안뜬다.

>> 그래서 16-17의 실행결과를 확인해보니.. 값을 할당하지 않은 곳은 0으로 초기화가 되어 있고, 인덱스가 1인 곳에는 1, 인덱스가 198인 곳에는 2가 저장되어있다.

     그래서 검색을 해봤다.


- 배열의 크기를 넘어서 사용하게 되면...

>> 아래 블로그에서 원하는 답변을 얻을 수 있었다.


http://blog.naver.com/PostView.nhn?blogId=tipsware&logNo=221054714926



>> 결론만 몇가지 말하면, 문법상 오류는 아니며, 예외처리는 개발자가 알아서 해야한다고 한다.

>> 또한, 이렇게 코딩을 해도 문제가 없다고 넘어가면, 돌아오는 것은 버그 라고 한다..



- 이 의문은 같이 스터디를 하는 동생의 질문에서 시작되었다.

- 블로그에서 관련내용을 다시 잘 정리한 것 같다.


- http://www.crocus.co.kr/1171?category=278489 

동영상 강의 : http://pythonkim.tistory.com/notice/77


# Day_03_01_file.py


- 파일에는 두가지 종류의 파일이 있다. 우리가 읽을 수 있는 파일(텍스트 파일)과 읽을 수 없는 파일(바이너리 피알)..!!


- 우선 Data 폴더를 만들고 텍스트 파일 하나를 만들자.


김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다.


>> 위의 시를 poem.txt 파일에 복붙하쟈.



- open() , close()


1
2
3
4
5
6
7
8
def read_1(filename):
    f = open(filename, 'r')
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 7 : 경로설정을 잘 해줘야한다. 현재 디렉토리에 있는 Data 폴더에 있는 poem.txt 라는 파일.

>> 프로젝트 폴더가 현재 디렉토리라고 여겨진다.


>> 2 : open() 에서의 옵션 'r' >> 파일을 읽겠다는 뜻.

>> 4 : open() 을 하고 볼일을 다 봤으면 항상 close() 를 해줘야한다.


- 경로에는 절대경로와 상대결로가 있다.

>> 절대경로 : 경로의 풀네임

>> 상대경로 : 현재 경로 기준으로 판단. // . 은 현재 디렉토리, // .. 은 상위 디렉토리

>> 일반적으로 상대경로를 많이 사용한다고 한다.


- 경로를 잘 설정했는데도 에러가 발생했다면 인코딩 문제를 의심해볼 수 있다.


1
= open(filename, 'r', encoding='utf-8')
cs


>> 세번째 옵션으로 인코딩 옵션을 설정한다.

>> 현재 전 세계적으로 텍스트파일에 대한 표준은 utf-8 이라고 한다.

>> html 에서 기본적으로 이것을 사용한다고 한다.



- readlines()


1
2
3
4
5
6
7
8
9
10
11
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
    print(lines)
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 4, 5 라인 추가. // readline 과 혼동하지 말자.

>> 실행결과

['김인육, 사랑의 물리학\n', '\n', '질량의 크기는 부피와 비례하지 않는다\n', '\n', '제비꽃같이 조그마한 그 계집애가\n', '꽃잎같이 하늘거리는 그 계집애가\n', '지구보다 더 큰 질량으로 나를 끌어당긴다.\n', '순간, 나는\n', '뉴턴의 사과처럼\n', '사정없이 그녀에게로 굴러 떨어졌다\n', '쿵 소리를 내며, 쿵쿵 소리를 내며\n', '\n', '심장이\n', '하늘에서 땅까지 아찔한 진자운동을 계속하였다\n', '첫사랑이었다.']



- 따로따로 출력을 해보자

1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line)
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs

>> 6, 7 라인의 변경

>> 실행결과


김인육, 사랑의 물리학




질량의 크기는 부피와 비례하지 않는다




제비꽃같이 조그마한 그 계집애가


꽃잎같이 하늘거리는 그 계집애가


지구보다 더 큰 질량으로 나를 끌어당긴다.


순간, 나는


뉴턴의 사과처럼


사정없이 그녀에게로 굴러 떨어졌다


쿵 소리를 내며, 쿵쿵 소리를 내며




심장이


하늘에서 땅까지 아찔한 진자운동을 계속하였다


첫사랑이었다. 


>> 줄바꿈이 심하다. 기본적으로 문자열 내부에 개행을 포함하며, print() 또한 개행을 포함하기 때문이다.



- 7 라인의 print() 에서 end='' 옵션을 추가해보쟈


1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line, end='')
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 실행결과

김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다. 


>> 하지만 파일을 읽어온 목적이 화면에 출력하는 것은 아니므로, 위와 같은 행위는 바람직하지 않다고 하신다.

>> 출력은 눈으로 확인용일 뿐, 중요하진 않다.



- strip() 사용하기


>> 개행문자가 필요한지 아닌지는 상황에 따라 다를 것이다.

>> 여기서는 필요 없어보인다. 그래서 strip() 을 사용

>> strip() : 문자열 양 끝에 있는 공백을 제거


1
2
3
4
5
6
7
8
9
10
11
12
13
def read_1(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    for line in lines:
        print(line.strip())
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_1(filename)
cs


>> 7 라인과 같이 사용한다.



- strip() 사용법


1
2
3
4
5
temp = '\t\t\n\n   apple koong   \n\n\t\t'
print('[{}]'.format(temp))
 
temp = temp.strip()
print('[{}]'.format(temp))
cs


>> 2 의 실행결과

[


   apple koong   


]


>> 5 의 실행결과

[apple koong]


>> 문자열 양 끝의 모든 공백들이 제거되었다.




- 파일읽기 2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def read_2(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    while True:
        line = f.readline()
        # if len(line) == 0: break; # EOF
        if not line: break;
        print(line.strip())
 
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_2(filename)
cs


>> 5 : readline() 함수는 한줄씩 읽어온다.

>> 6 : EOF 를 만나면 line 의 길이는 0이 된다. 하지만 7 라인과 같은 코딩을 선호한다고 한다.

>> 7 : Python 에서는 비어있는 것에 대해 false 로 판단한다.



- 파일읽기 3


1
2
3
4
5
6
7
8
9
10
11
def read_3(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    for line in f:
        print(line.strip())
 
    f.close()
 
 
filename = 'Data/poem.txt'
read_3(filename)
cs


>> 4 : for in 문에서 in 다음에는 이터러블한 것이라면 올 수 있다. 이처럼 파일도 올 수 있다.

>> EOF 를 만나면 알아서 끝난다.

>> 가장 심플한 코드.



- 파일읽기 4 : with 구문 사용


1
2
3
4
5
6
7
8
9
10
11
def read_4(filename):
    with open(filename, 'r', encoding='utf-8') as f:
 
        for line in f:
            print(line.strip())
 
        # f.close()
 
 
filename = 'Data/poem.txt'
read_4(filename)
cs


>> 2 : with 구문 사용, as f: f 라는 별칭까지 준다.

>> 7 : close() 가 필요가 없다. with 구문의 장점(자동으로 호출이 된다.)



- 파일읽기 5

- 일반적으로 파일을 다루는 코드 (리스트에 넣어서 처리)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 일반적으로 파일을 다루는 코드.
# 리스트에 넣어서 처리
def read_5(filename):
    lines = []
    with open(filename, 'r', encoding='utf-8') as f:
        for line in f:
            # print(line.strip())
            lines.append(line.strip())
 
    return lines
 
 
filename = 'Data/poem.txt'
lines = read_5(filename)
cs


>>



- readlines() 가 존재하는 이유.


1
2
3
4
5
6
7
8
9
10
11
12
def read_readlines(filename):
    f = open(filename, 'r', encoding='utf-8')
 
    lines = f.readlines()
 
    f.close()
    return ''.join(lines)
 
 
filename = 'Data/poem.txt'
text_all = read_readlines(filename)
print(text_all)
cs


>> join() 을 호출하기 위해 존재한다고 한다.

>> read_readlines() 가 리턴한 데이터의 타입은 문자열..!!

>> join() 의 역할은 리스트 안에 들어있는 문자열들을 한번에 결합

>> 하나의 변수로 파일의 내용을 다루고자 할 때 readlines() 를 사용한다.


>> 실행결과

김인육, 사랑의 물리학


질량의 크기는 부피와 비례하지 않는다


제비꽃같이 조그마한 그 계집애가

꽃잎같이 하늘거리는 그 계집애가

지구보다 더 큰 질량으로 나를 끌어당긴다.

순간, 나는

뉴턴의 사과처럼

사정없이 그녀에게로 굴러 떨어졌다

쿵 소리를 내며, 쿵쿵 소리를 내며


심장이

하늘에서 땅까지 아찔한 진자운동을 계속하였다

첫사랑이었다. 



cf) 


1
return '***'.join(lines)
cs


>> 실행결과


김인육, 사랑의 물리학

***

***질량의 크기는 부피와 비례하지 않는다

***

***제비꽃같이 조그마한 그 계집애가

***꽃잎같이 하늘거리는 그 계집애가

***지구보다 더 큰 질량으로 나를 끌어당긴다.

***순간, 나는

***뉴턴의 사과처럼

***사정없이 그녀에게로 굴러 떨어졌다

***쿵 소리를 내며, 쿵쿵 소리를 내며

***

***심장이

***하늘에서 땅까지 아찔한 진자운동을 계속하였다

***첫사랑이었다. 




- split() 과 join()


1
2
3
4
5
6
= 'AA,BB,CC'
= a.split(',')
print(b)            # ['AA', 'BB', 'CC']
 
= ''.join(b)
print(c)            # AABBCC
cs


>> 3, 6 의 실행결과는 주석으로 확인.

>> spit() 의 결과는 리스트



- 파일 쓰기


1
2
3
4
5
6
7
8
def write():
    f = open('Data/write.txt''w', encoding='utf-8')
    f.write('Hello ')
    f.write('Python')
    f.close()
 
 
write()
cs



>> Data 폴더에 write.txt 파일이 생성되고, 'Hello Python' 문자열이 저장되어 있다.



- command 키 누른 상태로 마우스를 open() 위에 가져다 놓기 (win 에서는 ctrl)

>> open() 에 대한 설명을 볼 수 있다.



- 기상청 날씨정보를 파싱 후 파일에 저장


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import re
 
url = 'http://www.weather.go.kr/weather/forecast/mid-term-rss3.jsp?stnId=108'
recvd = requests.get(url)
 
locations = re.findall(r'<location wl_ver="3">.+?</location>', recvd.text, re.DOTALL)
 
= open('Data/kma.csv''w', encoding='utf-8')
 
def findData():
    for loc in locations:
        prov = re.findall(r'<province>(.+)</province>', loc)
        city = re.findall(r'<city>(.+)</city>', loc)
        data = re.findall(r'<data>(.+)</data>', loc, re.DOTALL)
 
        for datum in data:
            mode = re.findall(r'<mode>(.+?)</mode>', datum)
            tmEf = re.findall(r'<tmEf>(.+?)</tmEf>', datum)
            wf   = re.findall(r'<wf>(.+?)</wf>', datum)
            tmn  = re.findall(r'<tmn>(.+?)</tmn>', datum)
            tmx  = re.findall(r'<tmx>(.+?)</tmx>', datum)
            reli = re.findall(r'<reliability>(.+?)</reliability>', datum)
 
            row = '{},{},{},{},{},{},{},{}'.format(prov[0], city[0], mode[0], tmEf[0], wf[0], tmn[0], tmx[0], reli[0])
            print(row)
            f.write(row)
            f.write('\n')   # 개행문자는 자동으로 처리되지 않으므로.
 
 
findData()
f.close()
cs


'Language > Python' 카테고리의 다른 글

<3-3> JSON  (0) 2018.03.05
<3-2> Set 과 Dictionary  (0) 2018.03.02
<2-3> 기상청의 전국 날씨정보 파싱, 외부 모듈 추가  (0) 2018.02.22
<2-2> 리스트, 튜플  (0) 2018.02.15
<2-1> 제어문과 반복문의 연결고리  (0) 2018.02.06

출처 : http://kks227.blog.me/60204955407



(1) namespace, using, ::


- C++ 에서 새로 도입된 개념인 이름공간(namespace)

- namespace 라는 키워드를 사용한다.

- namespace 네임스페이스명 { ... } 형태를 취한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <cstdio>
 
namespace ns {
    int n = 5;
    double f = 3.3;
    char c = 'G';
}
 
int k = 10;
 
int main()
{
    // n = 3; // Error
    ns::n = 3;
    printf("%d\n", ns::n);          // 3
 
    int n = 5;
    printf("%d %d\n", n, ns::n);    // 5 3
 
    using ns::f;
    using ns::c;
    //using ns::n;
    printf("%lf %c\n", f, c);       // 3.300000 G
 
    using namespace ns;    // directive
    
    printf("%d %lf %c\n", n, f, c); // 5 3.300000 G
 
    int k = 3;
    printf("%d %d\n", k, ::k);      // 3 10
}
cs


>> 3 : ns 라는 이름공간 생성

>> 13 : n 은 메인함수에서 선언되지 않은 변수 이므로 에러

>> 18 : main() 의 n 과 ns 라는 이름공간의 n

>> 20, 21 : 이름 공간의 변수를 이름공간을 생략하고 사용할 수 있다. (using 키워드 사용)

>> 22 : 이미 같은 이름의 변수가 지역적으로 선언되어 있으면, 컴파일 에러 발생

error: target of using declaration conflicts with declaration already in scope


>> 25 : 이름공간 ns 에 있는 변수들을 ns:: 없이 사용 가능.

     다만 이미 선언되어 있는 변수의 경우 무시되는 듯 하다. 27에서 n 의 값은 main() 스코프의 n.

>> 30 : ::k 는 전역번수 k  



(2) 여러개의 네임스페이스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <cstdio>
 
namespace ns1 {
    int n = 11;    
}
 
namespace ns2 {
    int n = 22;
}
 
namespace ns3 {
    int n = 33;
    namespace ns4 {
        int n = 44;
    }
}
 
int main()
{
    printf("%d %d\n", ns1::n, ns2::n);  // 11 22
 
    /*
    using ns1::n;
    using ns2::n;
    printf("%d\n", n);    // error!!
    */
 
    {
        using namespace ns1;
        printf("%d\n", n);              // 11
    }
    
    {
        using namespace ns2;
        printf("%d\n", n);              // 22
    }
 
    printf("%d %d\n", ns3::n, ns3::ns4::n);     // 33 44
 
    return 0;
}








cs


>> 26 : n 이 어디소속인지 알 수 없으므로 에러.

>> 29 ~ 37 : 이런식으로 스코프를 중괄호를 만들어 주고, 그 안에서 독자적으로 특정 네임스페이스를 사용하는 방법도 있다고 한다.

>> 12 ~ 17, 39 : 네임스페이스 안에 네임스페이스



(3) 이름없는 네임스페이스, 네임스페이스 안의 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <cstdio>
 
namespace {
    int n=4;
}
 
// n = 8; error!!
 
int func() { return n; }
 
namespace ns {
    void func();
}
 
 
int main()
{
    printf("%d\n", n);          // 4
 
    n = 8;
    printf("%d\n", n);          // 8
 
    printf("%d\n", func());     // 8
 
    ns::func();        // called ns::func()
 
    using ns::func; // not using ns::func();
    func();
 
    return 0;
}
 
namespace ns {
    void func() {
        puts("called ns::func()");
    }
}
 
cs


>> 3 : 이름없는 네임스페이스 선언

>> 18 : ::와 같은 연산자 없이 바로 사용 가능.

>> 7 : 하지만 전역 지역에서는 사용 불가.

>> 9 : 이와 같이 어떤 지역 스코프 안에서 사용 가능.


>> 12, 25 : 변수를 선언하고 사용하는것과 비슷하다.

>> 27 : using 키워드를 사용할 때는 using 네임스페이스명::함수이름; 의 형태로 써야한다. 

>>        using ns::func(); 는 잘못된 형태이다.

>> 33 : 프로토타입만 선언 후 나중에 따로 정의를 해도 된다.






'Language > C++' 카테고리의 다른 글

<2> 레퍼런스 (reference)  (0) 2018.02.12
<1> C++ 에서 확장된 기능  (0) 2018.02.12