2020-08-31

프로젝트 오일러 11번 문제를 풀어간 방법

0. 프로젝트 오일러라는 사이트는

수학적 문제들을 컴퓨터 프로그래밍으로 하나씩 해결해가는

퀴즈 풀이 사이트이다.

몇 가지 풀어보다가 '이런 풀이법 어떨까' 싶어서 공유한다.





1. 문제 11번.






2. 풀이 과정


일단 20*20의 숫자들을 배열로 만들 필요가 있었다.

수평, 수직, 대각선 방향으로 연속된 네 개의 숫자를 특정할 수 있어야 하기 때문에

일단 리스트형 자료형으로 만들었다.



그리고 배열을 쳐다보고, A4용지에 네모를 그려가던 도중

특이한 규칙성이 보이기 시작했다.


숫자가 4개 연속되어 나타나려면 '여유공간'이 필요하다는 것을 깨달았다.

0번째줄 16번째에 위치한 '50'을 보면

오른쪽으로 최소한 3칸의 여유공간이 있어야만 '50'부터 오른쪽으로 4개의

'연속된 숫자들'이 완성될 수 있다.



지금 정리해보면서 내가 문제를 잘못 풀었다는 사실을 알아냈는데,

문제를 풀고 있을 때까지만 하더라도 다음과 같은 아이디어로 접근했다.

네모가 쳐진 부분에 위치한 숫자들에서 '이동 가능한 방향'은 총 3가지: →, ↘, ↓

각각 '이동'하는 방법은 이렇다.

→: i + 1, 2, 3으로 인덱싱 (1씩 늘어남)
↘: i + 21, 42, 63으로 인덱싱 (21씩 늘어남)
↓: i + 20, 40, 60으로 인덱싱 (20씩 늘어남)

아직 한 가지 방향이 더 남았는데 그건 아래 사진과 같다.


↙: i + 19, 38, 57으로 인덱싱 (19씩 늘어남)

그래서 해당 숫자들의 위치를 어떻게 가져올까 하다가

numpy의 기가막힌 부분 인덱싱 방법을 차용하기로 한다.


numpy의 슬라이싱은 가히 예술적이다. 이렇게 쉽게 배열을 선택할 수 있다.

변수 a에 20*20의 2D matrix를 만들었고,

변수 b에 0부터 16번째까지 담는다.
(슬라이싱은 마지막 번호 미포함으로 인해 0:17로 적음)

변수 c는 ↙방향 숫자배열을 찾을 '시작위치들'을 담았다.
( [3:20, 0:16]이 아니라 [0:16, 3:20]임에 유의해야 한다)


이제 시작 위치부터 하나하나 꺼내오며 곱셈을 해보는 일만 남았다.


b에서는 세 방향으로 진행해서 가장 큰 값을 갱신하도록 만들었고

c에서는 한 방향으로 또 진행해서 가장 큰 값을 갱신하도록 만들었다.



답은 맞았는데, 문제를 잘못 풀었다는 이야기를 위에서 했었다...

그 이유는 다음과 같다...


방향별 인덱싱을 시작해야 할 위치를 누락했다.

빨간색: 오른쪽으로 진행하는 경우엔 아래 세 줄이 추가되어야 하고,

파란색: 아래쪽으로 진행하는 경우엔 오른쪽 세 줄이 추가되어야 했다.

두 가지 모두 겹치는 구간은 노란색의 ↘방향 뿐이다.





3. 정답

70600674


2020-08-30

Google 드라이브 파일 스트림 다운로드 할당량 초과됨

0. 다운로드 할당량이 초과됐다고 한다.

(쓰지마라 헤비 유저)

Google G Suite 관리자 고객센터의 FAQ에 따르면

한 명의 유저가 사용할 수 있는 할당량은 다음과 같다:

하루에 업로드 750 GB
(단, 진행 중인 업로드는 완료된다)
(단, 한 개의 파일 크기가 750 GB를 넘겨도 업로드는 완료된다)

한 번에 업로드할 수 있는 파일의 크기는 최대 5 TB



근데 가만히 생각해보자...

100Mbps 회선으로 750 GB를 다운로드 받으려면

최고 속도로 17시간을 다운로드 받아야 한다.

컴퓨터를 켜놓는 시간부터가 17시간 미만인데, 이게 가능한 소리인가..





1. 그럼 다운로드 할당량은 뭐지?

같은 문제를 앓고 있는 레딧의 한 유저를 발견할 수 있었다.

큰 파일을 이동시키고 있었는데 5분도 안 돼서 해당 경고를 받았다는 것.

상식적으로 5분만에 750 GB의 할당량을 다 썼다는게 말이 안 된다.



이 문제에 대한 가장 유력한 추정 원인은 다음과 같았다:

GDFS (Google Drive File Stream)으로

거대한 용량의 동영상이 많이 담긴 폴더를 열어보는 경우

GDFS가 모든 비디오를 자동으로 동기화하려는 경향이 있다.



실제로 난 100 GB에 달하는 브이로그용 동영상을 한 폴더에 몰아놓은 다음에

썸네일을 보자고 폴더에 들어갔던 적이 종종 있었다.

이 문제를 해결하기 위해서는

폴더를 나눠서 큰 파일을 저장하거나

혹은 트러블 슈팅을 통해 문제를 해결해달라고 민원을 제기해야 할 것 같다.



아니면 그냥 마음 편하게

하루 정도는 쉬어주는 것도 나쁘지 않겠다..


2020-08-26

파이썬 itertools 의 combinations 함수

0. 목적

총 5개의 꼭지점을 표현할 노드 [A, B, C, D, E] 리스트가 있을 때

AB, AC, AD, AE, BC, BD, BE, CD, CE, DE, 총 10개 선분의 조합을 얻고자 한다.

2개 혹은 그 이상의 조합을 반환하는 함수가 필요하다.





1. 이미 있다.

itertools 패키지의 combinations 함수가 바로 그 역할을 한다.


첫 번째 인자로 iterable 객체를 받고

두 번재 인자로 나눌 쌍의 개수를 지정한다.





참고자료 : https://stackoverflow.com/questions/6499327/the-pythonic-way-to-generate-pairs

2020-08-25

MSDS 여러개 다운로드 받기 (Python 코드)

0. CAS No. 목록을 갖고 있는데 MSDS 작성에 노가다가 들어간다.

그래서 파이썬으로 MSDS를 전부 다운받을 수 있도록 코드를 만들었다.

한국산업안전보건공단의 DB를 사용한다.





1. 코드

코드는 GitHub으로 공유하는 것이 좋을 것 같아 링크로 대체하였다...

CAS_to_MSDS.py





2. 컨셉

일단 CAS No. 목록을 보유하고 있어야 한다.

CAS No.를 한국산업안전보건공단에서 검색해서 msds_id를 얻는다.

msds_id로 pdf 파일을 다운로드 받는다.





3. 원리

get_msds_id 함수에서 cas_no를 받아서

산업안전보건공단에서 자체적으로 사용하는 msds_id를 찾아낸다.

msds_id를 토대로 get_pdf 함수에서 pdf 파일을 다운받는다.


http://msds.kosha.or.kr/kcic/msdsdetail.do 에서 인쇄 또는 저장을 누르면

포함할 정보의 항목을 설정할 수 있고,

해당 설정은 jsp에게 data로 post함으로써 설정할 수 있다.


이 부분에서 0과 1로 표현할 수 있는 듯하다.

PDF 파일을 다운받기 위해선 AICipher라는 값이 필요하다.

왜 필요한진 모르겠다.

하지만 필요하기 때문에 찾아보면


아까 그 jsp 인쇄 페이지에서 자바스크립트로 처리하고 있음을 알 수 있다.

또 왜인진 몰라도.. 다 비슷하게 생겼는데 엄밀히는 다르게 생겼다.

그 중 callParameter 변수를 사용한다.

RegEx로 잘라 requests.post할 때 data에 붙여서 보낸다.

여기에서 받는 리스폰은 PDF 파일이므로, 바이너리 파일로 저장해줘야 한다.





4. 사용법

cas_nofor 문으로 대입시켜가면서

목록을 하나하나 돌도록 추가 코드를 짜서 사용하면 된다.

다운로드 경로는 '다운로드 완료' 글자 위에 open 함수에서 정의하면 된다.



5. 업데이트 내역:

2021/08/17 - 요청 주소 최신화 및 클래스화 진행

2020-08-21

구글 드라이브 파일 스트림 캐시 크기

0. 구글 드라이브 파일 스트림 캐시 크기는 하드 드라이브 내 사용 가능한 공간의 20%로 제한된다.


정말일까?



1. 구글 드라이브 파일 스트림 캐시 위치


설치할 때 별다른 짓을 하지 않았다면

윈도우의 경우엔 %LOCALAPPDATA%\Google\DriveFS

Mac의 경우엔 ~/Library/Application Support/Google/DriveFS

에 캐시들이 저장된다.



2. 내 캐시 확인


사용 가능한 공간이 455GB, 구글 드라이브 파일 스트림 캐시의 크기는 약 100GB

얼추 맞아떨어진다.

matplotlib 기초지식 - 일반적인 컨셉과 Figure의 구성

일반적인 컨셉

matplotlib는 신규 사용자들에게 부담이 될 수 있을 정도로 광범위한 코드베이스를 담고 있다. 그러나 대부분의 matplotlib는 매우 간단한 컨셉의 프레임워크와 몇 가지 중요한 사항에 대한 지식만으로도 충분이 이해할 수 있다.

Plotting에는 가장 일반적인 수준(예를 들어서, 2차원 배열 그리기)부터 아주 특수한 수준 (예를 들어서, 화면 픽셀을 빨간색으로 칠하기)까지 다양한 수준의 작업을 수행할 수 있다. Plotting 패키지의 목적은 필요한 모든 제어방법을 통해 가능한 한 쉽게 데이터를 시각화할 수 있도록 지원하는 것이다. 즉, 대부분의 경우엔 상대적으로 높은 수준의 명령어를 사용하지만 필요한 경우엔 저수준 명령어도 사용할 수 있다.

matplotlib의 모든 것들은 계층화되어있다. 가장 높은 계층엔 유한상태기계 환경인 matplotlib.pyplot 모듈이 있다. 이 수준에서는 현재 figure의 plot에 선, 이미지, 글자 등을 추가할 수 있는 기본적인 함수가 들어있다.

그 다음으로 하위 계층에서는 객체지향 인터페이스의 첫 번째 수준으로, 여기에서 pyplot은 Figure 생성과 같은 몇 가지 기능에만 사용되며, 사용자는 Figure 및 axes 객체를 명시적으로 생성하고 다룰 수 있다. 이 수준에서 사용자는 pyplot을 사용해 figure를 만들고 해당 객체를 통해 하나 이상의 axes 객체를 생성할 수 있다. 여기에서 생성된 axes 객체는 대부분의 plotting 작업에서 사용된다.



출처 - matplotlib.org

Figure의 구성

Figure는 모든 하위 axes, artists, canvas들을 트래킹한다(각 요소들에 대한 요약은 아랫문단을 참조). Canvas가 뭔지 몰라도 염려할 필요는 없다, canvas가 plot을 그리기 위한 동작을 수행하긴 하지만 실제 사용자에게 보이는 일은 매우 드물다. Figure는 여러 개의 Axes을 가질 수 있으며, 적어도 1개 이상은 있어야 실제적으로 유용할 수 있다.

Pyplot을 이용해 새로운 Figure를 그리는 가장 쉬운 방법은 아래와 같다:




Axes

이것이 바로 일반적으로 생각되는 'plot'이며, 데이터공간이 들어있는 이미지 영역을 일컫는다. Figure는 여러 개의 Axes를 포함할 수 있지만, Axes 객체는 단 하나의 Figure에만 존재할 수 있다. Axes는 2D에서 2개, 3D에서 3개의 Axis를 포함한다. Axes와 Axis의 차이에 유의해야 한다. 데이터의 한계점은 set_xlim()set_ylim()으로 정의할 수 있다. 각 Axes들은 title을 갖고 있어서 set_title()set_xlabel() 등으로 설정 가능하다.



Axis

숫자 선 모양의 객체들을 말한다. 그래프가 표현할 수 있는 한계를 설정하고 눈금(축의 표시 및 틱)을 생성한다. Tick의 위치는 Locator 객체에 의해 결정되며, 눈금 레이블 문자열은 Formatter에 의해 형식이 지정된다. 정확한 Locator와 Formatter를 조합해서 눈금 위치와 레이블을 매우 세밀하게 제어할 수 있게 만들어준다.



Artist

기본적으로 그림에서 볼 수 있는 모든 것들이 Artist이다(Figure, Axes, Axis 객체 등등). Artist 객체는 Text 객체, Line2D 객체, collection 객체, Patch 객체 등을 포함하고 있다. 그림이 렌더링되면 모든 Artist가 Canvas에 그려진다. 대부분의 Artist는 Axes과 결합되어 있다. 이러한 Artist들은 여러 축에서 공유하거나 혹은 다른 축으로 이동할 수 없다.


2020-08-18

경로를 복사해서 PyCharm에 붙여넣었더니 백슬래시 때문에 불편했던 것에 관하여

0. 문제는 이럴 때 발생한다.


Windows 10에서는 파일에 Shift + 우클릭 할 경우에

위 사진과 같이 경로로 복사라는 기능을 지원한다.

그런데 이를 복사해서 PyCharm에 붙여넣으면

이렇게 붙여넣기가 이루어진다.


SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape

백슬래시는 문자열 내에서 특별한 의미를 갖고 있다.

그렇다보니 저 문자열 그대로 사용하면 원하는 경로를 적어줄 수 없게 된다.





1. 문제 해결

간단하다. 이렇게 작성하면 된다.


앞에 r을 붙여서 raw string으로 사용하면 된다.





2. 잡설

유닉스처럼 슬래시가 디렉토리 분리 문자일 경우엔

PyCharm에서 별도의 처리가 필요 없다.





참고자료:
https://lerner.co.il/2018/07/24/avoiding-windows-backslash-problems-with-pythons-raw-strings/

2020-08-09

스마트폰과 윈도우10을 USB로 연결했는데 일부 파일이 보이지 않는 문제에 관하여

 0. 스마트폰에 있는 파일을 백업하기 위해 PC와 USB로 연결했는데, 몇몇 파일이 누락되는 현상을 발견하였다.


사진 상에 표시되진 않았지만, FTP 서버로 열어본 디렉토리에서는 멀쩡하게 보이는 파일들이 USB 연결 환경에서는 보이지 않는 문제가 있다.



1. 추정 원인

StackExchange의 글에 따르면 이는 안드로이드 장치에서 파일을 생성하는 방법 때문에 발생하는 버그라고 한다. 폰을 재부팅한 후에도 MTP를 이용해 접근했을 때 일부 파일이 누락된 상태로 남아있을 수 있다.



2. 가능한 해결법

실행하기 간단한 순서대로 작성하였다. 시도해보고 안되면 다음 방법을 시도해보는 방식이 좋다.

- 미디어 스캐닝을 돌려본다. 미디어 스캔을 하는 방법은 따로 적지 않으니 구글링을 통해 시도해보면 좋다.

- FTP 파일 서버를 사용한다. 필자는 7Zipper라는 앱을 사용하는데, 해당 앱에선 가정용 라우터(공유기)에 함께 물린 네트워크 내에서 접근할 수 있는 FTP 서버를 제공한다. 사용법은 해당 앱 내에 친절히 설명되어 있다. 이 방법은 데이터의 크기가 작고, 당장 파일을 옮겨야 하는데 망할 USB가 작동하지 않을 때 사용하기 좋은 방법이다. 솔직히 이 방법으로 파일을 옮기지 못한 경우는 없었다. 하지만 무선 네트워크 속도에 제한을 받을 수 밖에 없다는 단점이 있다.

- MTP 대신 USB storage 모드를 사용해본다. 일부 기종에서는 해당 옵션이 보이지 않을 수도 있다. 이는 파일 저장소가 ext4 파일시스템으로 /data/media 하에 통합되어 있기 때문이다.

- Media Storage 앱의 데이터를 초기화한다. '설정 > 앱 > 모든 애플리케이션 보기 > Media Storage 터치 > '데이터 지우기'를 터치해 해당 앱의 데이터를 지운다. '모든 애플리케이션 보기' 대신에 '시스템 앱 보기'등의 옵션으로 제공될 수 있으니 잘 찾아보아야 한다. 이 방법은 미디어 데이터를 삭제시키기 때문에, 이후에 해당 앱이 미디어 파일을 다시 만들어내는 데에 시간이 걸릴 수 있다. 그걸 기다리는 동안엔 USB로 연결해도 파일들에 접근할 수 없으니, 커피 한 잔 마시고 와서 다시 들여다보도록 하자.

정리하자면 다음과 같다.

이동할 데이터의 크기가 작고 신속함이 요구된다면 FTP 파일 서버를 사용하는 것을 추천.
이동할 데이터가 크고, 시간이 남아돈다면 Media Storage 앱의 데이터 초기화를 추천.