'분류 전체보기'에 해당하는 글 303건

(2025.01.27) https://hojongs.medium.com/

 

이사 간 블로그 주소: https://hojongs.github.io/

 

Tech Blog by hojongs

Spring Boot, Kotlin, Kubernetes, Docker, DevOps 등에 호기심이 많은 한 서버 개발자의 문서 저장소

hojongs.github.io

블로그 이사한 이유: https://hojongs.github.io/posts/reasons-for-migrating-blog-from-medium/

 

Medium 블로그를 이사온 이유, 블로그 플랫폼 비교

왜 2년동안 사용하던 Medium을 버리고 github.io로 이사온 이유를 개발자로서 이야기하려 한다.

hojongs.github.io

 


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

medium 포스트 작성 UX가 전반적으로 티스토리보다 퀄리티가 높고

draft들이 리스트로 보이는 UI가 맘에 들어서, medium으로 옮기기로 마음먹게 되었다.

 

medium 외에 velog라는 블로그 서비스도 알게 되었다 우연히.

velog는 개발자들을 위한 블로그 서비스고, 국내의 벨라포트라는 프론트엔드 개발자가 만드셨다고 한다.

 

github 로그인 연동도 되고 markdown을 지원하고 UI가 마음에 들었지만, medium과 velog를 동시에 운영하고 싶지는 않았다..

 

medium에 Tech Blog용 계정과 이 글처럼 잡다한 포스팅용 계정 2개를 운영해야겠다.

약간 브레인 스토밍 느낌으로.

 

https://hojongs.medium.com/

 

Jongho Jeon – Medium

Read writing from Jongho Jeon on Medium. Server developer at TossBank. Done is better than perfect. Every day, Jongho Jeon and thousands of other voices read, write, and share important stories on Medium.

hojongs.medium.com

 

https://github.com/hojongs/

 

hojongs - Overview

🐢 Lazy Software Engineer who wants to be a small giant 👣 - hojongs

github.com

 


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

24시간 생각이 끊이지 않는 성격이라, 이 생각들을 글로 남겨두려고 한다. 잊어버리면 아까우니까.

대부분은 크게 중요하지 않은, 의미없는 생각들이겠지만 하나라도 기발한 생각이 남지 않을까.

이게 요즘 블로그에 다시 포스팅을 이어나가고 있는 이유이다.

또다른 이유는, 머릿 속으로 생각하는 것보다 말, 글, 또는 그림으로 생각을 표현하는 게 더 잘 정리가 되고, 이해가 되기 때문이다.

오늘은 특별한 주제없이, 그냥 생각이라는 것 자체를 주제로 글을 남겨보려고 한다.

---

주제를 벗어나는 이야기지만, 지난 포스팅에서 티스토리 말고 다른 블로그 플랫폼을 찾는다는 말을 썼었다.

조금 찾아보니,
네이버 블로그는 네이버 검색 최적화 외에는 큰 메리트를 느끼지 못 했고
medium은 원래 고려하지 않고 있었고 (한글 가독성 최악이라는 평도 있었음)
brunch는 가입해보니, 지금처럼 가벼운 글을 쓰는 플랫폼은 아니어서 PASS
wordpress는 세팅 귀찮음 (편의성이 지금 나에겐 최고 중요)
github io, notion은 나에게 적합하지 않았다

이 글을 쓰다보니 이글루라는 곳도 있었던 게 생각났는데, 여기도 큰 메리트가 있을 것 같지는 않다.

instagram, facebook, twitter와 같은 SNS는 이 글처럼 떠오르는 생각을, 짧게 쓰기에는 적합하지만
내가 쓰게 될 주제가 다양하고 긴 내용의 글도 있을 것 같아서 안될 것 같다.

결론은 다른 플랫폼을 찾기 전까지는 tistory를 유지할 것 같다.
검색 최적화는 안돼있을 것 같지만, 뭐 노출보다는 내 생각 정리해놓는 게 1순위니까.

markdown WYSIWIG이 지원되는 블로그 플랫폼 또 없나.. (어쩔 수 없이 medium으로 가야하나..)

아무튼, 딴 소리가 길었다. (곧 medium 계정 하나 더 만들어서 옮기게 될 것 같다 ㅋㅋ)

---

생각. 지금 나는 개발자로 일한 지 1년 4개월 정도 됐다.
그리고 요즘, 커뮤니케이션으로 대부분의 시간을 보내고 개발 업무에는 거의 집중력&효율성이 바닥인 상태이다.
왜 이렇게 커뮤니케이션 코스트가 높은걸까? 이건 다음 포스팅에서 정리해야겠다.
그래서 오늘 든 생각은, 업무 효율성에 관한 것이다.

---

업무 강도가 매우 높다보니, 업무 효율이 매우 떨어지고 눈앞의 업무를 해결하기에 급급해졌다.

퇴근 후 이런저런 생각을 하다가, 디자인(설계)에는 거의 신경을 쓰지 않고 있는 나 자신을 보게 되었다.

나는 종종 눈앞의 업무에 치여서, 좋은 디자인을 소홀히 하는 경험을 자주 하였다.

그리고 이건 부메랑처럼 돌아와, 곧 (1달도 채 되지 않는 시간이 지나서) 더 많은 업무 병목을 만들어냈다.

그래서 나는 대책을 생각했다. 크게 2가지다.

1. 하루 업무시간 중 4시간(절반)은 업무 집중시간으로, slack notification을 꺼놓고, 내 업무에만 집중하는 것이다. 예전에 잠깐 활용된 적 있는 방법이었는데 자연스럽게 잊혀졌었다.
2. 그리고 이 시간에, 개발 업무를 할 수도 있지만 일종의 Research를 하는 것이다. 다른 회사의 기술 블로그를 보고 내 Tech Blog에 읽은 내용 및 생각을 정리하거나, 좀더 넓은 시야에서 우리 회사 아키텍처를 바라보는 것이다.
전에는 나의 성장을 위한 접근법이라고 생각했지만 회사와 나 모두가 win-win하는 방법이라고 보인다.

커뮤니케이션만 생각하면 머리가 지끈거린다.
커뮤니케이션을 한 곳이 아니라 4~5가지의 주제로 10댓명과 비동기적으로 하다보니, 머리가 지끈거린다. (이 와중에 US 팀이랑 영어로도 이야기하고..)
ㅋㅋ 하루 중 절반이라도 개발만 할 수 있다면 개발 업무 속도가 회복될 것이다 (지금보다 4~5배는 빨라질 것이다..)
그리고 노후되어 가는 우리 코드의 아키텍처도 다시 한 번 돌아보고, 중장기적인(2주 혹은 1개월 이상 관점) 업무에도 다시 신경쓸 수 있게 될 것이다.

최근에 느낀 비효율적인 업무 방식에 대한 생각에 대한 내용을 정리해보았다.

---

업무를 비효율적으로 하다보니 가장 문제가 되었던 것 "생각이 정리되지 않는 것"이었다.
다른 사람들이 하는 말도 잘 이해 못 하게 되고, 문제 상황에 대한 정리 및 해결방안이 전혀 생각나지 않았다.
거의 머리 회전이 안되는 수준으로 느껴져서... 빠른 해결책이 필요했다. (그 해결책은 위에 써놓은 2가지를 시도해보려고 한다.)

---

오늘은 여러 가지 생각들을 적어보았다. 적다보니 내용이 다소 길어졌다.

갤럭시 탭에서 tistory 앱으로 포스트를 작성해보고 있는데, 별점 2.5점 정도 수준이다.
기본 기능은 하는데 불편한 게 좀 있고, 쓰다보면 더 많이 느껴질 듯.
medium으로도 포스팅해보고 차이가 크면 medium으로 빨리 옮겨야겠다.








WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

www.acmicpc.net/problem/10250

 

10250번: ACM 호텔

프로그램은 표준 입력에서 입력 데이터를 받는다. 프로그램의 입력은 T 개의 테스트 데이터로 이루어져 있는데 T 는 입력의 맨 첫 줄에 주어진다. 각 테스트 데이터는 한 행으로서 H, W, N, 세 정수

www.acmicpc.net

심심한 김에, 포스팅 하나 더 올린다.

설명만 길 뿐, 아주 단순한 문제다.

 

101,201,301, ... 102,202,302, ... 순서대로 방에 들어가는 아주 단순한 규칙만 찾으면 된다.

 

H=6일 때 10번째 손님은 402호에 배정된다.

402호라는 숫자를 어떻게 얻어낼 수 있을지 생각해보자.

 

101~601

102~402

 

1번째 손님 = 101호

6번째 손님 = 601호

 

boundary의 규칙만 잘 파악하면 전체 규칙을 파악할 수 있다. 이 때의 boundary는 601호 -> 102호로 흘러가는 타이밍이다.

7번째 손님 = 102호

 

YY=01

XX=02

 

자세한 설명은 다소 생략하고,

N번째 손님에 대해

(XX-1) * H + YY = N라는 규칙이 있음을 알 수 있다

 

검증)

102호 : (2-1)*6+1 = 7번째 손님

402호 : (2-1)*6+4 = 10번째 손님

 

이걸 코드로 표현하면 끝인 것이다.

 

아, 위에서는 X,H,Y를 가지고 N을 구하는 식을 작성했다.

우리가 해야할 일은 N을 가지고 X,Y를 구하는 것이다.

 

삽질..

더보기

N=10,H=6으로 다시 생각해보면

N/H=1과 나머지 4

배정 호 수는 402호이므로

YY=(나머지)

XX=(N/H)+1

임을 알 수 있다

 

검증)

N=3,H=6

배정 호 수 = 301

YY=3

XX=(3/6)+1=1

YYXX=301

 

간단한 문제라고 급하게 풀다가 실수만 하지말자.

 

testcase = int(input())

for i in range(testcase):
    s = input().split()
    h,w,n = map(int, s)
    
    yy = n%h
    xx = n//h+1
    if xx < 10:
        yyxx = str(yy)+'0'+str(xx)
    else:
        yyxx = str(yy)+str(xx)
    print(yyxx)

 

loop 방식이 비효율적이고 생각해서 n/h 방식으로 접근했다가, n/h == 0인 edge case가 문제가 되었다.

그래서 loop 방식으로 다시 접근해보았다.

 

testcase = int(input())

for i in range(testcase):
    s = input().split()
    h,w,n = map(int, s)
    
    temp_n = n
    xx = 1
    while temp_n > h:
        xx += 1
        temp_n -= h
    yy = temp_n
    
    if xx < 10:
        yyxx = str(yy)+'0'+str(xx)
    else:
        yyxx = str(yy)+str(xx)
    print(yyxx)

티스토리.. 코드블럭 기능이 추가되었다 했더니 코드블럭 밑에서 한글이 안 나오는 버그가 있나보다. (바로 입력하면)

아무튼, 다소 효율적인 코드는 아니지만 문제를 해결할 수 있었다

www.acmicpc.net/source/26406155

 

로그인

 

www.acmicpc.net

다음 포스팅은 tistory를 대신할 블로그 플랫폼을 찾는 글이 될 것 같다..

 

 


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

www.acmicpc.net/problem/14681

 

14681번: 사분면 고르기

점 (x, y)의 사분면 번호(1, 2, 3, 4 중 하나)를 출력한다.

www.acmicpc.net

 

몸풀이 if문 문제다

설명이 필요없다

 

소스는 여기에

www.acmicpc.net/source/26402990

 

---

 

마지막 포스팅 날짜가 2019.06월로, 1년 반만에 포스팅이다.

 

블로그 포스팅을 다시 시작해보려 한다. 단, 본격적인 Tech Blog는 medium에 올리려 한다 (UI/UX 및 검색 노출?)

medium.com/jongho-developer

 

jongho-developer – Medium

Jongho’s Tech Blog.

medium.com

여기는 좀더 일상적이고, 간단한, 가벼운, 한국 사람들에게 노출&소통하고 싶은(관심있어할 만한) 내용을 포스팅해보려 한다.

하다 못해 이런 알고리즘 문제풀이 포스팅이라도 남기려 한다.

 

새삼스럽지만 티스토리 포스팅 UI 참... 떠나고 싶게 만든다.. ㅋㅋㅋㅋ

카테고리 설정 어디에 있는거야..


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

웹 개발 언어는 크게 2가지로 분류할 수 있다

프론트엔드 언어와 백엔드 언어

프론트엔드 언어는 클라이언트에서, 백엔드 언어는 서버에서 실행된다




# 프론트엔드 언어

프론트엔드는 기본적으로 HTML/CSS/JS로 구성되지만, 이 세 언어를 기반으로 한 Framework들을 이용하여 생산성을 높이는 방향으로 발전하고 있다




# 백엔드 언어

백엔드 언어는 서버에서만 실행되며, DB 연동 등의 데이터 처리를 주로 담당한다

백엔드 언어는 php, java(Spring, Servlet, JSP), Node.js, python(Django, Flask) 등 다양하게 존재한다

이 post에서는 백엔드 언어의 종류별 차이/특징을 아는대로 정리해보려 한다.




# php

php는 빠른 개발속도를 장점으로 알고 있다.

기본적인 개발환경 세팅이 비교적 간단하다

MVC 패턴 구조를 취하지 않아도 되기 때문에, 개발 자체는 빠르지만 유지보수를 고려하지 않고 개발하면

유지보수할 수 없는 코드가 되어버린다

하나의 파일에 HTML/CSS/JS 코드와 php 코드가 섞여 있으므로, 코드가 길어지면 코드를 읽기가 힘들어진다

중소규모 프로젝트에 적합할 것이다


웹개발을 시작하거나 중소규모 웹개발 프로젝트에 추천,




# java

Java 언어 자체가 Pure OOP 언어이므로, 다른 언어보다는 유지보수가 용이하도록 코드를 작성하게 될 것이다

대규모 프로젝트에 적합하며, 그만큼 개발환경 세팅이 다른 언어보다 비교적 복잡하다

Spring Framework는 MVC 패턴, Dependency Injection 패턴을 사용하는 구조인 것으로 알고 있다

Servlet, JSP 파일 등으로 구분하여 View는 JSP, Servlet은 Control, 그 외 Model class를 작성하여 Model 역할로 나누어 MVC 패턴을 준수하는 구조일 것이다


웹개발 경험이 있는 사람에게, 대규모 웹개발 프로젝트에 추천.

Spring F/W는 책으로 공부하는 것을 추천, (워낙 방대해서)




# Node.js

프론트엔드 언어인 자바스크립트 문법을 사용함으로써, 프론트엔드 개발자가 풀스택 개발을 하기에 가장 쉽다

가장 큰 특징인 Async(비동기) 처리 방식으로, throughput(시간당 처리량)이 가장 높다

하지만 처리시간에 오래 걸리는 서비스에는 적합하지 않다

callback을 이용한 비동기 처리 방식과 자바스크립트 문법이 개인적으로 굉장히 복잡하게 느껴졌다


높은 throughput을 요구하는 (=요청이 많은) 웹개발에 추천

예를 들면 모바일 앱, 게임 백엔드 서버




# python

python이 웹 개발 언어가 아닌 범용 언어이므로, python을 사용하던 사람들에게 좋은 접근성을 제공한다

python의 장단점들을 모두 가져올 수 있다는 특징이 있다

Flask framework는 중소규모 프로젝트에, Django framework는 대규모 프로젝트에 적합하다

필자는 python 언어가 자유도가 높다고 생각하나, 그럼에도 불구하고 Django 프레임워크를 처음 사용할 때는 제한이 많다고 느꼈다


python을 좋아하는 사람들에게 추천

Spring F/W처럼 Django도 책을 가지고 공부하길 추천

아주 간단한 웹개발이라면 Flask, 이후에 프로젝트가 커질 것을 생각하면 Django를 추천




그 외에 무슨 언어들이 있었지?

지금 생각나는 것들은 이 정도.



'Web' 카테고리의 다른 글

[Web] form tag와 한글 인코딩  (0) 2018.04.26
[Javascript] var vs let 차이  (0) 2018.04.23
[Web] elasticsearch.js  (0) 2018.04.23
[Web] Javascript format string implementation  (0) 2018.04.08
[Web] 네이버 캘린더 오픈API, CalDAV  (0) 2018.04.08

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

인터넷에서 파일을 다운로드 받을 때, 파일이름이 URL decode 되지 않은채로 다운로드되는 경우가 있다

파일 사용 자체에는 문제 없지만, 파일이름을 알아보기 힘들다는 문제점이 있다

그런 파일들이 많을 때는 더 문제다


그래서 특정 디렉토리 내의 파일들의 이름을 url-decode하는 코드를 작성해봤다.

실행에는 python3가 필요하다



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
"""
Filename : urldecode.py
Python version : 3
Usage example : python urldecode.py C:\\my_dir
"""
import os
import argparse
from pathlib import Path
from urllib.parse import unquote
 
parser = argparse.ArgumentParser(description='특정 디렉토리의 url-encoded 파일이름들을 decode하는 프로그램')
parser.add_argument('dirpath', type=str, help='url-encoded 파일들이 위치한 디렉토리 경로')
args = parser.parse_args()
 
dirpath = Path(args.dirpath)
 
filenames = [x for x in dirpath.iterdir() if x.is_file()]
for x in filenames:
    print(x)
yn = input('rename all? (Y/n) : ').lower()
if yn != 'y':
    exit(0)
 
for old in filenames:
    new = Path(unquote(old.name))
    if new == old:
        continue
 
    print('Renamed {old} -> {new}'.format(old=old, new=new))
    old.rename(new)
 
cs



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

[python] BeautifulSoup4 vs Scrapy  (0) 2018.05.01
[python] map object  (0) 2018.04.26
[python] for문과 yield문, return문  (0) 2018.04.24
[python] elasticsearch-dsl scan / index / doc_type  (0) 2018.04.12
[python] logging handler class 소개  (0) 2018.04.12

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/




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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
#include <stdlib.h>
 
typedef int Element;
 
class Node
{
public:
    int id;
    Element elem;
    Node* left;
    Node* right;
 
    Node() : Node(00, nullptr, nullptr) {};
    Node(int id, Element elem) : Node(id, elem, nullptr, nullptr) {};
    Node(int id, Element elem, Node* left, Node* right) : id(id), elem(elem), left(left), right(right) {}
    virtual ~Node() 
    {
        printf("Node %d Deleted \n", id);
        delete left;
        delete right;
    }
    void preorder()
    {
        printf(" %d", elem);
        if (left) left->preorder();
        if (right) right->preorder();
    }
    void inorder()
    {
        if (left) left->preorder();
        printf(" %d", elem);
        if (right) right->preorder();
    }
    void postorder()
    {
        if (left) left->preorder();
        if (right) right->preorder();
        printf(" %d", elem);
    }
    Node* search_child(int id)
    {
        if (this->id == id)
            return this;
 
        Node* node = nullptr;
        if (left != nullptr)
            node = left->search_child(id);
        if (node == nullptr && right != nullptr)
            node = right->search_child(id);
 
        return node;
    }
};
 
Node* mirror_tree(Node* node)
{
    Node* left = nullptr;
    if (node->right)
        left = mirror_tree(node->right);
 
    Node* r = nullptr;
    if (node->left)
        r = mirror_tree(node->left);
 
    return new Node(node->id, node->elem, left, r);
}
 
int main()
{
    // init tree (bottom-to-top)
    const int NODE_LEN = 6;
    Node* node[NODE_LEN];
    for (int i = 0; i < NODE_LEN; i++)
        node[i] = nullptr;
 
    node[4= new Node(44);
    node[5= new Node(55);
    node[2= new Node(22);
    node[3= new Node(33, node[4], node[5]);
    node[1= new Node(11, node[2], node[3]);
    Node* root = node[1];
 
    // test preorder()
    printf("preorder : ");
    root->preorder();
    printf("\n");
 
    // test preorder() of mirror_tree
    Node* mirror_root = mirror_tree(root);
    printf("preorder : ");
    mirror_root->preorder();
    printf("\n");
 
    // test search_child()
    Node* child = nullptr;
    child = root->search_child(2);
    if (child != nullptr)
        printf("id : %d \n", child->id);
    else
        printf("id : null \n");
 
    child = root->search_child(5);
    if (child != nullptr)
        printf("id : %d \n", child->id);
    else
        printf("id : null \n");
    
    child = root->search_child(6);
    if (child != nullptr)
        printf("id : %d \n", child->id);
    else
        printf("id : null \n");
 
    printf("Delete original tree \n");
    delete root;
    printf("Delete mirror_tree \n");
    delete mirror_root;
    return 0;
}
/*
original tree : 
  1
2   3
   4 5
preorder : 12345

mirror_tree : 
   1
 3   2
5 4
preorder : 13542
*/
 
cs




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Intro

알고리즘 문제 해결 전략 책을 읽다가, 흥미로운 문제가 있어서 보충설명을 추가하여 정리하였다.
문제는 아래 링크에서 발췌하였다. (정오표의 틀린 내용도 보완하여 발췌하였다)
http://book.algospot.com/candy.html

사탕 나눠주기 문제

예제 문제를 하나 풀면서 점진적인 개선을 어떻게 적용할 수 있나 살펴봅시다. N(N≤30)개의 사탕을 세 명의 어린이에게 가능한 공평하게 나눠 주려고 합니다. 공평함의 기준은 받는 사탕의 총 무게가 가장 무거운 어린이와 가장 가벼운 어린이 간의 차이로 합시다. 사탕의 무게는 모두 20 이하의 정수입니다. 가능한 최소 차이는 얼마일까요?

이 문제를 푸는 가장 단순한 방법은 사탕을 나눠 주는 모든 방법을 하나씩 만들어 보는 것입니다. 각 사탕마다 셋 중 어느 어린이에게 줄 지를 결정한다고 하면 3^N, 즉 최대 205조 개의 방법을 만들어 보게 됩니다. 이는 죽기 전에 다 세어볼 수 있을까 엄두가 나지 않는 큰 수이지만, 사실 이 때 우리는 엄청나게 많은 수를 중복으로 세고 있습니다. 실제로 받은 사탕들이 서로 다르더라도 그 무게가 같다면 이 문제의 답은 같다는 점을 무시했기 때문입니다.

이 아이디어를 이용해 모든 방법을 만들어 보는 완전 탐색(6장) 대신 각 어린이가 가진 사탕의 총량을 상태 공간으로 하는 너비 우선 탐색(29장)으로 문제를 풀 수 있습니다. 이 때 각 상태는 세 어린이가 가진 사탕의 양을 표현하는 세 개의 정수입니다. 우리는 어떤 어린이에게도 사탕이 없음을 나타내는 (0, 0, 0)에서 시작해, 사탕을 하나 줄 때마다 그 어린이가 가진 사탕의 양을 늘립니다. 이렇게 하면 실제로 가진 사탕들이 다르더라도 그 무게가 같은 경우 하나의 상태로 취급해, 중복을 제거할 수 있습니다. 이 상태 공간의 크기는 얼마일까요? 사탕의 최대 무게는 20이므로, 각 어린이가 가진 사탕의 양은 0에서 20×N 사이입니다. 따라서 각 상태에 대해 방문 여부를 저장하려면 크기가 (20×N+1)3≤601^3(대략 2억)인 배열을 잡아야 합니다.

2억은 대개 시간 제한 안에 탐색할 수 있는 크기입니다만, 이 문제의 답이 최대 얼마인지 생각해 보면 이 방법을 더 최적화할 수 있습니다. 사탕을 가장 많이 받은 어린이와 가장 적게 받은 어린이의 차이가 20 이상이었다고 가정해 봅시다. 사탕의 최대 무게는 20이므로, 이때 사탕을 가장 많이 받은 어린이가 가장 적게 받은 어린이에게 사탕을 하나 준다면 이 둘이 가진 사탕의 양의 차이는 항상 감소합니다. 이렇게 하면 항상 원래보다 더 공평한 답을 얻을 수 있기 때문에, 차이가 20 이상인 경우는 절대로 최적의 답이 될 수 없다는 것을 알 수 있지요. 따라서 넉넉잡아도 사탕을 가장 많이 받은 어린이가 (20×N)/3+20 넘게 사탕을 받는 경우는 무시해도 됩니다. 그러면 실제로 할당해야 하는 배열의 크기는 (20×N^3+20)^3≤220^3(대략 1000만)으로 줄어듭니다.

이 정도면 충분히 문제를 풀 수 있을 것 같지만, 문제를 푸는 더 빠른 방법이 있습니다. 세 어린이 중 누가 가장 사탕을 적게 받고, 누가 가장 많이 받는지는 중요하지 않기 때문입니다. 세 어린이의 사탕의 총량이 (180, 190, 200)이건 (200, 190, 180)이건 우리의 답은 변하지 않지요. 따라서 세 어린이의 사탕의 총량이 항상 오름차순으로 정렬되어 있는 경우만을 탐색하도록 합시다. 서로 다른 세 수를 여섯 가지의 방법으로 나열할 수 있으므로, 이렇게 하면 경우의 수는 다시 대략 1/6으로 줄어듭니다. 결과적으로 대략 200만 개 이하의 경우의 수만을 탐색해 문제를 해결할 수 있지요. 이 과정에서 천재만이 떠올릴 수 있는 번뜩이는 영감은 필요없었지만, 처음에 생각했던 방법에 비해 검사해야 할 상태의 수가 1억분의 1로 줄어들었음을 알 수 있습니다.

보충설명

1

예제 문제를 하나 풀면서 점진적인 개선을 어떻게 적용할 수 있나 살펴봅시다. N(N≤30)개의 사탕을 세 명의 어린이에게 가능한 공평하게 나눠 주려고 합니다. 공평함의 기준은 받는 사탕의 총 무게가 가장 무거운 어린이와 가장 가벼운 어린이 간의 차이로 합시다. 사탕의 무게는 모두 20 이하의 정수입니다. 가능한 최소 차이는 얼마일까요?

문제는 다음과 같다.
최대 30개의 사탕을 3명의 어린이에게 나누어주려고 한다.
사탕의 무게는 1~20의 정수이다.
받은 사탕 무게의 합이 가장 큰 어린이와, 가장 가벼운 어린이의 무게 차는 최소 얼마일까?

2

이 문제를 푸는 가장 단순한 방법은 사탕을 나눠 주는 모든 방법을 하나씩 만들어 보는 것입니다. 각 사탕마다 셋 중 어느 어린이에게 줄 지를 결정한다고 하면 3^N, 즉 최대 205조 개의 방법을 만들어 보게 됩니다. 이는 죽기 전에 다 세어볼 수 있을까 엄두가 나지 않는 큰 수이지만, 사실 이 때 우리는 엄청나게 많은 수를 중복으로 세고 있습니다. 실제로 받은 사탕들이 서로 다르더라도 그 무게가 같다면 이 문제의 답은 같다는 점을 무시했기 때문입니다.

N개의 사탕을 3명의 어린이에게 나누어주는 경우의 수는 3^N개이다 (중복순열)
N=30일 경우 경우의 수는 약 205조 개가 된다
여기서 간과한 점은 각 어린이가 어떤 사탕들을 받았느냐가 아닌, 각 어린이가 받은 사탕 무게의 합이 중요하다는 점이다
받은 사탕의 개수나 각 사탕의 무게는 별도로 카운팅할 필요 없다

3

이 아이디어를 이용해 모든 방법을 만들어 보는 완전 탐색(6장) 대신 각 어린이가 가진 사탕의 총량을 상태 공간으로 하는 너비 우선 탐색(29장)으로 문제를 풀 수 있습니다. 이 때 각 상태는 세 어린이가 가진 사탕의 양을 표현하는 세 개의 정수입니다. 우리는 어떤 어린이에게도 사탕이 없음을 나타내는 (0, 0, 0)에서 시작해, 사탕을 하나 줄 때마다 그 어린이가 가진 사탕의 양을 늘립니다. 이렇게 하면 실제로 가진 사탕들이 다르더라도 그 무게가 같은 경우 하나의 상태로 취급해, 중복을 제거할 수 있습니다. 이 상태 공간의 크기는 얼마일까요? 사탕의 최대 무게는 20이므로, 각 어린이가 가진 사탕의 양은 0에서 20×N 사이입니다. 따라서 각 상태에 대해 방문 여부를 저장하려면 크기가 (20×N+1)3≤601^3(대략 2억)인 배열을 잡아야 합니다.

30개의 사탕을 3명의 어린이에게 나눠주는 방법이 아닌, 3명의 어린이가 받은 사탕 무게의 합의 경우의 수를 카운팅할 것이다
각 어린이가 가진 사탕 무게의 합이 될 수 있는 범위는, 0 ~ (20xN)이다 (20xN인 경우는 무게가 20인 모든 사탕을 다 받았을 경우)
즉, 20xN+1개의 경우의 수이다
어린이가 3명이므로, (20xN+1)^3개의 경우의 수가 존재하고, 최대 601^3 (약 2억)개가 될 수 있다
205조 개에서 2억 개로 경우의 수를 줄인 것은 굉장히 큰 차이라고 할 수 있겠다.
연산시간 관점에서나, 메모리 사용 관점에서나 모두.

4

2억은 대개 시간 제한 안에 탐색할 수 있는 크기입니다만, 이 문제의 답이 최대 얼마인지 생각해 보면 이 방법을 더 최적화할 수 있습니다. 사탕을 가장 많이 받은 어린이와 가장 적게 받은 어린이의 차이가 20 이상이었다고 가정해 봅시다. 사탕의 최대 무게는 20이므로, 이때 사탕을 가장 많이 받은 어린이가 가장 적게 받은 어린이에게 사탕을 하나 준다면 이 둘이 가진 사탕의 양의 차이는 항상 감소합니다. 이렇게 하면 항상 원래보다 더 공평한 답을 얻을 수 있기 때문에, 차이가 20 이상인 경우는 절대로 최적의 답이 될 수 없다는 것을 알 수 있지요. 따라서 넉넉잡아도 사탕을 가장 많이 받은 어린이가 (20×N)/3+20 넘게 사탕을 받는 경우는 무시해도 됩니다. 그러면 실제로 할당해야 하는 배열의 크기는 (20×N^3+20)^3≤220^3(대략 1000만)으로 줄어듭니다.

이 부분이 바로, 이 글을 포스팅하게 만든 부분이다.
2억 가지의 경우의 수 중, 무게 차가 20 이상인 경우에 대해서 생각해보자.
사탕의 총 무게가 가장 무거운 어린이를 A, 가장 가벼운 어린이를 C라고 하자.
사탕의 최대 무게는 20이므로, A가 C에게 사탕을 하나 주면 무게 차는 항상 감소한다고 한다. (사실은 동등 또는 감소)
예시를 통해 검증해보자.

무게 차가 20 이상인 경우는 카운팅 할 필요 없다는 사실을 확인하기 위한 과정을 묘사하는 중이다.
A의 무게가 100, C의 무게가 80이라고 가정하자. 이 때 무게 차는 20이다.
A가 C에게 무게 20의 사탕을 1개 줬다면, A의 무게는 80, C의 무게는 100이 된다.
이 때도 무게 차는 20으로 변동없다. (무게 크기 관계는 역전됐지만)

만약 A가 C에게 무게 1의 사탕을 1개 줬다면, A의 무게는 99, C의 무게는 81이며 무게 차는 18로 감소한다.
사탕의 무게가 1~20이므로, 무게 차가 20인 경우에는 A가 C에게 사탕을 1개 주더라도 무게 차가 동등 또는 감소한다는 사실을 확인했다.

무게가 20 초과인 경우는 직관적으로, A가 C에게 사탕을 1개 주면 무게 차가 항상 감소한다는 사실을 알 수 있을 것이다.

문제에서 원하는 답은, 무게 차의 최소값이다.
하지만 무게 차가 20 이상인 경우는 최소 무게 차가 될 수 없다.
무게 차가 더 작은 경우가 항상 존재하기 때문이다.
무게 차가 더 작은 경우란, 무게 차가 20 이상인 경우에서 A가 C에게 사탕을 1개 준 것과 동일한 경우를 의미한다.

그러므로 무게 차가 20 이상인 경우는 카운팅 할 필요 없다.
문제에 나와있듯이 각 어린이의 사탕 총 무게가 (20×N)/3+20 이상인 경우는 카운팅할 필요 없다.
무게 차가 최소값이 될 수 없는 경우니까.
N=30인 경우 이 무게는 최대 220이 된다 (모든 사탕의 무게가 20)

사탕 총 무게가 가장 무거운 어린이가 220일 때, 가장 가벼운 어린이는 최대 180이 될 수 있다 (나머지 한 어린이는 200)
3명의 무게 합은 600이고, 무게 차는 40이 된다

필자의 생각으로는, 220^3가지의 경우의 수는, 무게 차가 40인 경우를 제외한 모든 경우의 수로 보인다
무게 차가 20 이상인 경우를 모두 제외하면 경우의 수를 더 줄일 수 있지 않을까 생각이 든다 (개선의 여지)
정리하여, 또다시 경우의 수를 획기적으로 감소시켰다.
이미 문제를 푸는 데에는 문제가 없는 수준까지 개선시켰다고 할 수 있겠다.

5

이 정도면 충분히 문제를 풀 수 있을 것 같지만, 문제를 푸는 더 빠른 방법이 있습니다. 세 어린이 중 누가 가장 사탕을 적게 받고, 누가 가장 많이 받는지는 중요하지 않기 때문입니다. 세 어린이의 사탕의 총량이 (180, 190, 200)이건 (200, 190, 180)이건 우리의 답은 변하지 않지요. 따라서 세 어린이의 사탕의 총량이 항상 오름차순으로 정렬되어 있는 경우만을 탐색하도록 합시다. 서로 다른 세 수를 여섯 가지의 방법으로 나열할 수 있으므로, 이렇게 하면 경우의 수는 다시 대략 1/6으로 줄어듭니다. 결과적으로 대략 200만 개 이하의 경우의 수만을 탐색해 문제를 해결할 수 있지요. 이 과정에서 천재만이 떠올릴 수 있는 번뜩이는 영감은 필요없었지만, 처음에 생각했던 방법에 비해 검사해야 할 상태의 수가 1억분의 1로 줄어들었음을 알 수 있습니다.

3명 중 누구의 사탕 총 무게가 가장 무거운지는 중요하지 않다.
그러므로 3명을 무게 순으로 오름차순 배치하여 경우의 줄일 수 있다.
3명의 어린이를 배치하는 방법은 순열 P(3,3) = 3x2x1 = 6가지 이고
이 중 오름차순 배치만 카운팅 하면 되므로, 경우의 수는 1/6배가 된다.
최종 경우의 수는 220^3 / 6가지가 되었다.

구현 코드

코드 하이라이팅 출처 : https://colorscripter.com/

3^N 카운팅 코드

 


WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

직역하면 추상적인 공장

공장은 Object를 생성하는 공장이고

추상적인 공장이라 함은 생성하는 Object가 추상화되어 있다는 것이다


책에 있는대로 Object는 Maze를 예로 들겠다


Abstract Factory는 시스템에게, EnhancedMaze를 생성하는 factory인지, BoomMaze를 생성하는 factory인지에 대하여 추상화 되어있다
시스템(Client라고도 할 수 있다)은 어떤 Maze가 생성되는 지 모른다


그저 Factory를 통해서 어떤 Maze 생성을 수행한다

이것이 추상화의 의미


--- 효과 ---


Abstract Factory를 사용하면 Object와 시스템의 의존성을 제거함으로서 재사용성을 높일 수 있다

EnhancedMaze를 사용하는 System이 이미 있을 때, 이 시스템을 재사용하여 BoomMaze를 사용하는 System을 손쉽게 구현할 수 있다는 것이다


Clean Code에서는(197p) Abstract Factory를 이용하여 Application이 object 생성 시점을 결정(lazy initialization와 같은)하되, Object를 생성하는 코드는 애플리케이션(앞에서 시스템이라고 언급했던)이 모르게 한다고 되어있다




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

https://www.linux.com/learn/how-run-your-own-git-server


위 글을 참고하였으며

필자는 GCE에 git server를 설치하였다


--- SSH key 생성 및 서버에 등록 ---


# 서버에서 다음을 수행

sudo apt-get install git-core

sudo useradd -m -s /bin/bash git


# 로컬에서 다음을 수행

ssh-keygen 대신 XSHELL에서 RSA 키 생성 (git_rsa_2048) (패스워드는 없이 하자, 그렇지 않으면 git push 할때마다 작성해야함)

내보내기를 통해 git_rsa_2048.pem과 git_rsa_2048.pub 파일을 저장


 - GCE에 SSH public key를 등록 (필자의 다른 포스트에 자세한 방법이 포스팅 되어있음, GCE - Metadata - SSH 키 탭에서 가능)

 - 로컬머신(일반적으로 윈도우즈)에서는 %사용자 디렉토리%/.ssh 디렉토리에, 위 두 파일을 저장해주자


이제 아래 커맨드를 통해 GCE 서버의 git 계정에 접속할 수 있다

ssh -i ~/.ssh/git_rsa_2048.pem git@your-own-server


--- SSH config ---


http://ssaemo.tistory.com/338

위 글을 참고하여, SSH 클라이언트(일반적으로 윈도우즈일 것이다)에서

~/.ssh/config에 ssh host와 identity file을 세팅해주자


config을 작성한 후부터는 -i 옵션 없이 git 계정에 접속할 수 있다

ssh git@your-own-server


ssh가 안될경우, -v 옵션을 붙여서 디버깅해보자

ssh -v git@your-own-server


--- Remote Repository 생성 ---


ssh git@your-own-server 접속


# 서버에서 다음을 수행

mkdir -p /home/git/push_test.git

cd $_

git init --bare


--- local repository 생성 ---


# 로컬에서 다음을 수행

mkdir push_test

cd $_

git init


commit 하기위한 파일을 하나 생성한다 (example: main.py)


git add .

git commit -m "Initial commit"


--- push test ---


git remote add origin git@your-own-server:push_test.git # 경로는 git 홈디렉토리에 있는 디렉토리이다

git push origin master


성공적으로 push 될 것이다

실패한다면 local repo에서 commit을 했는지 확인해보자


git clone git@your-own-server:push_test.git


clone도 잘 작동한다

생각보다 간단하게 git-core 패키지를 통해 git server를 설치할 수 있었다


'Linux' 카테고리의 다른 글

SSH Options, config (SSH 키, 개인 키)  (0) 2018.06.21
Xilinx Gnome-power error  (0) 2018.04.17
[linux] ia32-libs - ubuntu 최신버전 (>=14.04)  (0) 2018.03.28
[Linux] 한글 인코딩  (1) 2018.03.21
[Linux] sudo path 설정방법  (0) 2018.03.20

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

접속이 안될 때 (예: Permission Denied (public key)) deubgging에 유용

ssh -v user@hostname


id_rsa가 아닌 다른 키를 사용해 SSH 접속할 경우

ssh -i ~/.ssh/id_rsa user@hostname


위와 같이 매번 -i 옵션을 사용하고 싶지 않거나, 사용할 수 없을 때 (예: own git server에 git push 할 때 등)

~/.ssh/config 파일을 생성하고 아래와 같은 syntax로 작성

windows(git bash)/linux 모두 위와 같이 설정하면 됨. system config은 /etc/ssh/ssh_config


Host <HOST>

User git

HostName <hostname>

IdentityFile ~/.ssh/git_rsa.pem



'Linux' 카테고리의 다른 글

Debian/Ubuntu Linux에 Git Server 설치하기  (0) 2018.06.21
Xilinx Gnome-power error  (0) 2018.04.17
[linux] ia32-libs - ubuntu 최신버전 (>=14.04)  (0) 2018.03.28
[Linux] 한글 인코딩  (1) 2018.03.21
[Linux] sudo path 설정방법  (0) 2018.03.20

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

beautifulsoup4은 파싱 라이브러리

scrapy는 크롤링 프레임워크


beautifulsoup4(bs4)에는 request 부분이 포함되어 있지 않다

하지만 scrapy는 포함되어 있고, 동시에 여러 개의 요청을 보낸다, 즉 별도구현없이 빠르다는 차이점이 있다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

https://profiles.google.com/connectedaccounts

여기 아니다. 여기는 연동 서비스 관리인 듯


https://myaccount.google.com/permissions

여기다




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<클라이언트 입장>

form tag로 데이터를 전송할 경우, Content-Type은 아래와 같다


Content-Type: application/x-www-form-urlencoded


즉, 한글 데이터는 URL Encoding되어 %xx%xx%xx... 식으로 변환되어 submit 된다



<서버 입장>

그리고 서버에서 해당 필드를 읽을 때, url encoded string을 그대로 읽힌다 (tomcat servlet 기준)

(참고로 '%'의 경우 %25로 encoding 될 것 이다)


따라서, 서버에서는 별도의 decoding 작업이 필요하다

이 때 encoded type과 decode type이 sync 되어야 한다


encoding type을 cp949 또는 euc-kr에서 UTF-8로 맞춰주는 부분을 가장 먼저 신경 쓰지만


값이 url encoded string으로 읽힌다는 부분은 많이 놓치지 않을까 싶다


필자가 겪은 시행착오의 메모였다


'Web' 카테고리의 다른 글

[Web Dev] Back-end Languages 종류,특징  (5) 2019.06.24
[Javascript] var vs let 차이  (0) 2018.04.23
[Web] elasticsearch.js  (0) 2018.04.23
[Web] Javascript format string implementation  (0) 2018.04.08
[Web] 네이버 캘린더 오픈API, CalDAV  (0) 2018.04.08

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

map object 생성방법은 아래와 같다


map(type, iterable)


어디에 사용할 수 있느냐? 하나의 라인에 여러 개의 int value를 입력받을 때 사용할 수 있다


a,b,c = map(int, input().split(' '))

# input example: 1 2 3


map 또한 iterable 타입으로서, next() 함수를 통해 순회할 수 있다




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

이 글에는 필자의 주관이 들어가있으며, 이 책의 좋다 또는 나쁘다 평가를 목적으로 한 글이 아닙니다


읽었던 내용을 잊지 않기 위한 메모 목적으로 이 글을 작성합니다


---


<표지>

심리학의 잣대로 분석한 도시인의 욕망과 갈등.

머물기에는 갑갑하고 떠나기에는 아쉬운 이곳 우리를 도시인이게 하는 22가지 심리.


<뒷면>

지친 도시인의 삶을 위로하는 명쾌한 심리 치유서.

복잡한 도시인의 마음을 뒤흔드는 심층 심리를 분석한다.


<작가의 말>

작가는 이 책을 통해 대한민국의 현재, 도시의 삶, 궁극적으로 도시 집단 속의 나를 샅샅이 살펴보고 이야기하려 한다

무엇이 우리를 짓누르고 있고 우리의 삶을 지배하고 있는지, 무엇 때문에 괴로운지 그 속삭을 한번 보자. - 2009년 5월


2009년이면 스마트폰이 이제 막 나오기 시작하던 때였던 것 같다.


1장 소통의 부재

 - 전화보다 문자, 소통이 아닌 통보의 커뮤니케이션

사람들은 보이지 않는 심리적 안전공간을 확보하기 위해 노력한다.

그리고 여기에 휴대전화가 등장한다. 


전화를 받았을 때 "지금 어디야?"라고 상대방이 묻는 것 (휴대전화로 통화 시에 가장 불쾌한 말이라고 한다)

휴대전화 벨이 울리면 즉각 응대해야 하는 어려움.

휴대전화는 편리함의 뒷면에서 우리의 심리적 안전공간을 위협한다고 할수 있다


휴대전화가 동시적 커뮤니케이션으로서 실시간 반응을 해야하므로 많은 에너지를 소모해야 한다는 반면,

문자와 같은 비동시적 커뮤니케이션은 느리지만 편하고 에너지가 덜 든다.


우울증세를 보이는 한 고등학생이 자신을 찾아와서 하소연한 이야기가 있다

친구들이 자신을 차단해놓고 "우리 요즘 그 사이트 안 가"라고 했다는 것이다

온라인에서의 상실감은 오프라인보다 더 클 수도 있다


문자(요즘으로 치면 카톡, SNS)를 통한 소통은 안전하고 편하지만 비효율적이다

목소리, 얼굴 표정과 같은 풍부한 정서는 느낄 수 없다

이모티콘을 사용하고, 길게 쓰고, 농담을 해도 목소리만 들어도 알 수 있었던 깊은 정서적 교감은 어렵다


테크놀로지는 우리가 원하는 방향으로 발달했다고 저자는 말한다

편하고 빠르고 이기적이면서도 욕먹지 않을 수 있으면서도 안전한 방향으로.

하지만 인간관계의 본질은 지연과 둘러감은 있어도 변화는 없다고 한다


방법이 많아지고 거리가 가까워지고 시간의 제약이 없어져도 여전히 외롭다. 어떨 때는 그 이전보다 더.


저자는 우리의 외로움이, 도시의 발달로부터 온다고 설명하는 듯 하다

편리해지는 것이 오히려 역으로 우리를 더 외롭게 만든다고


제목과 연관지어보자면, 전화보다 문자가 주가 되면서 깊은 정서적 교감이 부재하게 되었다고 말하는 것 아닐까




 - 우리는 하나다, 폭탄주를 마시면...

여기는 요약하자면, 도시의 삶에서 친해지고 싶지 않지만 의무적으로 친해져야 하는 비즈니스 관계에서.


폭탄주가 해결책이 되어준다고 한다. 흡수가 빠른만큼 거부감도 크지만.


그리고 비즈니스 관계 속에서 자신의 심리적 공간을 어떻게 확보하지는지.




 - 다문화가정을 순순히 받아들이기 어려운 이유

차별의 또다른 이름, 단일민족.


역사를 돌이켜볼 때 억압받은 적이 있는 집단의 결속력은 매우 강하다고 한다.


유대인이 있고, 우리나라가 있다 (일제강점기)


우리나라를 포함하여 이런 민족은 힘든 일이 발생하면 '우리 민족은 자랑스러운 민족이나 외부의 침략에 피해를 입어 지금 힘들게 살고 있다'는 피해자 논리가 습한 날 곰팡이같이 순식간에 퍼진다.


외국인이 우리나라에서 살기 힘들다고 이야기하면서,


오랫동안 억울함을 당해온 민족이라는 세뇌를 받아온 우리는 그렇게 '되로 받고 말로 갚는' 마음으로 '명동에서 뺨 맞고 한강에서 화풀이'를 하고 있다고 한다


집단의 순도가 떨어지는 것에 대한 과도한 두려움이 이러한 경향을 강화한다 (즉 다문화에 대한 거부감을 이야기한다)


우리나라 사람들이 다문화 가정 사람에게 공격성을 보이는 이유를 위와 같이 설명한다




 - 믿으면 천국행, 믿지 않으면 지옥행?

이 부분을 읽으면서, 저자는 종교에 대해서 부정적이거나, "도를 아십니까"에 많이 시달린 것 같다고 느꼈다 (...)


사는 것이 각박해질수록 사람들은 마음의 위안처를 찾는다.


종교의 근원은 인간이 알 수 없는 자연의 섭리를 설명하기 위해 만들어진 것이라고 설명한다.


그런데 지금, 자연현상은 웬만하면 다 설명할 수 있지만 오히려 종교인의 수는 오히려 늘고있다


역사는 과학이 영원불변한 진실일 수 없다고 반복해서 알려줬고


그러므로 나와 세상 사이의 연결 역시 안정적으로 어어져 있기 힘들 수밖에 없으며


이러한 상황으로 인해 논리적으로 답할 수 없는 초자연적인 '신'의 영역이 존재의 불안을 해결해 줄 것이라 믿게 되는 것이라고 한다


다음 내용은 극도로 축약해서, 종교활동에서 카타르시스를 경혐할 수도 있는데, 카타르시스를 집단적으로 경험할 경우 사람들 사이의 결속력과 연대의식은 시너지를 이루며 강력해질 것이라고 말한다


"혹시 믿음이 있으신지요?"


필자가 이런 질문을 받았던 경험을 이야기하며 답답함, 반발감, 자존심 훼손을 일으킨다고 한다


그리고 믿음을 강조하며 반복해서 얘기하는 사람일수록 자신의 존재와 삶에 대한 근복적 미등ㅁ이 약하고 그마저도 흔들리고 있을 가능성이 높다고 한다


이후 여러가지 설명에 프로이트의 논리로 설명이 되어있고


이 도시의 밤을 비추는 수많은 십자가들은 결국 도시인의 집단적인 외로움과 고립감, 불안감을 반영하는 지표라고 한다

(이 부분은 읽으면서 종교인들에 대해 저자의 시선이 부정적이라고 느껴졌다)




 - 영어라면 무조건 오케이, 예스맨의 두 얼굴

여기도 프로이트의 말 중에서 트라우마, 히스테리 연구를 통해서 설명한다


조기 영어교육 열풍을 비판하는 듯 하고, 커다란 희생을 겪어가며 얻어내려는 영어에 대한 무모한 집착, 굳은 결의의 내면에 그만큼 강한 공격성이 숨어 있다고 이야기 한다


그리고 동남아에 가서 그들의 영어 사용수준을 트집잡는 공격성도 언급한다


이쯤 읽으보니, 저자는 우리가 도시에서 살면서 느끼는 외로움 등보다는,

자신이 타인에게 공격적인 태도를 보이는 이유에 대해서 탐구하고 반성해보라는 뉘앙스로 느껴진다




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def func():
    for i in range(10):
        yield i
    return 'exit'
 
for i in func():
    print(i)
 
''' output
0
1
2
...
9
'''
 
cs



마지막 return문의 'exit'는 출력되지 않는다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

tensorflow를 통해 MNIST 데이터를 입력으로, regression analyse model을 학습시키는 튜토리얼

https://tensorflowkorea.gitbooks.io/tensorflow-kr/content/g3doc/tutorials/mnist/beginners/




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

[Javascript] var vs let 차이

Web 2018. 4. 23. 20:54

var는 function-scoped

let은 block-scoped


let이 좀더 C언어의 변수선언과 비슷한 느낌이다


https://gist.github.com/LeoHeo/7c2a2a6dbcf80becaaa1e61e90091e5d


'Web' 카테고리의 다른 글

[Web Dev] Back-end Languages 종류,특징  (5) 2019.06.24
[Web] form tag와 한글 인코딩  (0) 2018.04.26
[Web] elasticsearch.js  (0) 2018.04.23
[Web] Javascript format string implementation  (0) 2018.04.08
[Web] 네이버 캘린더 오픈API, CalDAV  (0) 2018.04.08

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

[Web] elasticsearch.js

Web 2018. 4. 23. 20:49

필자는 React Javascript Framework를 통해 웹페이지를 개발하고 있다

그리고 elasticsearch도 이용하고 있다

아래 모듈은 elasticsearch 사용을 더 쉽게 만들어줄 것이다


아래 커맨드를 통해 설치할 수 있다

npm i --save-dev elasticsearch


아래 Quick Start를 따라가자

https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/quick-start.html



'Web' 카테고리의 다른 글

[Web] form tag와 한글 인코딩  (0) 2018.04.26
[Javascript] var vs let 차이  (0) 2018.04.23
[Web] Javascript format string implementation  (0) 2018.04.08
[Web] 네이버 캘린더 오픈API, CalDAV  (0) 2018.04.08
[Web] rudux: reduce + flux  (0) 2018.04.05

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/


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
# 1, 2, 3 더하기
 
class Counter(object):
    save = None
 
    def init_save(self, N):
        if N < 3:
            N = 3
 
        self.save = [None] * (N+1)
        self.save[1= 1
        self.save[2= 2
        self.save[3= 4
 
    def count_of_combination(self, N):
        if N < 1:
            return 0
        elif self.save[N] != None:
            return self.save[N]
        else:
            result = (self.count_of_combination(N-1)
                      + self.count_of_combination(N-2)
                      + self.count_of_combination(N-3))
            self.save[N] = result
            # print('save[{}]={}'.format(N, result))
            return result
 
def main():
    T = int(input())
 
    counter = Counter()
 
    for i in range(T):
        N = int(input())
        counter.init_save(N)
        cnt = counter.count_of_combination(N)
        print(cnt)
 
if __name__ == '__main__':
    main()
 
cs





WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

http://www.bloter.net/archives/201445



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

<블로그 주인장의 말>

프로젝트를 진행하고 시간이 지난 후, 프로젝트를 재개하거나 다시 살펴봐야 할 일이 생겼을 때.

그 프로젝트를 다시 보려면 큰 각오가 필요하고 엄두가 안난다면?

이 책을 한번 읽어보자. 내가 코드를 클린하게 짜고 있는지.


---


코드는 요구사항의 상세한 표현이다


<클린코드의 4가지 원칙?>

중복을 피하라

한 기능만 수행하라

제대로 표현해라

작게 추상화해라


<우리는 저자다>
Javadoc에는 @author 필드가 있다

코드 작성을 글 작성처럼 이야기하는 듯 하다 (의도를 표현하는 글)


<좋은 코드를 작성하는 것은 오래 걸린다?>

80년대 에디터는 입력한 모든 커맨드를 기억했다. 그것을 재생시켜보면 실제로 코딩시간의 90%는 화면을 스크롤하고, 코드를 읽는 시간이었다고 한다

좋은 코드는 읽기 쉽다. 잘 안 읽히는 코드는, 코드 작성을 어렵게 만든다


변수/클래스는 명사구

함수/메서드는 동사구


<함수는 짧게>

함수길이는 최소한 한 화면에 들어와야 한다고 생각하고 있었지만,

이 책에서는 심지어 함수가 2~4줄 정도로 작아야 의도를 잘 표현한다고 이야기한다


함수의 최대 들여쓰기는 2단 이하를 추천한다

블록을 함수로 분리함으로써 2단 이하로 줄이는 것이다


함수 내 모든 라인의 추상화 레벨은 동일하게


SRP: Single Responsibility Principle

 - 가지 책임만 가져야 한다

OCP:Open Closed Principle

 - 변경에 닫혀있어야 한다 (new employee type이 추가될 때마다 case문을 추가해야한다)


앞부분에 Abstract Factory 패턴이 자주 나온다


<서술적인 이름 사용>

함수 이름이 길어도 괜찮다.

짧고 어려운 이름보다, 길고 서술적인 주석보다 좋다.


발음하기 쉬운 이름 사용


<파라메터>

파라메터 3개 이상은 피하자

특별한 이유가 없다면


많은 파라메터는 테스트도 어렵게 만든다


아웃풋 파라메터는 더 어렵다. 피하자


플래그 파라메터도 피하자

함수가 플래그에 따라 두가지 일을 한다고 대놓고 공표하는 셈이니까!

ex) render(True)


new Point(0,0)의 파라메터

이것은 한 값을 표현하는 두 요소이다. 두 요소에는 자연적인 순서도 있다


assertEquals(expected, actual)

이 함수는 2항을 피할수는 없지만, 항 사이 순서가 없다. 헷갈린다!


<오류코드 리턴보다는 예외 처리를 사용하라>

if문으로 에러코드를 리턴하면, caller는 에러코드를 "즉시" 처리해야 한다는 문제에 부딪힌다

하지만 try/catch문을 사용하면, 에러 처리 코드를 분리할 수 있다


또 하지만, 저자는 try/catch문이 코드 구조에 혼란을 일으키며 정상동작/에러처리 코드를 뒤섞어놓는다고 한다 (이해는 잘 안되지만)

그러므로 try, catch 블록 각각을 함수화 시켜야 한다고 이야기한다


좀더 추가설명을 하자면, 에러처리도 "한 작업"이므로 분리해야 한다는 것이다


<주석보다는 코드로 의도를 표현하라>

저자는 최대한 주석을 줄이라고 이야기한다

심지어 주석은 실패를 의미한다고 한다. 코드로 의도를 표현하는 데에 실패했다는 것이다



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

https://ko.wikipedia.org/wiki/%ED%8F%AC%ED%93%B0%EB%A6%AC%EC%A6%98#%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%97%90%EC%84%9C%EC%9D%98_%ED%8F%AC%ED%93%B0%EB%A6%AC%EC%A6%98_%EB%85%BC%EB%9E%80


대한민국에서 포퓰리즘은 "정책의 현실성이나 가치판단, 옳고 그름 등 본래 목적을 외면하고 대중적 인기에만 영합해 목적을 달성하려는 정치 행태", "인기영합주의", "대중추수주의" 등과 같은 부정적인 의미로 사용되고 있다.



WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Xilinx Gnome-power error

Linux 2018. 4. 17. 02:14

https://stackoverflow.com/a/32578786


리눅스 GUI에서 화면이 뜨지 않을 때, console로 진입하는 핫키는 Ctrl+Alt+F2이다


Xilinx default user

user: ise

password: xilinx




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Enable/Disable Hyper-V

etc 2018. 4. 17. 01:22

https://stackoverflow.com/a/35812945


disable

bcdedit /set hypervisorlaunchtype off


enable

bcdedit /set hypervisorlaunchtype auto 




WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Preemptive Scheduling

종류

 - round-robin

 - priority algorithm

특징

 - 현재 프로세스의 작업이 완료되지 않았음에도, 조건이 만족되면 다른 프로세스가 리소스를 선점할수 있다


Non-preemptive Scheduling

종류

 - FIFO

 - SJF

특징

 - 현재 프로세스의 작업이 완료될 때까지 다른 프로레스가 리소스를 선점할 수 없다


'etc' 카테고리의 다른 글

대한민국에서의 포퓰리즘 의미 (populism)  (3) 2018.04.17
Enable/Disable Hyper-V  (0) 2018.04.17
나이브 베이즈 분류  (0) 2018.04.15
[Web] Content-Type application/x-ndjson  (0) 2018.04.13
NTFS 저널링 파일 시스템 vs FAT  (0) 2018.04.13

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

나이브 베이즈 분류

etc 2018. 4. 15. 16:26

http://gomguard.tistory.com/69


텍스트를 분석하는 (의미를 알아내는) Language Model

텍스트 분석 Machine Learning


이라는 토픽에서 베이스 지식이다




나이브 베이즈 분류를 이해하기 위해서는 베이지안 룰을 알아야 한다

위 링크에 그 설명이 있다


'etc' 카테고리의 다른 글

Enable/Disable Hyper-V  (0) 2018.04.17
CPU Scheduling Policy: preemtive vs nonpreemtive  (0) 2018.04.16
[Web] Content-Type application/x-ndjson  (0) 2018.04.13
NTFS 저널링 파일 시스템 vs FAT  (0) 2018.04.13
인문학 추천도서 링크 모음  (0) 2018.04.12

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

Content-Type에는 여러 종류가 있는데, 그 중 json을 보내기 위한 Type이 있다

그중, 여러개의 json을 보내기 위한 type도 존재하는데 아래이다


Content-Type: application/x-ndjson  


예를들면 이렇게


{ ... }

{ ... }


Elasticsearch Bulk API가 그러한 형식을 이용한다


https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html



'etc' 카테고리의 다른 글

CPU Scheduling Policy: preemtive vs nonpreemtive  (0) 2018.04.16
나이브 베이즈 분류  (0) 2018.04.15
NTFS 저널링 파일 시스템 vs FAT  (0) 2018.04.13
인문학 추천도서 링크 모음  (0) 2018.04.12
[elasticsearch] scan, scroll  (0) 2018.04.11

WRITTEN BY
hojongs
블로그 옮겼습니다 https://hojongs.github.io/

사용중인 블로그 스킨이 방명록을 지원하지 않습니다.

초대장을 받고싶으신 분들은 댓글 또는 블로그 설명의 메일로.