강의 1. 저는 일본 사람이에요.

本講義を受講する前提として、ハングルの読みはできることを前提とする。

1. ~예요/이에요(~です)

名詞の後ろにつけ、主語の内容・属性を指定・説明

  • A는/은 B예요/이에요(AはBです)みたいに、A=Bを表現する
  • いつも名詞の後ろに来る

原型

原型は~다/이다であり、こちらは会話では使わない

  • ~예요/이에요は親しい人に使用
  • 敬語は~입니다

예요/이에요の区分

  • 예요
    • 前の名詞が母音で終わる場合
    • ex) 저는 유나예요.(私はユナです。)
  • 이에요
    • 前の名詞が子音で終わる場合
    • ex) 저는 일본 사람이에요.(私は日本人です。)

母音と子音の区分

받침の有無で区分すればよい。

  • 母音
    • 받침がない
    • ex) 저, 유나
  • 子音
    • 받침がある
    • ex) 일본, 한국

イントネーションによる意味変化

~예요/이에요は、文章の最後のイントネーションを上げると質問になる。

こちらも日本語と用法は同じ。

  • 일본 사람이에요? ↑
    • 日本の方ですか
  • 일본 사람이에요. ↓
    • 日本人です

2. ~은/는(~は)

対象(人物、話題など)の後ろにつけ、その対象について話す場合に使用する。

  • 基本的な用法は日本語のとほぼ一致する

은/는の区分

    • 前の名詞が母音で終わる場合
    • ex) 저 유나예요.(私ユナです。)
    • 前の名詞が子音で終わる場合
    • ex) 제 이름 유나예요.(私の名前ユナです。)

3. 肯定/否定

네/아니요(はい/いいえ)

用法ははい/いいえと完全一致する。

例文

유나씨는 한국 사람이에요?(ユナさんは韓国の方ですか?)

  1. , 저는 한국인이에요.(はい、私は韓国人です。)
  2. 아니요, 저는 일본인이에요.(いいえ、私は日本人です。)

~이/가 아니예요(~ではありません)

こちらも用法は完全に一緒。

例文

  • 유나씨는 일본 사람이에요?
    • ユナさんは日本の方ですか?
  1. 네, 저는 일본 사람이에요.(はい、私は日本人です。)
  2. 아니요, 저는 일본 사람이 아니예요. 한국 사람이에요.(いいえ、私は日本人ではありません。韓国人です。)

4. 質問

뭐(何)/뭐예요?(何ですか?)

は疑問詞であって、日本語のと一致する。

  • 質問の対象が事物や抽象名詞(名前、職業、趣味など)の場合に使用
  • 疑問視の後ろに에요?をつけて뭐에요?と質問する

例文

  • 이름이 뭐예요?(名前は何ですか?
  • 취미가 뭐예요?(趣味は何ですか?
  • 이것은 뭐예요?(これは何ですか?

이/가の区分

    • 前の名詞が子音で終わる場合
    • ex) 순대국 맛있어요.(スンデグック美味しいです。)
    • 前の名詞が母音で終わる場合
    • ex) 김치찌개 맛있어요.(キムチチゲ美味しいです。)

누구(誰)/누구예요?(誰ですか?)

누구は疑問詞であって、日本語のと一致する。

例文

  • 그 사람은 누구예요?(その人は誰ですか?

5. 이/그/저/어(こ/そ/あ/ど)

指示代名詞。日本語と韓国語が不思議なくらい似ていることが分かる。

例文

  • 이것은 뭐예요?(これは何ですか?)
  • 그 사람누구예요?その人は誰ですか?)
  • 저 옷는 얼마예요?(あの服はいくらですか?)
  • 어느 나라 사람이에요?(どの国の人ですか?)

練習

以下単語を使って、文章を作成してみましょう。

일본(日本), 한국(韓国), 중국(中国), 미국(アメリカ), 영국(イギリス), 스위스(スイス)
학생(学生), 주부(主婦), 직장인(会社員)
아기(赤ちゃん), 어린이(子供), 어른(大人)
사람(人), 과자(お菓子), 장난감(おもちゃ), 옷(服), 나라(国)

Tips

本チャプターでの子音・母音まとめ

意味 母音で終わる 子音で終わる
です 예요 이에요

Electronとは

  • 旧)Atom Shell
  • Node.jsに基づいたDesktop Application Flatform
    • HTML, CSS, JavaScriptで、Cross-Flatformで 動くDesktop Applicationを作れる
    • WebPageのGUIとjavascriptで操作するChromium Browser
  • Desktop Application : 似た技術としてNW.js (node-webkit)が存在
    • 技術的な違いについては、ここを参考
  • Electronで作られたアプリについては、Awesome Electron 参照

環境構築手順

目標

  • WindowsでのElectron開発環境構築
  • ElectronでHello Worldの出力
  • パッケージングでexeファイルを作成、動作確認

基本設定

  • 装置1スペック
    • CPU : i3-4000M 2.40GHz
    • RAM : 4.0GB
    • OS : Microsoft Windows 8.1 Enterprise K 64Bit
    • Electron Version: 0.36.8
  • 装置2スペック
    • CPU : i3-3240 3.40GHz
    • RAM : 4.0GB
    • OS : Microsoft Windows 7 Professional SP1 32Bit
    • Electron Version: 0.36.8

下準備

  • Node.js : Stable Version (v.5.7.1)
    • npmを使うので、Node.jsの設置は必須!
    • Windowsのバージョンに合わせて、msiファイルをダウンロードし、設置するだけでOK
  • Node.jsの設置確認
    • cmd > node
    • 簡単なjavascriptコードを入力し、テスト

    cmdTest.png

  • jsファイルでのテスト : app.js (エンコード:UTF-8)
var http = require('http');
 http.createServer(function(req,res){
   res.writeHead(200,{'Content-Type':'text/plain'});
   res.end('Hello World\nHello node.js!');
 }).listen(1337,"127.0.0.1");

 console.log("Server running at http://127.0.0.1:1337/");

Electronのインストール

  • npmを使って、electron-prebuiltをダウンロード
  • Globalで設置したので、どこでプロジェクトを作成しても「electron プロジェクト名/」で実行できる。

    inst.png

Electronの実行

Electron Appの構造

your-app/
├── package.json : main fieldにscript fileを指定し、main processのエントリーポイントとして使用
├── main.js      : Windowを作り、システムイベントを処理
└── index.html   : ユーザに見せるページ

プロジェクト生成

  • Electronは、実行されるときに「package.json」のmain scriptを呼び出す。
    • main script:main processで作動し、GUI Component操作・Web Page生成
  • npm initpackage.jsonを作成
    • 何を言ってるのか全然理解できなかったら、ただEnterだけ押せばほとんどOK *ここではプロジェクト名をelectronに設定
    • ただ、entry pointには必ず「main.js」を設定すること!
      • もしpackage.jsonmain scripttが設定されてない場合、 Electronは自動で同じディレクトリーのindex.jsをロードする

    initProject.png

    上の作業で、下のような「package.json」が生成される

/**
 * package.json
 **/
{
  "name": "electron",
  "version": "1.0.0",
  "description": "print \"Hello, Electron\"",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Youngjae Kwon",
  "license": "ISC"
}

Hello, Electron!

  • 一旦準備が終わったので、いつもの通り「Hello World」みたいな物を出力してみよう。
  • initmain script「main.js」で設定したので、main.jsから作成することに。

main.js

/**
 * main.js
 **/
// アプリケーション基盤をコントロールするモジュール
var app = require('app');

// ブラウザーウィンドーを作るモジュール
var BrowserWindow = require('browser-window');

// ウィンドーオブジェクトを全域に維持
var mainWindow = null;

// すべてのウィンドーが閉じられたら呼び出される (アプリケーション終了)
app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

// Electronの初期化が完了し、ブラウザーウィンドーを開く準備ができたら実行
app.on('ready', function() {
  // 新しいブラウザーウィンドーを生成
  mainWindow = new BrowserWindow({width: 800, height: 600});

  // 今のディレクトリーで「 index.html」をロード
  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  // ウィンドーが閉じられたら呼び出される  (アプリケーション終了)
  mainWindow.on('closed', function() {
    // ウィンドーオブジェクトの参照を削除
    mainWindow = null;
  });
});
  • main.jsindex.htmlを呼ぶことにしたので、今度はindex.htmlを作成する。
    • 実際目に見える部分はここで作成する。

index.html

<!--
/*
 * index.html
 */
 -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Sample</title>
</head>
<body>
  <p>Hello, Electron!</p>
</body>
</html>

これで準備はOK。実行してみよう。

sample.png

Packaging

  • プロジェクトを誰でも使えるように、パッケージ化してみよう。
  • ここでは、electron-packagerを使って作業。
    • これもnpmでもってこればOK

    packager.png

    これでダウンロード終わり。

早速使ってみよう

packager2.png

この通り、electron-win32-ia32とelectron-win32-x64フォルダが生成された。 書いた内容を説明すると…

platform : all, linux, win32, darwin arch : all, ia32, x64 version : Electronのバージョン (現在0.36.8)

ここでallを選んだので、フォルダが32と64の二つができた。

もし32bitWindowsの装置を使ってるとしたら、実は electron-packager ./electron electron --platform=win32 --arch=ia32 --version=0.36.8 これだけでOK。

実行

run.png

プロジェクト名をElectronにしてしまって、ちょっとわかり辛くなったが, こうやってEXEファイルができ、それを実行したら普通にアプリが動く。

Electronでのアプリケーション開発

1. 目標

  • 簡単なメモ帳アプリの作成 (テキストの保存とロード機能)
  • WindowsでElectronを使うこと
  • プロジェクト作成にはAtomGruntを使ってみること
  • パッケージングでEXEファイルを作り、動作を確認

2. 準備

2-1. Atom

  • Atom ダウンロード (https://atom.io)
    • Windowsのバージョンに合わせてインストールするだけでOK
  • Packageの設置 (File→Settings→InstallでPackage検索)
    • linter : 文法上のエラー表示
    • grunt-runner : AtomでGrunt実行
    • minimap, minimap-find-and-replace : minimapが見える
    • atom-minify : JS, CSSの圧縮化 (ctrl+shift+m or 「Minify on save」設定)

package-atom.png

2-2. Grunt

  • Gruntとは?
    • プロジェクト自動化のためのCommand Line Build Tool
    • パッケージ管理者 (Yeoman , Bower , Gulp等と同じ)
    • もっとも基本的な自動化パッケージ
  • grunt-cli (Grunt’s Command Line Interface) 設置
    • grunt-cliの設置で、システム経路に「grunt」コマンドが追加され、gruntが使えるようになる。
    • grunt-cliの役割はただGruntflieというファイルがある場所に設置されたGruntを実行するだけ。

grunt-cli.png

  • Grunt Module 設置方法 (package.jsonがあるディレクトリで設置)
    • 新しいModuleを設置し、package.jsonに記入 : npm install grunt --save dev
    • すでにpackage.jsonに記入されているModuleを設置 : npm install (package.jsonとGruntfile.jsがあれば、どこでも同じgrunt作業が可能!)
    • ここでは2の方法でプロジェクト作成

3. Project作成

3-1. ディレクトリ構成図

C:\PROJECT\MEMO
│  Gruntfile.js
│  main.js
│  package.json
│  
├─app
│  ├─css
│  │      bootstrap-theme.css
│  │      bootstrap-theme.css.map
│  │      bootstrap-theme.min.css
│  │      bootstrap.css
│  │      bootstrap.css.map
│  │      bootstrap.min.css
│  │      
│  ├─fonts
│  │      glyphicons-halflings-regular.eot
│  │      glyphicons-halflings-regular.svg
│  │      glyphicons-halflings-regular.ttf
│  │      glyphicons-halflings-regular.woff
│  │      glyphicons-halflings-regular.woff2
│  │      
│  ├─html
│  │  │  index.html
│  │  │  
│  │  └─include
│  │          link.html
│  │          memo.html
│  │          
│  ├─js
│  │  │  memo.js
│  │  │  memo.min.js
│  │  │  
│  │  └─lib
│  │          bootstrap.js
│  │          bootstrap.min.js
│  │          jquery-1.12.1.js
│  │          jquery-1.12.1.min.js
│  │          npm.js
│  │          
│  └─view
│      │  index.html
│      │  
│      └─include
│              link.html
│              memo.html
│              
├─dist
│  ├─css
│  │      style.min.css
│  │      
│  └─js
│          site.js
│          site.min.js
│          
└─node_modules
    ├─grunt
    ├─grunt-cache-breaker
    ├─grunt-contrib-cssmin
    ├─grunt-contrib-uglify
    ├─grunt-includes
    ├─load-grunt-tasks
    ├─moment
    └─time-grunt

css・fonts・libフォルダには、 BootstrapJQuery をダウンロードして入れる。

3-2. プロジェクトソース

package.json

{
  "name": "memo",
  "version": "1.0.0",
  "description": "save and load txt file",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Youngjae Kwon",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.5",
    "moment": "^2.8.3",
    "grunt-cache-breaker": "^2.0.1",
    "grunt-contrib-cssmin": "^1.0.0",
    "grunt-contrib-uglify": "^1.0.0",
    "grunt-includes": "^0.5.4",
    "load-grunt-tasks": "^3.4.1",
    "time-grunt": "^1.3.0"
  }
}

main.js

/**
 * main.js
 **/
var app = require('app');
var BrowserWindow = require('browser-window');
var mainWindow = null;

app.on('window-all-closed', function() {
  if (process.platform != 'darwin') {
    app.quit();
  }
});

app.on('ready', function() {
  mainWindow = new BrowserWindow({width: 550, height: 410});
  mainWindow.loadUrl('file://' + __dirname + '/app/view/index.html');
  mainWindow.on('closed', function() {
    mainWindow = null;
  });
});

Gruntfile.js

/**
 * Gruntfile.js
 **/
module.exports = function(grunt) {
    'use strict';
    var moment = (require('moment'))();
    var timestamp = 'None';

    // 自動でgrunt Taskをロードする。(grunt.loadNpmTasksは省略可能)
    require('load-grunt-tasks')(grunt);

    // 作業時間表示
    require('time-grunt')(grunt);

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),

        // html task
        includes: {
            files: {
                cwd: 'app/html/',    // app/htmlのhtmlファイルにinclude処理をして
                src: ['**/*.html'],
                dest: 'app/view/',    // その結果をapp/viewに入れる
                options: {
                    flatten: true,
                    debug: true,
                    includePath: 'app/html/'
                }
            }
        },
        // css task
        cssmin: {
            options: {
                keepSpecialComments: 1,
            },
            dist: {
                src: 'dist/css/style.css',
                dest: 'dist/css/style.min.css'
            }
        },
        // js task
        uglify: {
            options: {
                banner: '<%= banner %>'
            },
            dist: {
                src: 'dist/js/site.js',
                dest: 'dist/js/site.min.js'
            }
        },
        cachebreaker: {
          dev: {
            options: {
              match: ['.js'],
              replacement: function () {
                return moment.format('YYYYMMDDhhmmss');
              }
            },
            files: {
              src: ['app/html/*.html', 'app/view/*.html']
            }
          }
        }
    });

    // html task
    grunt.registerTask('html', ['includes']);
    // css task
    grunt.registerTask('css', ['cssmin']);
    // javascript task
    grunt.registerTask('js', ['uglify', 'cachebreaker']);

    // default task
    grunt.registerTask('default', ['html', 'css', 'js']);
};

index.html

<!--
/*
 * index.html
 */
 -->
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Memo MK2</title>
  <link href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  include "include/link.html"
  include "include/memo.html"
</body>
</html>

link.html

<!--
/*
 * link.html
 */
 -->
<script src="../js/lib/jquery-1.12.1.min.js"></script>
<script src="../js/lib/bootstrap.min.js"></script>
<script type="text/javascript" src="../js/memo.min.js"></script>

memo.html

<!--
/*
 * memo.html
 */
 -->
<table class="table table-striped">
  <tr>
    <td style="text-align: left; width: 100px;">テキスト入力</td>
    <td colspan="2" style="text-align:left; width:300px;">
      <textarea id="ntText" class="input-xxlarge" style="width:95%; height:200px;" maxlength="4000"></textarea>
    </td>
  </tr>
  <tr>
    <td>ファイル名</td>
    <td>
      <input type="text" class="form-control"  id="nmSaveFile" />
    </td>
    <td>
      <button class="btn btn-default btn-primary" onclick="saveTxt()">保存する</button>
    </td>
  </tr>
  <tr>
    <td>ファイル選択</td>
    <td>
      <input type="file" class="form-control"  id="nmLoadFile" />
    </td>
    <td>
      <button class="btn btn-default btn-primary" onclick="loadTxt()">ロードする</button>
    </td>
  </tr>
</table>

memo.js

/**
 * memo.js
 **/
// テキスト保存
function saveTxt(){
  var ntText = document.getElementById("ntText").value;
  var ntBlobText = new Blob([ntText], {type:'text/plain'});
  var nmSaveFile = document.getElementById("nmSaveFile").value;
  var saveLink = document.createElement("a");
  saveLink.download = (nmSaveFile === null || nmSaveFile == "") ? "memo.txt" : nmSaveFile + ".txt";
  saveLink.innerHTML = "Download File";
  saveLink.href = window.webkitURL.createObjectURL(ntBlobText);
  saveLink.click();
}

// テキストロード
function loadTxt(){
  var nmLoadFile = document.getElementById("nmLoadFile").files[0];
  var fileReader = new FileReader();
  fileReader.onload = function(fileLoadedEvent){
    var ntLoadText = fileLoadedEvent.target.result;
    document.getElementById("ntText").value = ntLoadText;
  };
  fileReader.readAsText(nmLoadFile, "UTF-8");
}

3-3. プロジェクト作成

  • node_modules インストール
    • package.jsondevDependenciesとして定義されているmoduleを全部インストールする。
    • C:\PROJECTにてnpm install
  • Atom Minifymemo.min.js作成
    • atom-minifyの設定で「Minify on save」を設定すると、保存する時に自動でmemo.min.jsを生成
    • この画面が出ればOK。

    success_minify.png

  • Grunt RunnerGruntDefaultで動かす
    • Gruntは勉強用で入れたのがほとんどで、実際この作業で必須なのはincludesだけ。
    • link.htmlmemo.htmlindex.htmlに含め、/app/view/index.htmlを作成
    • この画面が出ればOK。

    grunt_success.png

  • C:\PROJECTにてelectron memo/で動作確認
    • この画面が出ればOK。

    run_electron.png

4. パッケージング・動作確認

4-1. パッケージング

memoフォルダmemoMK2という名前でパッケージングする。

C:\project>electron-packager ./memo memoMK2 --platform=win32 --arch=ia32 --version=0.36.8
Packaging app for platform win32 ia32 using electron v0.36.8
Wrote new app to C:\project\memoMK2-win32-ia32
C:\project>

4-2. 作動確認

complete.png

まとめ

  • すごく簡単!
    • Web Pageを作る感覚で、普通にDesktop Applicationが作れる。
    • 環境設定に時間がかからないのもメリット
      • 以前のHadoopの時を考えたら…
      • 特にWindowsでも簡単にできるのが嬉い。
  • Creatorとしての喜び
    • こうやって簡単にアプリを作れるから、創作意欲が沸く。
    • 自分に必要な物は、自分で作ってみよう!

参考