<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>brian_j.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 12 Jun 2022 13:27:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>brian_j.log</title>
            <url>https://velog.velcdn.com/images/brian_j/profile/e853220f-c244-4520-b1ac-855fae94748b/image.webp</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. brian_j.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/brian_j" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[코드카타]]></title>
            <link>https://velog.io/@brian_j/%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80-dj14bj81</link>
            <guid>https://velog.io/@brian_j/%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80-dj14bj81</guid>
            <pubDate>Sun, 12 Jun 2022 13:27:59 GMT</pubDate>
            <description><![CDATA[<p>문제
로마자에서 숫자로 바꾸기 1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요.</p>
<p>로마 숫자를 숫자로 표기하면 다음과 같습니다.</p>
<p>Symbol    Value
I    1
V    5
X    10
L    50
C    100
D    500
M    1000
로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다. III = 3 XII = 12 XXVII = 27입니다.</p>
<p>그런데 4를 표현할 때는 IIII가 아니라 IV 입니다. 뒤의 숫자에서 앞의 숫자를 빼주면 됩니다. 9는 IX입니다.</p>
<p>I는 V와 X앞에 와서 4, 9 X는 L, C앞에 와서 40, 90 C는 D, M앞에 와서 400, 900</p>
<p>풀이</p>
<pre><code class="language-python">def roman_to_num(s):
    li = [&quot;M&quot;, &quot;D&quot;, &quot;C&quot;, &quot;L&quot;, &quot;X&quot;, &quot;V&quot;, &quot;I&quot;]
    li_2 = [1000, 500, 100, 50, 10, 5, 1]
    poo = []
    result = 0
    for i in s:
        index = li.index(i)
        poo.append(index)
    for i, v in enumerate(s):
        if i == len(s)-1:
            result += li_2[li.index(v)]
            break

        if poo[i] &gt; poo[i+1] :
            result -= li_2[li.index(v)]
        else :
            result += li_2[li.index(v)]

    return result</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[코드카타]]></title>
            <link>https://velog.io/@brian_j/%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80</link>
            <guid>https://velog.io/@brian_j/%EC%BD%94%EB%93%9C%EC%B9%B4%ED%83%80</guid>
            <pubDate>Sun, 12 Jun 2022 13:12:28 GMT</pubDate>
            <description><![CDATA[<p>문제
숫자로 이루어진 배열인 nums를 인자로 전달합니다.</p>
<p>숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.</p>
<p>예를 들어,</p>
<p>nums = [3,2,3]
return 3</p>
<p>nums = [2,2,1,1,1,2,2]
return 2</p>
<p>가정
nums 배열의 길이는 무조건 2 이상입니다.</p>
<p>풀이</p>
<pre><code class="language-python">def more_than_half(nums):
    nums.sort()

    i = 0
    while i &lt;= len(nums)-1:

        if nums.count(nums[i]) &gt;= len(nums)/2:
            return nums[i]

        else :
            i += nums.count(nums[i])</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[코트카타 ]]></title>
            <link>https://velog.io/@brian_j/%EC%BD%94%ED%8A%B8%EC%B9%B4%ED%83%80-vv3xwx2n</link>
            <guid>https://velog.io/@brian_j/%EC%BD%94%ED%8A%B8%EC%B9%B4%ED%83%80-vv3xwx2n</guid>
            <pubDate>Sun, 12 Jun 2022 12:59:41 GMT</pubDate>
            <description><![CDATA[<p>문제
주어진 숫자 배열에서, 0을 배열의 마지막쪽으로 이동시켜주세요. 원래 있던 숫자의 순서는 바꾸지 말아주세요.</p>
<p>새로운 배열을 생성해서는 안 됩니다.
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]</p>
<p>풀이</p>
<pre><code class="language-python">def move_zeroes(nums):
    znt = nums.count(0)
    for i in range(znt):
        del nums[nums.index(0)]
        nums.append(0)
    return nums</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[(알고리즘) 배낭 문제 (knapsack Problem)]]></title>
            <link>https://velog.io/@brian_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B0%EB%82%AD-%EB%AC%B8%EC%A0%9C-knapsack-Problem</link>
            <guid>https://velog.io/@brian_j/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B0%EB%82%AD-%EB%AC%B8%EC%A0%9C-knapsack-Problem</guid>
            <pubDate>Sun, 05 Jun 2022 05:19:35 GMT</pubDate>
            <description><![CDATA[<h1 id="1-개요">1. 개요</h1>
<p>조합최적화 문제의 일종이다. 한정된 가방의 무게 W안에서 가치가 최대가 되도록 아이템들의 부분집합을 찾는 문제이다.
&#39;분할 가능한 배낭&#39;과 &#39;분할 가능하지 않은 배낭&#39; 문제로 구분된다. 후자는 흔히 &#39;0-1 배낭 문제&#39;로 표현된다.</p>
<h1 id="2-0-1-배낭문제">2. 0-1 배낭문제</h1>
<p>0-1 배낭문제 (0-1 Knapsack Problem)는 동적계획법, 백트래킹 등의 조합 최적화 문제 풀이의 방법을 사용해야 한다.</p>
<p>동적계획법을 이용한 풀이</p>
<pre><code class="language-python">def knapsack2(i, W, w, p):
    if (i &lt;= 0 or W &lt;= 0):
        return 0
    if (w[i] &gt; W):
        value = knapsack2(i - 1, W, w, p)
        print(i - 1, W, value)
        return value
    else: # w[i] &lt;= W
        left = knapsack2(i - 1, W, w, p)
        print(i - 1, W, left)
        right = knapsack2(i - 1, W - w[i], w, p)
        print(i - 1, W - w[i], right)
        return max(left, p[i] + right)</code></pre>
<p>출처 : <a href="https://namu.wiki/w/%EB%B0%B0%EB%82%AD%20%EB%AC%B8%EC%A0%9C">https://namu.wiki/w/%EB%B0%B0%EB%82%AD%20%EB%AC%B8%EC%A0%9C</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[django - transaction]]></title>
            <link>https://velog.io/@brian_j/django-transaction</link>
            <guid>https://velog.io/@brian_j/django-transaction</guid>
            <pubDate>Sun, 05 Jun 2022 05:03:21 GMT</pubDate>
            <description><![CDATA[<p>DB에 연속된 처리를 실행할 때, 중간점에서 에러가 발생한다면 데이터의 무결성(integrity)이 보장되지 않는다.</p>
<p>이러한 이유로 연속된 데이터베이스 처리를 하는 경우 django에서 제공하는 transaction 메서드를 사용한다.</p>
<pre><code class="language-python">from django.db import transaction

@transaction.non_atomic_requests
def my_view(request):
    do_stuff()

@transaction.non_atomic_requests(using=&#39;other&#39;)
def my_other_view(request):
    do_stuff_on_the_other_database()</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[python 기초 - 데이터타입 (튜플, 세트)]]></title>
            <link>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%ED%8A%9C%ED%94%8C-%EC%84%B8%ED%8A%B8</link>
            <guid>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%ED%8A%9C%ED%94%8C-%EC%84%B8%ED%8A%B8</guid>
            <pubDate>Sun, 29 May 2022 09:10:55 GMT</pubDate>
            <description><![CDATA[<p>튜플 타입으로 선언 또는 변환</p>
<ol>
<li>(value1, value2, ... ) 으로 선언
예시) a = (1, 2, 3)</li>
</ol>
<p>기본적으로 리스트 타입과 유사하지만 가장 큰 차이는 튜플은 한 번 선언되고나면 수정이 안된다는 것이다.</p>
<p>세트 타입으로 선언 또는 변환</p>
<ol>
<li>{value1, value2, ... } 으로 선언</li>
</ol>
<p>세트는 요소의 중복을 허용하지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[python 기초 - 데이터타입 (리스트, 딕셔너리)]]></title>
            <link>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EB%94%95%EC%85%94%EB%84%88%EB%A6%AC</link>
            <guid>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EB%94%95%EC%85%94%EB%84%88%EB%A6%AC</guid>
            <pubDate>Sun, 29 May 2022 09:10:04 GMT</pubDate>
            <description><![CDATA[<h2 id="리스트-타입으로-선언-또는-변환">리스트 타입으로 선언 또는 변환</h2>
<ol>
<li><p>[]로 선언
예시 ) a = [1,2,3]</p>
</li>
<li><p>list() 함수 이용
b = &quot;123&quot;
c = list(b)
c
[&quot;123&quot;]</p>
</li>
</ol>
<h2 id="딕셔너리-타입으로-선언-또는-변환">딕셔너리 타입으로 선언 또는 변환</h2>
<ol>
<li><p>{key : value} 로 선언
예시) a = {&#39;id&#39;:&#39;1234123&#39;}</p>
</li>
<li><p>dict() 함수 사용</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[python 기초 - 데이터타입 (숫자, 문자)
]]></title>
            <link>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90</link>
            <guid>https://velog.io/@brian_j/python-%EA%B8%B0%EC%B4%88-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90</guid>
            <pubDate>Sun, 29 May 2022 09:08:55 GMT</pubDate>
            <description><![CDATA[<p>파이썬의 데이터타입은 숫자형, 문자형, 리스트, 딕셔너리, 튜플, 세트, 불(boolean)형이 있다.</p>
<p>숫자형
int와 float, 그리고 복소수형태가 있다.</p>
<h2 id="숫자형의-선언-및-변환">숫자형의 선언 및 변환</h2>
<ol>
<li>num = 123<pre><code class="language-python">num = 123
print(num, type(num))
123 &lt;class &#39;int&#39;&gt;</code></pre>
</li>
</ol>
<h2 id="문자형의-선언-및-변환">문자형의 선언 및 변환</h2>
<ol>
<li>str = &quot;hello, python!&quot;<pre><code class="language-python">str = &quot;hello, python!&quot;
</code></pre>
</li>
</ol>
<p>print(str, type(str))
hello, python! &lt;class &#39;str&#39;&gt;
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JWT]]></title>
            <link>https://velog.io/@brian_j/JWT</link>
            <guid>https://velog.io/@brian_j/JWT</guid>
            <pubDate>Fri, 20 May 2022 02:28:20 GMT</pubDate>
            <description><![CDATA[<p>JWT - JSON Web Token</p>
<p>토큰 발급에 관한 라이브러리이다.</p>
<p>http는 stateless 하기 때문에 웹사이트 이용시 계속적으로 유저정보를 함께 보내줘야 한다. 따라서 유저가 어떤 요청을 보낼 때, 해당유저임을 확인할 수 있도록, 로그인시 token을 발급하고, 이후에는 headers에 포함된 token 정보를 통해 유저정보를 식별할 수 있다.</p>
<pre><code class="language-python"># Token 발급
token = jwt.encode( {&#39;account_id&#39;: account.id}, settings.SECRET_KEY, settings.ALGORITHM)

# Token 확인
token = request.headers.get(&#39;Authorization&#39;)
payload = jwt.decode(token, settings.SECRET_KEY, settings.ALGORITHM)
request.account = Accounts.objects.get(id=payload[&#39;account_id&#39;])</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[비밀번호 암호화]]></title>
            <link>https://velog.io/@brian_j/%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%95%94%ED%98%B8%ED%99%94</link>
            <guid>https://velog.io/@brian_j/%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%95%94%ED%98%B8%ED%99%94</guid>
            <pubDate>Fri, 20 May 2022 02:07:11 GMT</pubDate>
            <description><![CDATA[<h2 id="encoding-과-decoding">encoding 과 decoding</h2>
<p>encoding : &#39;str&#39; -&gt; &#39;byte&#39;
decoding : &#39;byte&#39; -&gt; &#39;str&#39;</p>
<h2 id="bcrypt">bcrypt</h2>
<p>pip install bcrypt</p>
<p>기본 문법 : bcrypt.hashpw(password, salt)
salt 생성 : bcrypt.gensalt([num])
비밀번호 확인 : bcrypt.checkpw(password, hashed_pw)</p>
<h3 id="회원가입시-비밀번호-암호화">회원가입시 비밀번호 암호화</h3>
<pre><code class="language-python">class SignupView(View):
    def post(self, request):

        try :
            signup_data = json.loads(request.body)
            email       = signup_data[&quot;email&quot;]
            password    = signup_data[&quot;password&quot;]    

            hashed_pw = bcrypt.hashpw(password.encode(&#39;utf-8&#39;), bcrypt.gensalt())

            Accounts.objects.create(
                name         = signup_data[&quot;name&quot;],
                email        = email,
                password     = hashed_pw.decode(&#39;utf-8&#39;),
                phone_number = signup_data[&quot;phone_number&quot;],
                )

            return JsonResponse({&quot;MESSAGE&quot;: &quot;SUCCESS&quot;}, status=201)

        except KeyError :
            return JsonResponse({&quot;MESSAGE&quot;: &quot;KEY_ERROR&quot;}, status=400)</code></pre>
<p>request.body에 담겨온 데이터를 json.loads로 ditc type으로 캐스팅해서 signup_data에 담는다.</p>
<p>이 중 key 가 &quot;password&quot;인 value를 &#39;password&#39;라는 변수에 담고, bycrypt의 메서드를 활용해서 암호화하는 과정이다.</p>
<p>초기에 입력받은 password 는 str 타입이므로 encoding을 통해 byte 타입으로 바꿔서 활용한다.</p>
<p>이렇게 암호화된 비밀번호를 DB에 저장할 때는 다시 str 타입으로 바꿔줘야 한다(decoding)</p>
<h3 id="로그인시-비밀번호-체크">로그인시 비밀번호 체크</h3>
<p>bcrypt.checkpw(password, hashed_pw)</p>
<pre><code class="language-python">class LoginView(View):
    def post(self, request):

        try :
            login_data = json.loads(request.body)
            email      = login_data[&quot;email&quot;]
            password   = login_data[&quot;password&quot;]

            account = Accounts.objects.get(email=email)
            if not bcrypt.checkpw(password.encode(&#39;utf-8&#39;), account.password.encode(&#39;utf-8&#39;)) :
                raise ValidationError(&quot;INCORRECT_PASSWORD&quot;)

            token = jwt.encode( {&#39;account_id&#39;: account.id}, settings.SECRET_KEY, settings.ALGORITHM)

            return JsonResponse({&quot;TOKEN&quot;: token}, status=201)

        except KeyError :
            return JsonResponse({&quot;MESSAGE&quot;: &quot;KEY_ERROR&quot;}, status=400)

        except ValidationError as verr :
            return JsonResponse({&quot;MESSAGE&quot;: verr.message}, status=401)</code></pre>
<p>중간에 jwt 라는 녀석이 나오는데 토큰발급에 관한 라이브러리 이므로 별도 포스팅으로 다루도록 하자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[로그인 기능 구현 (LoginView)]]></title>
            <link>https://velog.io/@brian_j/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84-LoginView</link>
            <guid>https://velog.io/@brian_j/%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B8%B0%EB%8A%A5-%EA%B5%AC%ED%98%84-LoginView</guid>
            <pubDate>Mon, 16 May 2022 04:49:53 GMT</pubDate>
            <description><![CDATA[<h2 id="예외처리">예외처리</h2>
<h3 id="1-아무런-입력값-없이-login-요청할-경우-jsondecodeerror-반환request_without_data-400">1. 아무런 입력값 없이 login 요청할 경우, JSONDecodeError 반환(REQUEST_WITHOUT_DATA, 400)</h3>
<pre><code class="language-python">except json.decoder.JSONDecodeError :
    return JsonResponse({&quot;MESSAGE&quot;: &quot;REQUEST_WITHOUT_DATA&quot;}, status=400)</code></pre>
<p><img src="https://velog.velcdn.com/images/brian_j/post/8e8a08e1-c34e-4ce5-be19-23afa2d708d6/image.png" alt=""></p>
<h3 id="2-email-또는-password가-전달되지-않을-경우-keyerror-반환key_error-400">2. &#39;email&#39; 또는 &#39;password&#39;가 전달되지 않을 경우, KeyError 반환(KEY_ERROR, 400)</h3>
<pre><code class="language-python">except KeyError :
    return JsonResponse({&quot;MESSAGE&quot;: &quot;KEY_ERROR&quot;}, status=400)</code></pre>
<p><img src="https://velog.velcdn.com/images/brian_j/post/3a17feeb-c4cb-4d08-8b74-abf257e52ba7/image.png" alt="">
email은 필드명이 기재되어 &quot;&quot;빈 데이터로 전달은 되었으나, password 가 전달되지 않아 KeyError 반환 (400) &lt; 아래 예시와 비교&gt;</p>
<h3 id="3-email-또는-password가-일치하지-않을-경우-에러반환-invalid_user-401">3. email 또는 password가 일치하지 않을 경우, 에러반환 (INVALID_USER, 401)</h3>
<pre><code class="language-python">    if not Accounts.objects.filter(email=email, password=password).exists() :
        raise ValidationError(&quot;INVALID_USER&quot;)

    ...

except ValidationError as verr :
    return JsonResponse({&quot;MESSAGE&quot;: verr.message}, status=401)</code></pre>
<p><img src="https://velog.velcdn.com/images/brian_j/post/9e882cd9-76fd-482d-8ac1-ef4363a8d727/image.png" alt="">
email, password 가 모두 전달되었으나, 일치하는 데이터가 없어 (INVALID_USER, 401) 반환</p>
<h2 id="로그인-성공">로그인 성공</h2>
<pre><code class="language-python">    return JsonResponse({&quot;MESSAGE&quot;: &quot;SUCCESS&quot;}, status=201)</code></pre>
<p><img src="https://velog.velcdn.com/images/brian_j/post/d17b4a17-3c25-48bd-a3a5-a785f8e04c46/image.png" alt=""></p>
<p>DB에 저장된 email과 password 비교하여 올바른 값을 입력할 경우, (SUCCESS, 201) 반환 </p>
<p>(생각해볼점) 로그인 성공시 왜 Created라고 표출될까 ?
<img src="https://velog.velcdn.com/images/brian_j/post/80aecc53-af5c-4513-85e3-7087aedbd750/image.png" alt=""></p>
<p>(출처 : <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status">https://developer.mozilla.org/en-US/docs/Web/HTTP/Status</a>)</p>
<p>해석하면, 일반적인 POST 또는 PUT 응답에 대한 일반적인 응답이라는 내용이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(python) class]]></title>
            <link>https://velog.io/@brian_j/python-class</link>
            <guid>https://velog.io/@brian_j/python-class</guid>
            <pubDate>Sun, 15 May 2022 05:12:01 GMT</pubDate>
            <description><![CDATA[<h2 id="class-복습">class 복습</h2>
<p>Database 라는 이름의 <strong>class를</strong> 구현해 주세요.</p>
<p>Database 클래스 내부에 다음의 속성(attribute)들을 선언해주세요.</p>
<p>name : database의 이름
size : 저장할 수 있는 데이터의 max 사이즈. Size를 넘어서는 데이터를 저장할 수 없다.
Database 클래스 내부에 다음의 메소드들을 구현해주세요.</p>
<p>insert
select
update
delete
각 메소드들에 대한 설명은 아래와 같습니다.</p>
<h3 id="insert"><strong>Insert</strong></h3>
<p>insert 메소드는 self 외에 2개의 parameter를 받습니다.</p>
<p>field와 value 입니다.</p>
<p>Field 는 저장하고자 하는 데이터의 필드명이고 value는 값입니다.</p>
<p>Field 와 value는 내부적으로 dictionary에 저장되어야 합니다.</p>
<p>insert 메소드는 다음 처럼 호출 할 수 있습니다.</p>
<p>#객체 이름이 db 라는 가정하에
db.insert(&quot;name&quot;, &quot;정우성&quot;)
insert 메소드는 특별한 return 값은 없습니다.</p>
<p>단, 만일 내부 dictionary의 총 사이즈가 Database 클래스의 size 속성보다 크면 더이상 새로운 값들을 저장하지 말아야 합니다.</p>
<h3 id="select">Select</h3>
<p>select 메소드는 self 외에 1개의 parameter를 받습니다.</p>
<p>바로 field 입니다.</p>
<p>field 는 읽고자 하는 데이터의 필드명 입니다.</p>
<p>내부적으로 데이터를 저장하고 있는 dictionary에서 해당 field에 해당하는 키와 연결되어 있는 값을 return 해주어야 합니다.</p>
<p>예를 들어, 이미 name이라는 필드명으로 &quot;정우성&quot; 이라는 값을 저장했다고 한다면:</p>
<p>#객체 이름이 db 라는 가정하에
db.select(&quot;name&quot;)
 &quot;정우성&quot;
이 되어야 합니다.</p>
<p>만일 해당 필드값으로 저정되어 있는 값이 없다면 None 을 return 해주세요.</p>
<h3 id="update">Update</h3>
<p>self 외에 2개의 parameter를 받습니다.</p>
<p>field와 value 입니다.</p>
<p>이름 그대로 이미 저장되어 있는 값을 수정하는 메소드 입니다.</p>
<p>#객체 이름이 db 라는 가정하에
db.update(&quot;name&quot;, &quot;아이유&quot;)
만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.</p>
<p>그리고 특별한 return 값은 없습니다.</p>
<h3 id="delete">Delete</h3>
<p>delete 메소드는 self 외에 1개의 parameter를 받습니다.</p>
<p>field 입니다.</p>
<p>field 는 지우고자 하는 데이터의 필드명 입니다.</p>
<p>#객체 이름이 db 라는 가정하에
db.delete(&quot;name&quot;)
만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.</p>
<p>그리고 특별한 return 값은 없습니다.</p>
<pre><code class="language-python">class Database:
    def __init__(self, name, size):
        self._name = name
        self._size = size
        self._dict = dict()

    def insert(self, field, value):
        if len(self._dict) &lt; self._size:
            self._dict[field] = value
        else:
            pass
    def select(self, field):
        if field in self._dict:
            return self._dict[field]
        else:
            return None
    def update(self, field, value):
        if field in self._dict:
            self._dict[field] = value
        else:
            pass
    def delete(self, field):
        if field in self._dict :
            del self._dict[field]
        else:
            pass</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CODE KATA] ]]></title>
            <link>https://velog.io/@brian_j/CODE-KATA</link>
            <guid>https://velog.io/@brian_j/CODE-KATA</guid>
            <pubDate>Tue, 10 May 2022 10:15:49 GMT</pubDate>
            <description><![CDATA[<ol start="2022">
<li><ol start="5">
<li>10 화요일</li>
</ol>
</li>
</ol>
<p>오늘의 코트카타</p>
<p><img src="https://velog.velcdn.com/images/brian_j/post/6beb1044-db2d-432e-ac99-de88796b84b7/image.png" alt=""></p>
<p>[제출한 풀이]</p>
<pre><code class="language-python">def reverse(number):
    s = str(number)
    v = &quot;-&quot;+s[:0:-1] if (number &lt; 0) else s[::-1]
    return int(v)</code></pre>
<p>[고민해본 방법]</p>
<ol>
<li><p>reverse() / reversed()</p>
</li>
<li><p>str type and slicing</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIS] #1 .gitignore]]></title>
            <link>https://velog.io/@brian_j/TIS-1-.gitignore</link>
            <guid>https://velog.io/@brian_j/TIS-1-.gitignore</guid>
            <pubDate>Mon, 09 May 2022 13:39:45 GMT</pubDate>
            <description><![CDATA[<p>[TIS] 오늘의 삽질</p>
<p>공부한 내용은 아직 머리속에 정리가 되지않아 메모장에 끄적이고, 오늘의 삽질을 기록하기로 했다.</p>
<p>2022.05.09</p>
<p>TIS
.gitignore 없이 push하여 github repo에 my_setting.py처럼 업로드되서는 안되는 설정들이 죄다 push되었다.</p>
<p>일단 github repo에서 my_settings.py를 삭제하고 git local repo에서 .gitignore 파일을 만들고, 다시 push하려하니 오류가 발생했다.</p>
<p>오류 내용은 pull 하라고 하는 것 같아서 일단 해보자라는 마인드로 pull했는데 github repo와 내용이 완전히 틀어졌는지 github repo에 0kb my_settings.py 파일이 다시 생성되었다.</p>
<p>이미 git, github repo 망한 것 같아서, 이것저것해보자라는 생각에 branch를 새로파서 다시 push를 시도했다. 결과는 역시 pull 어쩌구 하는 오류였다.</p>
<p>결국 rm -rf .git 으로 local git을 전부 삭제하고, 다시 새로운 branch를 만들어서 push했다.</p>
<p>오늘의 교훈</p>
<p>push하기전에 .gitignore 만드셨나요 ?
git init보다 .gitignore가 먼저다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django Tutorial - #5 settings.py 설정]]></title>
            <link>https://velog.io/@brian_j/Django-Tutorial-5-settings.py-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@brian_j/Django-Tutorial-5-settings.py-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Wed, 04 May 2022 11:54:01 GMT</pubDate>
            <description><![CDATA[<h1 id="5-settingspy-설정">5. settings.py 설정</h1>
<h3 id="1-ip-허용">1) IP 허용</h3>
<p>ALLOWED_HOSTS = [&#39;*&#39;]</p>
<h3 id="2-admin-csrf-auth---주석-처리">2) admin, csrf, auth -&gt; 주석 처리</h3>
<h3 id="3-configurlspy-수정">3) config/urls.py 수정</h3>
<pre><code class="language-python">from django.urls import path

urlpatterns = [
]</code></pre>
<p>my_settings.py 생성(DATABASES, SECRET_KEY)</p>
<ul>
<li>django 설정 중 SECRET_KEY, DATABASE 등은 별도의 파일이나, 환경변수로서 관리하는게 좋다</li>
<li>settings.py 에 저장되는 방식은 지양해야 한다.</li>
</ul>
<p>zsh에서 cd 명령어를 통해 생성한 project 폴더로 이동하고,
touch 명령어를 이용해서 my_settings.py 파일을 생성해주자.</p>
<pre><code class="language-python">touch my_settings.py
ls
config / manage.py / my_settings.py</code></pre>
<p>ls 명령어를 통해 잘 생성된 것을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[django_Tutorial #4 Django Project 생성]]></title>
            <link>https://velog.io/@brian_j/djangoTutorial-4-Django-Project-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@brian_j/djangoTutorial-4-Django-Project-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Wed, 04 May 2022 11:41:19 GMT</pubDate>
            <description><![CDATA[<h1 id="4-django-project-생성">4. django project 생성</h1>
<blockquote>
<p>django-admin startproject &quot;project_name&quot;</p>
</blockquote>
<p>python manage.py 명령어와
django-admin 명령어가 좀 헷갈리는데 한번에 정리해보자.</p>
<p>*<em>python manage.py
*</em></p>
<ul>
<li>python manage.py <strong>runsever</strong></li>
</ul>
<p>*<em>django-admin
*</em></p>
<ul>
<li>django-admin <strong>startproject</strong> [project_name]</li>
<li>django-admin startapp [app_name]</li>
</ul>
<p>나는 우선 Users/[user_name]/django_tutorial 폴더를 만들고,
zsh에서 cd 명령어를 통해 해당 위치로 이동한 후,</p>
<p>django-admin startproject config .</p>
<p>명령어를 통해 해당 위치에 config 라는 project를 생성하였다.</p>
<p>생성하고 나면, 여러가지 파일이 생성된다.</p>
<p>zsh에서 tree 명령어를 이용해 확인해보면, </p>
<p><img src="https://velog.velcdn.com/images/brian_j/post/462832ee-94cb-4d3b-8203-3a408efca114/image.png" alt=""></p>
<p>첨부와 같이 생성된 것을 확인할 수 있다.</p>
<p><code>__init__.py</code> : 패키지임을 알려주는 파일
<code>asgi.py</code> 아직 모름
<code>settings.py</code> project의 각종 setting을 설정
<code>urls.py</code> url을 잡아줌
<code>wsgi.py</code> 아직모름</p>
<p><code>manage.py</code> : python manage.py runserver 등</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[django_tutorial #3 패키지 설치]]></title>
            <link>https://velog.io/@brian_j/djangotutorial-3-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@brian_j/djangotutorial-3-%ED%8C%A8%ED%82%A4%EC%A7%80-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Wed, 04 May 2022 11:22:22 GMT</pubDate>
            <description><![CDATA[<h1 id="3-패키지-설치">3. 패키지 설치</h1>
<h3 id="1-패키지-목록-확인">1) 패키지 목록 확인</h3>
<blockquote>
<p>pip freeze</p>
</blockquote>
<h3 id="2-패키지-설치">2) 패키지 설치</h3>
<blockquote>
<p>pip install 패키지 이름</p>
</blockquote>
<h4 id="1-django-설치--pip-install--django">(1) django 설치 : pip install  django</h4>
<h4 id="2-mysql-설치--pip-install-mysql">(2) mysql 설치 : pip install mysql</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django Tutorial - #2 database 생성]]></title>
            <link>https://velog.io/@brian_j/django-Tutorial-2-database-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@brian_j/django-Tutorial-2-database-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Wed, 04 May 2022 11:00:17 GMT</pubDate>
            <description><![CDATA[<h1 id="2-database-생성">2. Database 생성</h1>
<h3 id="1-mysql-설치">1) mysql 설치</h3>
<pre><code class="language-python">&gt;&gt;&gt; brew install mysql</code></pre>
<h3 id="2-database-생성-1">2) database 생성</h3>
<blockquote>
<p>데이터베이스 생성 : mysql -u root -p
mysql &gt; create database <em>name</em> character set utf8mb4 collate utf8mb4_general_ci;</p>
</blockquote>
<pre><code class="language-python">&gt;&gt;&gt;&gt; mysql --version # mysql version check               
mysql  Ver 8.0.29 for macos12.2 on arm64 (Homebrew)

&gt;&gt;&gt;&gt; mysql -u root -p # create Database                                  
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is ###
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type &#39;help;&#39; or &#39;\h&#39; for help. Type &#39;\c&#39; to clear the current input statement.

mysql&gt; create database db_django_tuto character set utf8mb4 collate utf8mb4_general_ci;
Query OK, 1 row affected (0.01 sec)</code></pre>
<p>Query OK ! 라고 뜬 걸 보니 성공한 것 같다.</p>
<p>_(에러발생시) mysql.server start 확인!
_</p>
<h3 id="3-database-확인">3) database 확인</h3>
<blockquote>
<p>mysql&gt; show databases;</p>
</blockquote>
<pre><code class="language-python">&gt;&gt;&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| db_django_tuto     |</code></pre>
<p>조금 전에 만든 db_django_tuto 가 들어있는 걸 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django Tutorial - #1 가상환경 설정]]></title>
            <link>https://velog.io/@brian_j/Django-Tutorial-1</link>
            <guid>https://velog.io/@brian_j/Django-Tutorial-1</guid>
            <pubDate>Wed, 04 May 2022 10:13:53 GMT</pubDate>
            <description><![CDATA[<p><del>이것은 ... django tutorial story ...</del></p>
<blockquote>
<p><strong>Tutorial 진행 환경</strong>
OS: Mac(M1)
venv : miniconda 가상환경
python version : 3.9.12
django version :
IDE : vscode</p>
</blockquote>
<p>Tutorial link = <a href="https://docs.djangoproject.com/ko/3.1/intro/tutorial01/">https://docs.djangoproject.com/ko/3.1/intro/tutorial01/</a>
&quot;첫번째 장고 앱 작성하기&quot;</p>
<p>이 튜토리얼을 통해, 간단한 설문조사(Polls) 어플리케이션을 만드는 과정을 따라해 보겠습니다.</p>
<ol>
<li>가상환경 생성</li>
<li>django 설치 및 프로젝트 생성</li>
<li>git으로 project 관리하기</li>
</ol>
<p>순으로 진행해보겠습니다.</p>
<h1 id="1-가상환경-생성">1. 가상환경 생성</h1>
<h3 id="1-miniconda-설치">1) miniconda 설치</h3>
<blockquote>
<p>zsh에서 miniconda 설치 확인 : conda --version</p>
</blockquote>
<pre><code class="language-python">conda --version
conda 4.12.0</code></pre>
<h3 id="2-가상환경-생성">2) 가상환경 생성</h3>
<blockquote>
<p>conda create -n &quot;가상환경 이름&quot; python=3.9 (최신버전 3.9로 진행)</p>
</blockquote>
<pre><code class="language-python">conda create -n django_tuto python=3.9</code></pre>
<p>proceed[y/n] 어쩌구 나오면 y
(새로운 패키지 설치된다는 내용임)</p>
<pre><code>The following NEW packages will be INSTALLED:

  ca-certificates    pkgs/main/osx-arm64::ca-certificates-2022.4.26-hca03da5_0
  certifi            pkgs/main/osx-arm64::certifi-2021.10.8-py39hca03da5_2
  libcxx             pkgs/main/osx-arm64::libcxx-12.0.0-hf6beb65_1
  libffi             pkgs/main/osx-arm64::libffi-3.4.2-hc377ac9_2
  ncurses            pkgs/main/osx-arm64::ncurses-6.3-h1a28f6b_2
  openssl            pkgs/main/osx-arm64::openssl-1.1.1n-h1a28f6b_0
  pip                pkgs/main/osx-arm64::pip-21.2.4-py39hca03da5_0
  python             pkgs/main/osx-arm64::python-3.9.12-hbdb9e5c_0
  readline           pkgs/main/osx-arm64::readline-8.1.2-h1a28f6b_1
  setuptools         pkgs/main/osx-arm64::setuptools-61.2.0-py39hca03da5_0
  sqlite             pkgs/main/osx-arm64::sqlite-3.38.2-h1058600_0
  tk                 pkgs/main/osx-arm64::tk-8.6.11-hb8d0fd4_0
  tzdata             pkgs/main/noarch::tzdata-2022a-hda174b7_0
  wheel              pkgs/main/noarch::wheel-0.37.1-pyhd3eb1b0_0
  xz                 pkgs/main/osx-arm64::xz-5.2.5-h1a28f6b_1
  zlib               pkgs/main/osx-arm64::zlib-1.2.12-h5a0b063_2


Proceed ([y]/n)? y

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
#     $ conda activate django_tuto
#
# To deactivate an active environment, use
#
#     $ conda deactivate</code></pre><p>처럼 나오면 가상환경 생성 성공</p>
<h3 id="3-가상환경-생성-확인">3) 가상환경 생성 확인</h3>
<blockquote>
<p>conda env list</p>
</blockquote>
<pre><code class="language-python">conda env list
# conda environments:
#
base                  *  /Users/[user_name]/miniconda3
django_tuto              /Users/[user_name]/miniconda3/envs/django_tuto</code></pre>
<p>django_tuto 환경이 생성된 것을 확인할 수 있다.</p>
<h3 id="4-가상환경-진입">4) 가상환경 진입</h3>
<blockquote>
<p>conda activate &quot;가상환경 이름&quot;</p>
</blockquote>
<pre><code class="language-python">conda activate django_tuto</code></pre>
<p>각자의 zsh 커스터마이징에 따라 표기가 다르지만, 가상환경에 진입하였다는 사실을 확인할 수 있다.
(만약 변화가 없는 경우 powerlevel 문제 일 수 있으니, 설정 확인해 볼 것)</p>
<blockquote>
<p>만약 가상환경 진입은 되나, 표기상의 문제가 있는 경우, 
(나의 경우 powerlevel9k에서 설정상 문제로 가상환경 표기가 제대로 되지 않아, powerlevel10k로 overwriting 하여 문제 해결)
비슷한 증상이 있을 경우,
#powerlevel10k 설치
$ git clone --depth=1 <a href="https://github.com/romkatv/powerlevel10k.git">https://github.com/romkatv/powerlevel10k.git</a> ~/powerlevel10k
#설정
$ echo &#39;source ~/powerlevel10k/powerlevel10k.zsh-theme&#39; &gt;&gt;! ~/.zshrc</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[정규화]]></title>
            <link>https://velog.io/@brian_j/%EC%A0%95%EA%B7%9C%ED%99%94</link>
            <guid>https://velog.io/@brian_j/%EC%A0%95%EA%B7%9C%ED%99%94</guid>
            <pubDate>Tue, 03 May 2022 08:29:23 GMT</pubDate>
            <description><![CDATA[<p>*<em>데이터베이스 정규화(nomalization)
*</em>- 관계형 데이터베이스에서 중복을 최소화하도록 데이터를 구조화하는 과정을 &#39;정규화&#39;라고 한다.</p>
<p>*<em>1정규화 : &quot;중복되는 항목이 없어야 한다&quot;
*</em></p>
<ul>
<li>각 테이블에서 중복을 제거한다.</li>
<li>각각 관계된 데이터 모임을 위하여 분리된 테이블을 만든다</li>
<li>각각 관계된 데이터 모임을 기본키로 식별한다.</li>
</ul>
<p><strong>2정규화 : 후보키 K와 K에 속하지 않는 속성 A가 있을 때, A를 결정하기 위해 K의 일부가 아닌 K 전체를 참조해야만 하는 경우 1NF 테이블은 2NF이다.</strong>
<del>(뭔말이야 ??)</del></p>
<p>*<em>3정규화
*</em>- 테이블이 제2 정규형을 만족하고,</p>
<ul>
<li>테이블 내의 모든 속성이 기본 키에만 의존하며, 다른 후보 키에 의존하지 않는다.</li>
</ul>
<p>갱신이상</p>
<blockquote>
<p>참고
<a href="https://ko.wikipedia.org/wiki/%EC%A0%9C1%EC%A0%95%EA%B7%9C%ED%98%95">https://ko.wikipedia.org/wiki/%EC%A0%9C1%EC%A0%95%EA%B7%9C%ED%98%95</a>
<a href="https://ko.wikipedia.org/wiki/%EC%A0%9C2%EC%A0%95%EA%B7%9C%ED%98%95">https://ko.wikipedia.org/wiki/%EC%A0%9C2%EC%A0%95%EA%B7%9C%ED%98%95</a></p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>