Transposing Sparse Matrix 

1. 희소행렬(Sparse Matrix)이란?

희소행렬은 행렬안의 값들 중에서 0이외의 값이 희소한 행렬을 의미합니다.

따라서 대부분 0이라면 모든 값들을 표현하지 않고 0이아닌 값과 그 위치만 알고 나머지는 0이다 라고 표현을 할 수 있습니다.

그러므로
 
평소에 그리던 행렬을
이런 방식으로 표현할 수 있습니다.(변환 방식은 생략)

2. 희소행렬의 대칭이동

위에서 봤던 간단하게 표현된 행렬을 통해서 대칭이동을 하겠습니다.
단순한 대칭이동은 그저 row와 col값을 교환해주면 간단합니다. 그러나 정렬을 유지 하고싶다면 어떻게 해야할까요?

단순 교환은 정렬이 유지되지 않습니다. 따라서 새로운 방법을 궁리해야합니다.

3. 대칭이동과 정렬


우선 기존행렬을 A, 바뀐 새로운 행렬을 B라고 합시다.
대칭이동을 하면서 정렬을 하기위해선 단순히 바꾸기보다는 적절한 위치에 A의 원소를 넣고 row,col을 바꿔주기
자 그럼 할일은 두가지 입니다.

1. row, col 바꿔주기

: 못하면 안됩니다;;

2. 적절한 위치에 넣어주기

네 이부분이 관건이 됩니다.

적절한 위치에 어떻게 넣지? 라고 생각하면 우리가 선택한 원소가 갈 장소가 적힌 배열(row_start[])을 만들어서 해결해봅시다.

그럼 자연스럽게 이 배열은 어떻게 만들지? 라고 생각 할 수 있습니다.

코딩이 아니라 머리로 넣을 장소를 생각해봅시다. 머리로 생각 할 줄 알아야 코드를 짤 수 있으니까요

같은 색은 A에서 같은 col을 의미합니다. 위 방식대로 우리는 쭈욱~ 채워나갈수 있습니다.
그리고 이걸 보면 A에서 같은 각col 종류의 갯수들을 알면 row_start[]을 알 수 있겠네? 라는 생각을 할 수 있습니다.

구체적으로는
row_start[i]의 값은 row_start[i-1]에서 그 i-1에 해당하는 A의 col갯수를 더하면 알 수 있습니다.
그리고row_start[0]은 0번째 즉 첫번째니까 바로 1을 넣을 수 있습니다.

예를 들어 우리가 A의 열 1이 들어갈 row_start[1]을 구하고 싶다면
row_start[0]에서 A의 열중 0의 갯수를 구하고 더하면 됩니다.

그 다음부터는 위의 규칙을 적용하면 차례로 row_start[i]를 구할수 있겠죠?

자 그렇다면 다음으로 구해야할 것들은 해당하는 A의 col갯수들이담긴 배열(col_count)입니다.
이건 A에 있는 col들을 i=1 ~ 8 까지 전체를 세어서 col_count[A[i].col]++을 하면 되겠죠?

이제 구상이 끝났으니 코드를 조져봅시다.

4. 코드

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
#include <stdio.h>
#include <stdlib.h>
#define size 9
#define MAX_COL 6
#define MAX_ROW 6
/*
term: 행렬의 행,열 그리고 해당 값을 저장
*/
typedef struct term {
    int row;
    int col;
    int value;
}term;
term *transposing(term A[]);
int main(void) {
    term A[9= { { 6,6,8 },{ 0,0,15 },{ 0,3,22 },{ 0,5,-15 },{ 1,1,11 },{ 1,2,3 },{ 2,3,-6 },{ 4,0,91 },{ 5,2,28 } };
    term *= transposing(A);
    system("pause");
}
term *transposing(term A[]) {
    //setting 
//처음 부분이니 여러가지를 선언해서 세팅을 해줍시다.
// 위의 col_Count는 여기서 rowTerms로 표현했습니다.
    int rowTerms[MAX_COL] = { 0 }, startPoint[MAX_COL] = { 0 };
    term B[size];
    B[0].col = A[0].row; B[0].row = A[0].col; B[0].value = A[0].value;
    //get rowTerm
    for (int i = 1; i < size; i++) {
        rowTerms[A[i].col]++;
    }
    //get startpoint
    startPoint[0= 1;
    for (int i = 1; i <MAX_COL; i++) {
        startPoint[i] = startPoint[i - 1+ rowTerms[i - 1];
    }
    //transport to B
    for (int i = 1; i < size; i++) {
        int j = startPoint[A[i].col]++;
        B[j].row = A[i].col;
        B[j].col = A[i].row;
        B[j].value = A[i].value;
    }
    return B;
}a
cs

Toast & Snackbar

토스트메세지

 정의

일반적으로 어떤 알림을 주기위해서 화면의 하단에 잠깐 보였다가 사라지는게 토스트메세지입니다.


여기서는 토스트메세지의 기본보다는 좀더 심화방법에 대해서 다루어 보겠습니다.

 

1.토스트 메세지의 위치설정 

예시 코드를 통해서 설명하도록 하겠습니다.

1
2
3
4
5
6
Toast toast=Toast.makeText(getApplicationContext(),"위치가 바뀐 토스트",Toast.LENGTH_LONG);
//기본적인 토스트 메세지를 만들어줍니다.
toast.setGravity(Gravity.TOP|Gravity.LEFT,200,200);
//setGravity( 처음 기준점, x축 offset, y축 offset)을 사용하여 위치조정
toast.show();
//
cs

 

2. 토스트 메세지의 모양설정


토스트 메세지의 모양은 기본적으로 toast.setView(View)를 통해서 설정할 수 있습니다.
여기선 shapeDrawable을 통해서 TextView의 모양을 만들고 이 TextView를 포함한 레이앙를 토스트에 설정해서 토스트메세지로 TextView가 출력되도록 하겠습니다.

우선 textView를 넣어둘 toastborder.xml파일입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/toast_layout_root">
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:textSize="40dp"
        android:background="@drawable/toast"/>
<!--이 배경은 커스터마이징한겁니다-->
 
</LinearLayout>
cs


우리는 이안에 있는 TextView를 토스트로 출력해볼겁니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LayoutInflater inflater=getLayoutInflater();
    //여기선 R.layout에 toastborder.xml파일을 만들고 그 안에 TextView를 만들어 줍니다
 
    View layout=inflater.inflate(R.layout.toastborder,(ViewGroup)findViewById(R.id.toast_layout_root));
    //layoutInflater : xml로 정의된 resource들을 view의 형태로 반환해줌
    TextView textView=(TextView)layout.findViewById(R.id.text);
    //반환된 레이아웃에서 해당 텍스트를 가져옵니다.
    textView.setText("모양을 바꾼 토스트입니다");
    //텍스트의 글자를 설정합니다.
    Toast toast=new Toast(getApplicationContext());
    //토스트를 출력할 context를 설정합니다.
    toast.setGravity(Gravity.CENTER,0,-100);
    toast.setDuration(Toast.LENGTH_LONG);
    //토스트의 여러 특성을 설정합니다.
    toast.setView(layout);
    //토스트의 뷰를 우리가 뽑았던 레이아웃으로 설정합니다.
    toast.show();
cs

 

스낵바

정의

스낵바 또한 알림을 위해 사용되는 메세지 출력입니다. 그러나 그 기본형태는 토스트와 다르게 아래에서 올라오듯이 출력되며, 출력 유지, 시간 등 토스트보다 세부사항이 설정가능합니다.

주의: 스낵바를 사용하기위해선 Project struture , Dependency에서 design라이브러리를 등록해야합니다.
 

 

예제: 버튼을 클릭하면 스낵바가 출력되도록하는 코드입니다.
1
2
3
4
5
6
7
Button button2=(Button)findViewById(R.id.button4);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"스낵바입니다",Snackbar.LENGTH_LONG).show();
//만드는형식은 토스트와 아주 유사합니다. 그러나 첫번째 인자로 해당 뷰를 출력해야합니다.
// 그럼 해당 뷰의 parent뷰를 그 뷰를 출력대상으로 설정합니다.
            }
        });
cs

 

아래는 모두 합한예제 파일입니다.

MainActivity.java

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
package com.jasonlee.ed_with_android_studio;
 
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button=(Button)findViewById(R.id.button2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast toast=Toast.makeText(getApplicationContext(),"위치가 바뀐 토스트",Toast.LENGTH_LONG);
                toast.setGravity(Gravity.TOP|Gravity.LEFT,200,200);
                toast.show();
            }
        });
        Button button1=(Button)findViewById(R.id.button3);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                LayoutInflater inflater=getLayoutInflater();
                //layoutInflater : xml로 정의된 resource들을 view의 형태로 반환해줌
                View layout=inflater.inflate(R.layout.toastborder,(ViewGroup)findViewById(R.id.toast_layout_root));
                TextView textView=(TextView)layout.findViewById(R.id.text);
                textView.setText("모양을 바꾼 토스트입니다");
                Toast toast=new Toast(getApplicationContext());
                toast.setGravity(Gravity.CENTER,0,-100);
                toast.setDuration(Toast.LENGTH_LONG);
                toast.setView(layout);
                toast.show();
 
            }
        });
        Button button2=(Button)findViewById(R.id.button4);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"스낵바입니다",Snackbar.LENGTH_LONG).show();
            }
        });
    }
}
 
cs


toast.xml (이건 drawable에 저장합니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <stroke
        android:width="4dp"
        android:color="#ffffff00"/>
    <solid
        android:color="#ff883300"/>
    <padding
        android:left="20dp"
        android:right="20dp"
        android:top="20dp"
        android:bottom="20dp"
        />
    <corners
        android:radius="15dp"/>
</shape>
cs


table_layout.xml (TextView가 저장된 레이아웃)

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
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:stretchColumns="0,1,2">
    android:stretchColumns: make assigned colum full
    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
 
        <TextView
            android:text="Name : "
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            />
        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_span="2"
            />
 
 
    </TableRow>
    <TableRow
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="NO"
            android:layout_column="1"
            />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="NO"
            android:layout_column="2"
            />
 
    </TableRow>
</TableLayout>
cs


Activity_main.xml

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
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="토스트 띄우기"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="8dp" />
 
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="토스트 모양바꾸기"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="324dp"
        />
 
    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="99dp"
        android:text="스낵바띄우기"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
 
cs

 

Alert 대화 알림상자

설명: 대화알림상자는 흔히 봐왔던 작은 경고창(예, 아니오)를 의미합니다.


이번에는 대화알림상자에서

1. 만드는법
2. 제목, 아이콘 그리고 메세지 내용의 설정
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
//이 함수는 MainActiyity.java 클래스에 포함된 함수입니다.
//어디에 쓰이는지 알고싶다면 아래의 예시 코드를 참조하시기바랍니다.
public void showMessage(){
        final AlertDialog.Builder builder=new AlertDialog.Builder(this);
        //우선 AlertDialog.Builder를 통해서 알림상자를 만드는 객채를 설정합니다
        builder.setTitle("안내");
        //제목을 설정합니다.
        builder.setMessage("종료하시겠습니까");
        //내용을 설정합니다.
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        //제목에 추가할 아이콘을 추가합니다. 여기서는 기본적으로 제공되는 아이콘을 사용했습니다.
        //이제 부정 버튼을 설정해봅시다.
        builder.setNegativeButton("아니오"new DialogInterface.OnClickListener() {
            //함수의 첫인자는 버튼의 메세지, 두번째는 리스너입니다.
            //여기서 리스너는 DialogInterface 클래스의 것을 사용합니다.
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Snackbar.make(textView,"아니오 버튼이 눌렸습니다.",Snackbar.LENGTH_LONG).show();
                //아니오 버튼이 눌리면 스낵바를 출력합니다.
            }
        });
        //마찬가지로 긍정 버튼을 설정합니다.
        builder.setPositiveButton("예"new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Snackbar.make(button,"예 버튼이 눌렸습니다.",Snackbar.LENGTH_LONG).show();
            }
        });
        //빌더에서 알림dialog를 새로 생성해줍니다. 빌더는 빌더일뿐 결과 객체가 아닙니다.
        AlertDialog dialog=builder.create();
        //보여주도록합니다.
        dialog.show();
    }
cs

아래는 이를 활용한 예시입니다.

Main_Activity.java

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
package com.jasonlee.ed_with_android_studio;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
    TextView textView;
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button)findViewById(R.id.button);
        textView=(TextView)findViewById(R.id.textView2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showMessage();
            }
        });
    }
    public void showMessage(){
        final AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle("안내");
        builder.setMessage("종료하시겠습니까");
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setNegativeButton("아니오"new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Snackbar.make(textView,"아니오 버튼이 눌렸습니다.",Snackbar.LENGTH_LONG).show();
            }
        });
        builder.setPositiveButton("예"new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Snackbar.make(button,"예 버튼이 눌렸습니다.",Snackbar.LENGTH_LONG).show();
            }
        });
        AlertDialog dialog=builder.create();
        dialog.show();
    }
}
cs

activity_main.xml

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
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="알림대화상자 띄우기"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="116dp"
        android:text="알림대화상자"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
cs

웹 페이지 화면에서 클릭이나 드래그 등의 동작에 반응을 주고 싶을 때 사용하는것이 이벤트 리스너이다. 여기에서는 간단하게 클릭한 정보를 콘솔에 출력하는 실습을 할 것이다.

이벤트:

   이벤트는 브라우저가 받는 활동들을 의미한다.
   Example : 보통 화면이나 요소를 클릭, 드래그, 휠 조정등 다양한 입력들을 이벤트라고한다.

 이벤트 리스너(핸들러):

   특정한 이벤트가 일어났을때 해당 이벤트에 대한 반응을 의미한다.
   Example : 검색버튼을 클릭, 로그인버튼을 클릭 등등 다양하다.

학습을 위해서는 아래의 코드를 통해 브라우저로 실행한뒤 직접클릭해보면서 코드를 이해하는게 좋다

JS 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var el = document.querySelector(".outside1");
//querySelector를 통해서 리스너를 추가할 뷰를 선택한다.
// addEventListener의 함수의 인자와 동작에 대해서는 정식링크를 참조하는 것이 좋다.
//https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener#%EA%B5%AC%EB%AC%B8
el.addEventListener("click"function(e){
  //function에 들어오는 인자는 클릭했을때는 호출한 이벤트의 정보가 있다.
  //do something..
  var target=e.target;
  //target은 어떤것이 클릭되었는지를 전달, 가장많이쓰임
  console.log("hellow",target.className,target.nodeName,target.innerText);
}, false);
// See :https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_handler_properties
cs
HTML파일
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    <div class="outside1">outside element</div><br>
  </body>
  <script src="event_listener.js"></script>
</html>
cs

Ajax 통신 정의


Ajax 통신은 비동기적인 웹 어플리케이션의 제작을 위한 웹 개발 기법이다.

*여기서 비동기적인이란 서버에 웹페이지를 요청할 때 정식루트로 데이터가 오가든 말든 서버에 요청을 따로 요구할 수 있다는 것이다.

쉽게 얘기하면 한 페이지에서 어느 부분에 대한 변화를 요청한다면( 예시: 네이버 메인에서 웹툰, 푸드 카테고리 변화) 그 부분에 대해서만 통신하여 결과를 변화로 반영하는 형식이다.

Ajax 통신의 필요성

단적으로 말해서 Ajax 통신이 없다면 페이지의 한 부분만 변화시키고 싶어도 항상 서버와 클라이언트사이에는 전체 페이지의 데이터를 주고받아야한다. 이는 중복되는 데이터를 계속주고 받음으로써 대역폭낭비를 야기하고 대역폭 낭비는 곧 금전적 손실과 속도 하향 등 많은 문제를 야기한다.

따라서 Ajax 통신을 사용하여 필요한 부분만 데이터를 주고 받게 함으로써 중복성을 피할 수 있다.

Ajax 통신의 예제



위 사진에서 카테고리를 선택하면 아래의 화면이 부분적으로 빠르게 변화하는 것을 볼 수 있을 것이다. 여기서 Ajax 통신을 사용하고있다. 단순한 카테고리 변화이기 때문에 각 카테고리의 해당 부분만 서버에서 가져오면 되는 것이다.

예시 코드



예시는 많지만 HTTP예제중 하나인  XMLHTTPRequest를 사용해서 작성해보도록 한다.
Ajax의 예시는 다양하게 있으니 검색해서 알아보는게 좋은 것이다.

function ajax(data) {
 var oReq = new XMLHttpRequest();
 oReq.addEventListener("load", function() {
   console.log(this.responseText);
 });    
 oReq.open("GET", "http://www.example.org/getData?data=data");//parameter를 붙여서 보낼수있음. 
 oReq.send();
}

1.open을 하면 해당 URL에 데이터를 요청을 준비한다.
2.send를 통해서 해당 서버에 데이터를 요청합니다.
3.addEventListener에 load이벤트 리스너를 추가하여 데이터가 load되면 해당 함수를 실행합니다.

Ajax통신에는 XML뿐만 아니라 다양한 데이터형식들을 주고받을 수 있습니다.


출처:https://www.edwith.org/boostcourse-web/lecture/16701/




'Web' 카테고리의 다른 글

Servlet - Hellow World 출력하기(intellij)  (0) 2020.01.18
Web - Event & EventListener  (0) 2020.01.18
JSP(Java Server Page) - 정의, 문법  (0) 2020.01.18
Scope (유효변수)에 대하여  (0) 2020.01.18
Page scope  (0) 2020.01.18

JSP란?

JSP(자바 서버페이지)는 코드를 삽입하여 웹 서버에서 동적으로 웹 페이지를 생성하여 웹 브라우저에 돌려주는 언어이다.  - 위키백과

 

위의 정의를 쉽게 설명해보겠습니다. 서버에서 요청에 따라 동적으로 처리하는 건 PHP와 매우 유사합니다. 사실상 자바로 동적 웹을 제어하기 위해서 만들어진것이 JSP입니다. 대부분 서블릿과 JSP를 비교하는데 차이점을 알아두시는게 좋을 것같습니다.

 

서블릿: 자바를 기반으로 하여 웹페이지를 동적으로 제작함 -> 자바문법을 따라야 하며 HTML태그및 코드들을 일일이 다 출력해줘야함 -> 페이지를 디자인하고 작성하는데 불편함
JSP: HTML 표준에 따라서 작성하고 PHP처럼 중간에 삽입이 가능함 -> 디자인에 효율적

 

JSP의 실행 구조

 

JSP는 Tomcat과 같은 내장 서버 프로그램이 빌드하여 실행을 합니다. 이 때 서버는 JSP를 서블릿으로 바꾸고 그 서블릿을 다시 실행하여 웹페이지를 제작합니다.  JSP를 자체를 빌드하기 보다는 변환하여 빌드를 진행합니다.

 

JSP - 문법

 

그럼 본격적으로 JSP의 문법을 코드를 통해서 알아보습니다.

코드와 주석을 보면서 파악하는게 가장 효율적입니다.

 

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
<%--
JSP Description:
jsp는 서블릿의 한계를 극복하기 위한 언어이다.
기존의 html형식에 자바스크립트처럼 끼워넣어 사용하지만 명백히 서버사이드 언어이다. 따라서 JS보다 해킹에 안정적이다.
jsp는 jsp를 바로 실행하는 모듈(서버, 톰캣 등등)이 있는 것이 아니라 서블릿으로 변화하여 실행이 된다.
 --%>
<%-- JSP의 기본문법:
0. 기본적인 지시자: <%@ %>
1. 전역변수 및 함수 선언문: <%! 내용 %>
2. 스크립트릿(프로그래밍 코드를 기술): <% 내용 %>
3. 표현식(화면에 출력할 내용을 기술): <%= 내용 %>
4. JSP의 주석: <%-- 내용 --%>
<%-- 훑어 보시고 직접 예시를 보시는걸 추천해드립니다.  --%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%--
@:지시자이다.
page: 페이지에 대해서 지시한다는 뜻이다.
language: 언어의 타입을 설정 다른 언어도 이론적으로 사용가능하지만 안씀
contentType: 말그대로 내용이다 text/html은 데이터의 형식 charset은 데이터표기 방식이다.
pageEncoding: 코드를 해석하여 페이지를 표현할때의 데이터 표기방식을 정한다. --%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>sum10</title>
  </head>
    <body>
      <%-- 예제 1번: 반복문을 사용해서 합을구하고 표현하기 --%>
      <%-- 스크립트릿을 사용해서 html안에서 바로 자바코딩이 가능합니다. --%>
      <%
      int total = 0;
      // 여기에서 선언되는 변수는 지역변수가 됩니다.
      for(int i = 1; i <= 10; i++){
          total = total + i;
        }
        %>
        1부터 10까지의 합 : <%=total %>
        <%-- <%=total %>의 의미는 .out.println(total)과 같은 의미이다. --%>
        <br>
          <%-- 예제 2번: 함수및 전역변수 선언하기 + 표현하기--%>
          <%!
          public static int id=12321;
          public static int getId(){
          return id;
        }
        %>
        id는 <%=getId()%> , <%=id%>입니다.
      </body>
</html>
cs

'Web' 카테고리의 다른 글

Web - Event & EventListener  (0) 2020.01.18
Ajax 통신 정의, 필요성, 예제  (0) 2020.01.18
Scope (유효변수)에 대하여  (0) 2020.01.18
Page scope  (0) 2020.01.18
Request Scope  (0) 2020.01.18

서문

 

웹 프로그래밍에서 데이터를 다루는 부분은 아주 다양합니다.

예를 들어 페이지 안에서만 하는 경우, 브라우저가 처리하는 경우, 서버가 다루는 경우 등 여러 범위에 퍼져있기 때문에 웹 프로그래밍 전체에서 데이터의 범위를 표현하기위해서 Scope라는 개념을 사용합니다.


Scope란?

변수의 유효범위(접근성)과 생존기간을 뜻합니다.

 

범위의 종류는?

기본적으로  4가지 scope를 사용하여 표현합니다.

page Scope < request Scope < Session Scope < Application Scope

순서대로 점차 넓은 범위를 가지게 됩니다.

 

 

4가지 Scope는?

Application : 웹 어플리케이션이 시작되고 종료될 때까지 변수가 유지되는 경우 사용

Session : 웹 브라우저 별로 변수가 관리되는 경우 사용

Request : http요청을 WAS가 받아서 웹 브라우저에게 응답할 때까지 변수가 유지되는 경우 사용

Page : 페이지 내에서 지역변수처럼 사용

 

 

 

자료 출처: https://www.edwith.org/boostcourse-web/lecture/16708/

'Web' 카테고리의 다른 글

Ajax 통신 정의, 필요성, 예제  (0) 2020.01.18
JSP(Java Server Page) - 정의, 문법  (0) 2020.01.18
Page scope  (0) 2020.01.18
Request Scope  (0) 2020.01.18
Session Scope에 대해  (0) 2020.01.18

Page_scope

:한 페이지가 실행되는 동안만 사용되는 변수 범위

 

특정 서블릿이나 JSP가 실행되는 동안에만 정보를 유지 하고 싶은 경우가 있습니다.

 

이 경우에 사용되는 것이 page scope입니다.

 

이번 시간에는 page scope에 대해서 알아보도록 하겠습니다.

 

*사용방법

setAttribute, getAttribute로 사용

 

지역변수처럼 사용한다.

 

EL이나 JSTL에서 편하게 사용할수 있다.


*자세한 내용

 

  1. PageContext 추상 클래스를 사용한다.
  2. JSP 페이지에서 pageContext라는 내장 객체로 사용 가능 하다.
  3. forward가 될 경우 해당 Page scope에 지정된 변수는 사용할 수 없다.
  4. 사용방법은 Application scope나 Session scope, request scope와 같다.
  5. 마치 지역변수처럼 사용된다는 것이 다른 Scope들과 다릅니다.
  6. jsp에서 pageScope에 값을 저장한 후 해당 값을 EL표기법 등에서 사용할 때 사용됩니다.
  7. 지역 변수처럼 해당 jsp나 서블릿이 실행되는 동안에만 정보를 유지하고자 할 때 사용됩니다.

출처: https://www.edwith.org/boostcourse-web/lecture

'Web' 카테고리의 다른 글

Ajax 통신 정의, 필요성, 예제  (0) 2020.01.18
JSP(Java Server Page) - 정의, 문법  (0) 2020.01.18
Scope (유효변수)에 대하여  (0) 2020.01.18
Request Scope  (0) 2020.01.18
Session Scope에 대해  (0) 2020.01.18

Request Scope

사용이유:

웹 브라우저로부터 WAS가 요청을 받은 후, 포워드 되는 동안 유지하고 싶은 정보가 있을 경우 request scope를 사용합니다.

이번 시간에는 request scope에 대해 알아보도록 하겠습니다.

 

정의: 

request scope는 서블릿 기준으로 클라이언트가 서버에 요청하는 HttpServletRequest객체를 의미합니다.

쉽게 말해서 클라이언트가 서버에 전달하는 변수라고 생각하시면 좋습니다.

 

Request Scope가 Page_scope보다 넓은 범위인 이유:

우선 Request Scope는 페이지에 관한 모든 정보를 가지고 있습니다. 그리고 request는 단순히 요청에만 쓰이는 변수가 아니라

서버 내에서 포워딩( 하나의 페이지 처리 프로세스가 다른 프로세스를 호출 )을 할 때 사용되는 변수입니다.

따라서 Request Scope = Page_scope + 프로세스간 전달 이기에 pageScope보다 큰 영역입니다.

 

Request Scope의 특징

 

  • http 요청을 WAS가 받아서 웹 브라우저에게 응답할 때까지 변수값을 유지하고자 할 경우 사용한다.
  • HttpServletRequest 객체를 사용한다.
  • JSP에서는 request 내장 변수를 사용한다.
  • 서블릿에서는 HttpServletRequest 객체를 사용한다.
  • 값을 저장할 때는 request 객체의 setAttribute()메소드를 사용한다.
  • 값을 읽어 들일 때는 request 객체의 getAttribute()메소드를 사용한다.
  • forward 시 값을 유지하고자 사용한다.
  • 앞에서 forward에 대하여 배울 때 forward 하기 전에 request 객체의 setAttribute() 메소드로 값을 설정한 후, 서블릿이나 jsp에게 결과를 전달하여 값을 출력하도록 하였는데 이렇게 포워드 되는 동안 값이 유지되는 것이 Request scope를 이용했다고 합니다.

출처: https://www.edwith.org/boostcourse-web/lecture/16710/

'Web' 카테고리의 다른 글

Ajax 통신 정의, 필요성, 예제  (0) 2020.01.18
JSP(Java Server Page) - 정의, 문법  (0) 2020.01.18
Scope (유효변수)에 대하여  (0) 2020.01.18
Page scope  (0) 2020.01.18
Session Scope에 대해  (0) 2020.01.18

Session Scope

사용이유:

접속한 웹 브라우저별로 정보를 관리 하고 싶을 때 세션 scope를 사용합니다.

이번 시간엔 이러한 세션 스코프에 대해서 좀 더 자세히 알아보도록 하겠습니다.

 

정의:

session scope 웹브라우저 별로 관리하는 변수범위를 의미합니다.

쉽게 예를 든다면 같은 페이지를 보더라도 다른 아이디로 로그인했다면 브라우저 마다 각각

다른정보가 표현될 수 있습니다.(장바구니, 구매목록 등) 이를 관리해주기 위해서 서로다른 브라우저가 각각접속할때

각 브라우저에 따라서 관리를 하기위한 변수범위가 바로 session scope입니다.

 

Session scope가 Request scope보다 범위가 넓은 이유:

request scope는 url을 요청(페이지에 접속)할 때 서버에 request 변수를 보낸다는 사실을 알 것입니다.

그리고 request변수는 서버가 요청을 다 처리하고 response 값을 클라이언트에게 전송했을때(페이지가 나타날 때)

사라집니다.

 

그러나 session scope의 값은 남아있습니다. 예를 들어 쿠팡에서 로그인하고 장바구니 페이지로 이동했다고 합시다.

그러면 로그인, 장바구니 두 개의 페이지를 두 번 접속하면 request변수를 두 번 사라집니다.

그러나 session scope는 두번 접속 한다고 해도 같은 회원이 접속하기 때문에 로그인 정보를 가지고 있어 사라지지 않습니다.

 

따라서 session scope는 request scope보다 더 긴 유효시간은 가지기에 넓다고 할 수 있습니다.

 

Session scope의 특징:

 

 

  • 웹 브라우저별로 변수를 관리하고자 할 경우 사용한다.
  • 웹 브라우저간의 탭 간에는 세션정보가 공유되기 때문에, 각각의 탭에서는 같은 세션정보를 사용할 수 있다.
  • HttpSession 인터페이스를 구현한 객체를 사용한다.
  • JSP에서는 session 내장 변수를 사용한다.
  • 서블릿에서는 HttpServletRequest의 getSession()메소드를 이용하여 session 객체를 얻는다.
  • 값을 저장할 때는 session 객체의 setAttribute()메소드를 사용한다.
  • 값을 읽어 들일 때는 session 객체의 getAttribute()메소드를 사용한다.
  • 장바구니처럼 사용자별로 유지가 되어야 할 정보가 있을 때 사용한다.

 

 

출처:https://www.edwith.org/boostcourse-web/lecture/16711/

'Web' 카테고리의 다른 글

Ajax 통신 정의, 필요성, 예제  (0) 2020.01.18
JSP(Java Server Page) - 정의, 문법  (0) 2020.01.18
Scope (유효변수)에 대하여  (0) 2020.01.18
Page scope  (0) 2020.01.18
Request Scope  (0) 2020.01.18

신경망의 구조

신경망은 앞서 언급했던 퍼셉트론(여러 개의 입력을 계산하여 하나의 결과값을 출력하는 객체)과 공통점이 많습니다. 이번에는 신경망과 퍼셉트론의 차이점을 주로 설명하여 신경망에 대해서 설명하겠습니다.

퍼셉트론의 구조

 

신경망은 여러개의 퍼셉트론을 연결하여 입력층, 은닉층 그리고 출력층을 제작한 것입니다. 

입력층은 우리가 분석하고자 하는 데이터를 입력할 때 사용되는 층입니다. 그리고 신경망이 데이터를 분석할 때 하나 이상의 은닉층에서는 매 번 가중치를 곱하고 결과값을 다음 은닉층에 전달하는 과정이 일어납니다. 이러한 일련의 과정을 거쳐 출력층에서 우리가 원하는 결과값이 출력되는 것입니다.

우리의 몸으로 비유를 하자면 눈으로 사물을 인식하는 것이 입력층이고 시각신호가 뇌에서 처리되는 것이 은닉층 그리고 은닉층을 통해서 우리는 어떤 사물인지 인지하는 결과가 출력층인 것입니다.

 

신경망의 기본 구조


활성화 함수

활성화 함수란 입력신호의 총합을 어떤 출력신호로 변화시킬지 정하는 함수입니다.

활성화 함수

퍼셉트론에서는 데이터의 총합이 임계값을 넘으면 1 그렇지 않으면 0을 출력하는 단순한 구조였지만 신경망에서는 인공뉴런들이 데이터의 총합을 독특한 방식으로 출력합니다. 

1. 시그모이드 함수

시그모이드 함수

# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


def sigmoid(x):
    return 1 / (1 + np.exp(-x))    

X = np.arange(-5.0, 5.0, 0.1)
Y = sigmoid(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)
plt.show()


# coding: utf-8
import numpy as np
import matplotlib.pylab as plt


def sigmoid(x):
    return 1 / (1 + np.exp(-x))    

X = np.arange(-5.0, 5.0, 0.1)
Y = sigmoid(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)
plt.show()

시그모이드 함수는 사용하는 뉴런은 각각의 데이터와 가중치의 총합을 시그모이드 함수로 계산한 결과값을 다음 층에 전달합니다. 입력값이 0보다 더 큰 경우 1에 가까운 결과값을 출력하고 0보다 작을 수록 0에 가까운 결과값을 출력하는 것이 특징입니다.

초기에는 자주  logistic classification 신경망에 사용되었지만 여러가지 단점들이 부각되고 ReLU함수의 등장으로 최근에는 사용하지 않게 되었습니다.

 

2. 계단함수

계단함수

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
def function(x):
  return np.array(x > 0, dtype=np.int);
x=np.arange(-5,5,0.1);
y=function(x);
plt.plot(x,y);
plt.show();

계단 함수는 0을 기준으로 0보다 크면 1, 0보다 작으면 0을 출력하는 함수 입니다. 

이 함수는 입력값에 비해서 출력값이 0을 기준으로 극단적으로 출력하는 함수 이기 때문에 신호처리 분야에서 자주 사용되는 함수 입니다.

 

3. ReLU 함수

ReLU

# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
def function(x):
  return np.maximum(0,x);
x=np.arange(-5,5,0.1);
y=function(x);
plt.plot(x,y);
plt.show();

ReLU(Recrified Linear Unit, 정류된 선형 함수)는 0이하의 입력값은 모두 0으로 0이상의 출력값은 그대로 출력하는 함수입니다. 시그모이드 함수로 인해 발생하는 문제(vanishing gradient)를 해결하기 위해 사용된 함수로써 현재 가장 많이 사용되는 함수입니다.

 

** 활성화 함수의 특징 : 활성화 함수는 여러가지가 존재 할 수 있지만 반드시 비선형 함수여야 합니다. 선형함수인 경우 여러개의 층을연결하여 계속 계산하는 것은 한 번 계산하는 것과 동일하기에 의미가 없기 때문입니다.**

AdapterViewAdapter와 AdapterView란?

어댑터 뷰는 말 직역하면 적응형 뷰라는 의미가 된다. 앱들을 보면 같은 틀에 다른 내용들이 포함되어 여러개로 나열된 경우를 많이 보았을 것이다. (ex. 카카오톡 친구목록, 페이스북 게시글, Pinterest의 게시글 등) 여기서 사용되는 하나의 틀은 AdapterView로 정의하고 입력할 내용들과 방식은 Adapter로 정의하여 정보들을 원하는 방식으로 나열하여 표현 할 수 있다. 

 

사용방식

기본적으로 ListView나 GridView를 통해서 하나의 View씩 나열 할 수 있다. 또한 Custom View를 제작하여 AdapterView로 사용함으로써 자신이 원하는 틀을 제작할 수 있다. 실제 개발에서는 후자의 경우가 많이 사용될 것이므로 이에 대해서 설명하도록 하겠다.

 


 

개발방법 

(customView를 수직으로 나열하도록 개발)

  1. 먼저 res->layout에 AdapterView로 사용할 customVeiw.xml 파일을 생성한다

  2. 자신이 원하는 View구성을 위 파일에 입력한다.

  3. View들을 나열할 액티비티로 이동해서 ListView listview를 추가한다.

  4. 나열할 데이터들을 가져와 배열을 생성함

  5. ListView객체를 생성하고 미리 생성한 ListVeiw를 참조함

  6. Adapter를 생성함

    1. 데이터를 가지고 있는 ArrayList<HashMap<String,Object>> dataList를 생성함

    2. 배열 내부의 HashMap을 참조하기 위해 key값이 나열된 배열을 생성 -> String[] keys

    3. 위에서 생성한 AdapterView의 내부 View아이디를 참조하기 위한 id 배열생성 -> String[] id

      1. **중요** 나중에 keys, id 배열들의 값이 각각 일대일 대응되어 데이터가 저장되므로 순서가 중요함

    4. Adapter를 만들어 준다

      1. SimpleAdapter ad = new SimpleAdapter( this,  dataList, R.layout.customView, keys,id);

        (keys와 ids 내부의 배열들이 인덱스 0 부터 일대일 대응이 되고 keys 배열 순서에 따라 dataList의 하나의 해쉬맵에서 value가 참조되어 ids에  일대일 대응 되어 삽입이 된다.)
    5. Adapter를 세팅해준다.

      1. listview.setAdapter(ad);

        

 

 

Chapter 1 ~ 3은 파이썬의 초기설정, 퍼셉트론 이론 그리고 신경망이론에 대해서 설명하고 있다.

이에 대해서는 기본적으로 알고 있다고 생각하고 여기에는 신경망을 실질적으로 이해하고 코드로 구현하는 방법에 대해서 설명하고자 한다.

 

1. 신경망의 정의

 

책에서 설명하는 신경망은 사실상 퍼셉트론의 확장이라고 할 수 있다. 퍼셉트론에서 활성화 함수(인공뉴런 의 입력값을 출력값으로 바꿀때 쓰이는 함수)로 시그모이드 함수나 ReLU함수 같은 비계단형 함수를 사용하면 그것이 신경망의 물리적 구조라고 할 수 있기 때문이다. 

 

2. 신경망의 학습과정

 

신경망의 학습과정은 추상적으로 표현할 경우 다음과 같다.

1. 모델(예측함수) -> 2. 결과값 비교 -> 3. 매개변수 업데이트 계산 -> 1. 모델(예측함수) .....

 

이런 말은 상당히 많이 들어봤을 거라고 생각한다. 그래서 하나하나 문장의 의미를 프로그래밍 코드로 표현할 수 있도록 수학적으로 표현해 볼 예정이다.

 

1. 모델(예측함수)

 여기서 말하는 모델은 말그대로 신경망 자체를 의미한다. 신경망은 입력층 - 은닉층 - 출력층으로 구성되어 있고 각 층 사이에는 가중치값들로 노드들이 서로 연결되어있다. 

 그리고 예측은 입력층부터 출력층까지 가중치 값을 통해서 계산하여 결과값을 나타내는 것을 의미한다.

 

이를 세부적으로 풀어서 말해보자

 

1) 입력층

입력층은 말그대로 데이터를 입력하는 뉴런들이 있는 첫 번째 층이다. 예를 들어 우리가 24x24 사이즈의 사진 데이터를 입력하여 사진에 고양이가 있는지 없는지 판단해본다고 하자. 그럼 입력해야하는 데이터는 24x24 = 576가지가 된다. 그러므로 입력층에는 576개의 뉴런들이 존재하게된다.

 

2) 출력층

은닉층을 설명하기 전 출력층에 대해서 설명해보도록 하자. 출력층 또한 말 그대로 전 단계의 층에서 받은 데이터를 처리해서 출력하는 것을 의미한다. 우리가 원하는 출력은 고양이가 있는지/없는지 즉 두 가지 종류를 가지고 있다. 이를 좀더 수식으로 표현하면 Result = 1 ( 고양이가 존재함 ) or 0 (고양이가 존재하지 않음)으로 표현할 수 있다. 따라서 마지막 출력층은 두 가지 데이터를 출력 할 수있으므로 출력층의 뉴런은 1개만 있어도 된다.

 

3) 은닉층

은닉층은 입력층과 출력층 사이에 존재하면서 데이터를 처리하도록 한다. 만약 은닉층이 없을 경우 입력층에서 바로 출력층으로 이어지게 되며 위와 같은 예시에서는 576개의 입력층 뉴런이 1개의 출력층 뉴런에 바로 이어지게 되며 이에 사용되는 매개변수는 576개가 된다. 이 때 매개변수가 매우 적으므로 범용적으로 데이터의 출력값을 정확히 하기에는 어려움이 있다. 왜냐하면 매개변수가 적을 경우 데이터를 판별하는 기준이 적다는 의미가 되고 기준이 적다는건 컴퓨터가 제대로 데이터를 판단하는데 부족한 능력을 가질 수 밖에 없기 때문이다.

 

 

+ Recent posts