# data[].attributes.body
주피터 노트북 버전이 새롭게 바뀌어, 새 노트북을 생성하는 메뉴가 변경되었습니다.

화면에 나오는 것 처럼, [notebook]을 선택하시면 됩니다.

# data[].attributes.headline
미니콘다 다운로드 화면 개편

# data[].attributes.subject
미니콘다 다운로드 화면 개편

# data[].attributes.body
미니콘다 싸이트 개편으로 다운로드 화면이 변경되었습니다.

윈도우즈를 사용하시는 고객은 위에 표시된 항목을 선택하시면 됩니다. 미니콘다 버전은 실습과 상관이 없습니다. 미니콘다에서 가상환경을 만들 때, 필요한 파이썬 버전을 설치하시면 됩니다.

실습 내용에서는 파이썬 "3.8"을 사용하였으나 지금은 "3.9" 이상을 사용하시는 걸 권장합니다.

# data[].attributes.body
수업 중 궁금한 사항이나, 오류 관련 질문을 생성해 주시면 답변 드리겠습니다. 패들렛 화면 오른쪽 하단의 "+" 아이콘을 눌러서 작성해 주세요.

# data[].attributes.body
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>글목록</title>
<style>
.rm_underline {
text-decoration: none;
}
.new_bulletin {
text-align: center;
font-size: 30px;
display: block;
}
</style>
</head>
<body>
<table align="center" border="1" style="width:80%">
<thead>
<tr align="center" bgcolor="yellow">
<th>글번호</th>
<th>작성자</th>
<th>제목</th>
<th>작성일</th>
</tr>
</thead>
{% if bulletin_list %}
<tbody>
{% for bulletin in bulletin_list %}
<tr align="center">
<td style="width:30px">{{bulletin.id}}</td>
<td style="width:50px">{{bulletin.name}}</td>
<td align='left' style="width:200px">
<span style="padding-right: 30px"></span>
<a class='rm_underline' href="{% url 'bulletin_board:view' bulletin.id %}">{{bulletin.title}}</a>
</td>
<td width="10%">{{bulletin.writeDate}}</td>
</tr>
{% endfor %}
</tbody>
{% else %}
<tbody>
<tr>
<td colspan="4">
<p align="center">
<b><span style="font-size: 15pt;">등록된 글이 없습니다.</span></b>
</p>
</td>
</tr>
</tbody>
{% endif %}
</table>
<a class="rm_underline" href="{% url 'bulletin_board:new_bulletin' %}">
<span class="new_bulletin">글쓰기</span>
</a>
</body>
</html>

# data[].attributes.body
from django.shortcuts import render, get_object_or_404
from .models import Bulletin
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.utils import timezone

def index(request):
bulletin_list = Bulletin.objects.all().order_by('-writeDate')
context = {'bulletin_list' : bulletin_list}
return render(request, 'bulletin/index.html', context)

def create_bulletin(request):
return render(request, 'bulletin/create_bulletin.html')

def add_bulletin(request):
bulletin = Bulletin()
bulletin.title = request.POST['title']
bulletin.content = request.POST['content']
bulletin.name = request.POST['name']
bulletin.passwd = request.POST['pincode']
bulletin.save()

return HttpResponseRedirect(reverse('bulletin_board:index'))

def view_bulletin(request, bulletin_id):
bulletin = get_object_or_404(Bulletin, pk=bulletin_id)
return render(request, 'bulletin/detail.html', {'bulletin': bulletin})

def update_bulletin(request, bulletin_id):
bulletin = Bulletin.objects.get(id=bulletin_id)

if request.method == 'POST':
bulletin.title = request.POST['title']
bulletin.content = request.POST['content']
bulletin.writeDate = timezone.datetime.now()
bulletin.save()
return HttpResponseRedirect(reverse('bulletin_board:view', args=(bulletin_id,)))
else:
return render(request, 'bulletin_board/detail.html', {'bulletin': bulletin})

def delete_bulletin(request, bulletin_id):
bulletin = Bulletin.objects.get(id=bulletin_id)
bulletin.delete()
return HttpResponseRedirect(reverse('bulletin_board:index'))

# data[].attributes.body
from django.urls import path
from . import views

app_name = 'noticeboard'
urlpatterns = [
path('', views.index, name='index'),
path('write/', views.create_bulletin, name='new_bulletin'),
path('add/', views.add_bulletin, name='insert_bulletin'),
path('<int:bulletin_id>/', views.view_bulletin, name='view'),
path('update/<int:bulletin_id>/', views.update_bulletin, name='update'),
path('delete/<int:bulletin_id>/', views.delete_bulletin, name='delete'),
]

# data[].attributes.body
Java와 C#같은 언어가 컴파일러 언어인지 아니면 인터프리터 언어인지 혼란스러운 경험을 해보신 분이 있을 겁니다. 잠시 한 번 살펴보도록 하겠습니다.

Java는 source code(~.java) 작성 후 compiler를 이용하여 컴파일하면 byte code(~.class)가 생성됩니다. 이렇게 생성된 byte code는 JVM(Java Virtual Machine)이 byte code를 라인단위로 읽어들이면서 실행하게 됩니다.

C#은 source code(~.cs) 작성 후 compiler를 이용하여 컴파일하면 .NET assembly(~.exe 또는 ~.dll)이 생성됩니다. 이렇게 생성된 .NET assembly를 CIL(Common Intermediate Language)라 합니다. 생성된 exe 파일을 실행하면 .NET framework의 가상머신인 CLR(Common Language Runtime)에 의해 실행됩니다.

여기서 컴파일러 언어와 인터프리터 언어의 주요 특징을 살펴볼 필요가 있습니다.
컴파일러 언어는 인간이 해석할 수 있는 단어로 이루어진 source code를 기계가 바로 실행할 수 있는 기계어로 번역합니다.  일단, 번역이 이루어진 이후에는 실행 시 추가 번역이 필요 없이 빠른 속도로 실행이 가능합니다. 그렇게 하기 위해서 컴파일 시점에 모든 변수의 타입을 결정하고 메모리를 확보하는 과정이 들어갑니다. 이를 데이터의 compile-time binding이라 합니다.

반면에 인터프리터 언어는 사용자가 source code를 입력하자 마자 바로 인터프리터가 해석하여 실행합니다. 이렇게 기계와 인간이 interactive하게 대화하는 형식으로 사용합니다. 이러다 보니, 동일한 코드를 다시 실행하려고 하면 다시 인터프리터가 해석을 해야 하고, 이는 컴파일러 언어에 비해 처리 속도가 매우 느린 원인이 됩니다. 그리고 데이터의 binding은 실행 시 이루어집니다. 즉, 데이터의 runtime binding이 일어납니다.

이쯤에서 여기서 우리가 주목할 부분은 다음과 같습니다.
첫째, JVM, CLR이 해석하는 코드가 과연 source code인가?
JVM이 사용하는 byte code와 CLR이 사용하는 .NET assembly는 기계어와 1:1 매칭이 되는 가상의 기계어 형태입니다. 그렇기 때문에 속도면에서 많은 손해를 보지 않고 빠른 속도를 낼 수 있습니다. 애초에 JVM의 목적이 다중 플랫폼에서 동일한 코드를 실행하기 위해 탄생한 거고, CLR역시 .NET 플랫폼만 있으면 실행 가능하게 하며 다른 언어의 .NET assembly와의 상호 연동을 위해 탄생했기 때문이죠

둘째, JVM과 CLR이 사용자와 기계간의 interactive한 대화를 가능하게 하는가?
사전에 컴파일해야 하기 때문에 그럴 수 없습니다.

셋째, Java와 C#의 데이터는 언제 binding 되는가?
둘 다 compile-time binding 입니다.

결론적으로, 엄밀히 말하자면 변형된 컴파일러 언어 또는 일종의 하이브리드 언어라는 새로운 카테고리로 분류할 수 도 있지만, 컴파일러 또는 인터프리터 언어의 두 가지 관점에서 분류하자면 컴파일러 언어라고 보는 것이 더 타당합니다.

# data[].attributes.body
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('bulletin/', include('bulletin_board.urls')),
]

# data[].attributes.body
from django.contrib import admin
from bulletin_board.models import Bulletin

admin.site.register(Bulletin)

# data[].attributes.body
from django.db import models
from django.utils.timezone import now

class Bulletin(models.Model):
title = models.CharField(max_length=100)
content = models.CharField(max_length=2000)
writeDate = models.DateTimeField(default=now, editable=False)
name = models.CharField(max_length=50)
passwd = models.CharField(max_length=50)

def __str__(self):
return self.title

# data[].attributes.body
변경 또는 추가된 소스

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'web_db',
'USER': 'django',
'PASSWORD': '1234',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
import pymysql

pymysql.version_info=(1, 4, 2, "final", 0)
pymysql.install_as_MySQLdb()

TIME_ZONE = 'Asia/Seoul'
USE_TZ = False