OmniAICreator/Qiita-1.07M huggingface dataset:
HoloLens用のUnity Native Pluginの作り方

# はじめに
HoloLens用にUnityのネイティブプラグインを作成するためのサンプルプロジェクトを作りました。
UnityEditor用DLLのプロジェクトとHoloLens(UWP)用DLLのプロジェクトを一つのソリューションにまとめた形になっています。
プロジェクト設定が非常に面倒だったので、今後はこのプロジェクトをテンプレートとして流用していきたいです。

# サンプルプロジェクト
- [NativePluginSampleForHoloLens](https://github.com/sotanmochi/NativePluginSampleForHoloLens)
  -> ネイティブプラグインを作成するためのVisual Studioのプロジェクト
- [UnityProjectForNativePluginSample](https://github.com/sotanmochi/UnityProjectForNativePluginSample)
  -> 上記のプロジェクトで作成したDLLを使っているUnityのサンプル

# 開発・検証環境
- Visual Studio 2017 (Version 15.6.6)
- Unity 2017.4.2.f2

# Native Plugin の作り方
[NativePluginSampleForHoloLens](https://github.com/sotanmochi/NativePluginSampleForHoloLens)のソリューションファイルを開いてビルドします。
流用する場合はソースコードを修正してからビルドします。

## 解説
ソリューション構成は以下の通りです。

- NativePlugin -> ソースコード管理用の共有プロジェクト
- NativePluginForEditor -> UnityEditorでの実行時に利用されるDLL用のプロジェクト
- NativePluginForUWP -> HoloLens実機での実行時に利用されるDLL用のプロジェクト

![Solution.png](https://qiita-image-store.s3.amazonaws.com/0/162000/27836672-f7a9-103f-8d77-573ef0a2dee8.png)

ソースコードは共有プロジェクトの「NativePlugin」に含まれていますが、メインとなるコードは「NativePlugin.h」と「NativePlugin.cpp」です。今回のサンプルでは2つの整数の和を計算する単純な関数を実装してあります。

![NativePluginHeader.png](https://qiita-image-store.s3.amazonaws.com/0/162000/5f5ac9dd-2803-3e3f-49f5-90a8baeab3b1.png)

![NativePluginSource.png](https://qiita-image-store.s3.amazonaws.com/0/162000/d8659778-55cc-933a-f418-075a92cc4995.png)

## ビルド方法
1. Visual Studio 2017で「NativePluginSampleForHoloLens.sln」を開く

2. ビルド -> バッチビルド を選択
![Build01.png](https://qiita-image-store.s3.amazonaws.com/0/162000/d3eb6256-8c10-476b-c6c7-c591b0811169.png)

3. ビルドするプロジェクトを選択してビルドを実行する。HoloLens(UWP)用DLLとUnityEditor用DLL(32bit/64bit)を選択する。
![Build02.png](https://qiita-image-store.s3.amazonaws.com/0/162000/6ff8bd74-2123-f848-2b8c-35d64e21895f.png)

ビルドが成功すると3つのDLLが生成されます。

- UnityEditor(32bit)用DLL  
  -> NativePluginSampleForHoloLens\Release\NativePluginForEditor\NativePlugin.dll
- UnityEditor(64bit)用DLL  
  -> NativePluginSampleForHoloLens\x64\Release\NativePluginForEditor\NativePlugin.dll
- HoloLens(UWP)用DLL  
  -> NativePluginSampleForHoloLens\Release\NativePluginForUWP\NativePlugin.dll

# Unityプロジェクトへのプラグインの追加
作成したDLLをPluginsフォルダに配置して、インポート設定を変更します。

## HoloLens(UWP)用DLL
「Plugins\WSA\x86」に配置する。設定は以下の通り。
![PluginSettingUWP.png](https://qiita-image-store.s3.amazonaws.com/0/162000/b97aa9fe-5a39-d4ed-2e69-354bac478d33.png)

## UnityEditor(64bit)用DLL
「Plugins\x64」に配置する。設定は以下の通り。
![PluginSettingEditor64.png](https://qiita-image-store.s3.amazonaws.com/0/162000/aa138ebd-17e8-c9d0-7254-42e79e649632.png)

## UnityEditor(32bit)用DLL
「Plugins\x86」に配置する。設定は以下の通り。
![PluginSettingEditor32.png](https://qiita-image-store.s3.amazonaws.com/0/162000/84324a6c-4415-af2e-147d-77ccb40bcb1a.png)

# Native Pluginの処理をスクリプトから呼び出す
DLLをインポートしたクラスを作成する。
![Script01.png](https://qiita-image-store.s3.amazonaws.com/0/162000/8749458f-cf82-778a-712c-06f2e34d5cfe.png)

上記のクラスから処理を呼び出す。
![Script02.png](https://qiita-image-store.s3.amazonaws.com/0/162000/21cbd9c8-22d7-38bb-148c-cb2e56198544.png)

# まとめ
HoloLens用にUnityのネイティブプラグインを作成するためのサンプルプロジェクトを紹介しました。
ネイティブプラグインで実装した処理をUnityで実行する方法についても紹介しました。
VagrantでCentOS7インストール

# 環境
Mac OS
Vagrant-1.8.5
Oracle VirtualBox 5.1.2


# 手順
vagrantで仮想サーバーを構築する際は、Vagrantfileが必要になるので用意する

```vim:Vagrantfile
Vagrant.configure("2") do |config|
 
  config.ssh.insert_key = false
 
  config.vm.define "[VM Name]" do |[VM Name]|
    [VM Name].vm.box = "centos/7"
    [VM Name].vm.network :private_network, ip: "192.168.xxx.xxx"
  end

  config.vm.provider "virtualbox" do |vb|
    vb.gui = false 　　　　　　　　　　　　← vagrant upするたびにウィンドウを開かないようにする
    vb.name = "[VM Name]"
  end

# Synced Folder
#  config.vm.synced_folder "[Host Directory]", "[Guest Directory]", type: "nfs"

end
```

ちなみに

```
[VM Name].vm.box = "centos/7"
```
の設定を変更すると、いろんなサーバーがサクッと作れちゃういます
https://app.vagrantup.com/boxes/search

vagrantfileを用意したディレクトリでvagrant upを実行

```
> vagrant up
〜
==> [VM Name]: Configuring and enabling network interfaces...
```


エラーが出ずに終了したら、vagrant sshでサーバーにログインする

```
> vagrant ssh
```

# ここからは個人的に良くやる初期設定
## VMなんでSELinux切る
一時的に切る場合は以下コマンド実行

```
> setenforce 0
```

永久的に切る場合は以下のファイルを修正

```vim:/etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
# SELINUX=enforcing　　　←　この行をコメントアウト
SELINUX=disabled　　　　 ←　この行を追加
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted
```

## SSHの公開鍵認証を設定
サーバー側のSSH設定を変更

```/etc/ssh/sshd_config
〜
#PubkeyAuthentication yes　　←　コメント解除
```
設定を変更したらSSHの再起動

```
> systemctl restart sshd
```

ホストマシン側で鍵を作成

```text:Mac
$ ssh-keygen -t rsa
〜
# 鍵の出力先を変更する場合は下記に出力先を入力
Enter file in which to save the key (/Users/hoge/.ssh/id_rsa): [出力先入力]

# パスワードを設定したい場合は下記入力
Enter passphrase (empty for no passphrase): [パスフレーズ]
Enter same passphrase again: [パスフレーズ]
```

公開鍵をサーバーに設置

```text:Mac
$ cd ~/.ssh
$ scp id_rsa.pub hoge@xxx.xxx.xxx.xxx:/
```

```text:Server
> cd ~

# authorized_keysがない場合のみ作成
> touch ~/.ssh/authorized_keys

# 先程送った公開鍵を追記する
> cat id_rsa.pub >> authorized_keys

# 権限を設定
> chmod 700 ~/.ssh
> chmod 600 ~/.ssh/authorized_keys
```
ティラノスクリプトの[s]タグでゲーム停止中にメッセージレイヤーを非表示にするとゲーム再開できなくなる問題

長いよ。
これでも簡潔に説明してるんです。

##どういうことか
ティラノスクリプトのゲームはデフォルトでシステム画面へジャンプするボタンが付いています。
画像右下の歯車ボタンですね。
![20180529.PNG](https://qiita-image-store.s3.amazonaws.com/0/190389/47a27367-e7f0-ac44-80ce-265b63e3c32e.png)

このボタンから移動できるシステム画面にはデフォルトだと以下の機能を持ったボタンが配置されています。

- セーブ画面へのリンク
- ロード画面へのリンク
- メッセージレイヤーを非表示
- 既読メッセージのスキップ
- タイトル画面へ戻る

通常、右クリックをすることでもメッセージレイヤーの表示・非表示の切り替えは可能ですが、選択肢の表示中など[s]タグを使い、ゲームを停止させている状態では右クリックは無効にされているようです。
また、[s]タグでゲーム停止中は、選択肢などのリンクをクリックする以外にはゲームの進行を再開させることはできません。
しかしゲーム停止中でも歯車ボタンからメッセージレイヤーを非表示にすることはできます。
つまりどういうことかというと、

1. [s]タグでゲームを停止させる
2. 歯車ボタンからメッセージレイヤーを非表示にする
3. 右クリック無効のため右クリックでメッセージレイヤーを表示させることができない
4. 通常のクリック操作も当然無効
5. 何もできなくなる

ということです。

##ではどうするか
解決策は色々あると思いますが今回はシステム画面からメッセージレイヤーの表示・非表示切り替えができるようにしました。

```javascript:kag.menu.js
layer_menu.find(".menu_window_close").click(function (e) {
          //ここから追加
          if(that.kag.stat.is_hide_message === false){
            that.kag.layer.hideMessageLayers();
          }else{
            that.kag.layer.showMessageLayers();
          }
          //ここまで追加
          layer_menu.hide();
          if (that.kag.stat.visible_menu_button == true) $(".button_menu").show();
          e.stopPropagation()
        });
```

ただ操作が直感的でないなとは思います…が、右クリックでメッセージ非表示にできるのにわざわざシステム画面から非表示にする人なら同じボタンでメッセージ表示にすることにも気づいてくれるんじゃないかな……
C++ Builder 10.2 Tokyo > TOpenDialog > FilterIndex > 1から始まる > Off-by-one errorに注意

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
Windows 10 Pro (64bit) バージョン 1803 (April 2018 Update)
```

### index from 1

http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Dialogs.TOpenDialog.FilterIndex

> Set FilterIndex to 1 to choose the first file type in the list as the default, or set FilterIndex to 2 to choose the second file type as the default, and so forth. 

一つ目の項目を選択するためには「1」をFilterIndex に代入する。

C++ではインデックスは0始まりのため、この点はOff-by-one errorにつながりそう。

- [技術英語 > Off-by-one error / OBOE](https://qiita.com/7of9/items/9cf5e9c1e8751c23dbd5)

### delphiのString > index from 1

C++ BuilderはDelphiの実装がベースであると認識している。
Delphiの実装に基づき1始まりのインデックスなのだろうか。

下記を見つけた。
https://stackoverflow.com/questions/1143340/how-to-get-the-first-element-in-a-string

> answered Jul 17 '09 at 13:41
Ondrej Kelle

> Strings are 1-based:

FilterIndex が使われるのはStringではなくて、StringListだろう。
そちらも1-basedになっているようだ。
unicornを再起動するとエラー②~MySQLに関するエラー~

#unicorn再起動するとエラーが出ます
どうやらMySQL関連のエラーのようですね・・・

##MySQL起動してない
log/unicorn.logを見ます

```:unicorn.log
Can't connect to local MySQL server through socket
```

MySQLが起動していない??

```:Terminal
$ sudo service mysqld start 
```

##production環境のDatabaseを作成できてない

```:unicorn.log
Unknown database '[db]_production'
```

以下のように記述します。

```:database.yml
 production:
   <<: *default
   database: [Application_name]_production
   username: root
   password:   
   socket: /var/lib/mysql/mysql.sock
```

さらにそれをdb:migrateしていきます。これでdevelopment環境だけでなく、production環境のデータベースをさくせいできます。

##db:migrateできない

```:Terminal
$ rake db:migrate
```

```:Terminal
Can't connect to local MySQL server through socket '/tmp/mysql.sock'
```

このエラーは①のエラーと殆ど同じかと思われますが、データベースが起動できてない、もしくは権限に関するエラーの可能性が高いです。

権限に関するエラーの解決
https://qiita.com/kanohisa/items/564035efd74d9c75bdcb

ググるといろいろ出てくるエラーでした。
Chefによるテキストファイル編集をfileリソースにおけるsed, awkで行う例

#Chefによるテキストファイル編集をfileリソースにおけるsed, awkで行う例
```ruby:default.rb 
file '/tmp/text' do
  content lazy {
    s = %x(cat #{path})

    # 以下の編集箇所は、rubyのloopなどで繰り返し処理可能
    s = %x(
      { 
        cat <<'EOC'
#{s.chomp}
EOC
      } | sed -e 's/abc/def/'
    )

  }
end
```

Chef::Util::FileEditは便利だが、パイプラインで繋いでsedやawkを使いたくなるときもある。一つの%x()で処理するならばcat #{path} | sed ...などとできるが、Rubyのループと組み合わせにくくなってしまう。色々試した結果、上の様な書き方に落ち着いた。

シェルの''で括ったヒアドキュメントは各種記号をエスケープなしでそのまま扱うことができる。
\により行を継続させる必要がなければ cat <<'EOC' | sed ...などとしても良い。(i.e. ヒアドキュメント文で\による行の継続をスマートに行う方法が判らなかった。)
- echo '#{s}' | ...
- echo -e "#{s}" | ...
- echo -e "#{Regexp.escape(s)}" | ...
などでは含まれる記号によってはescapeが必要となってしまう
.gsub などを付けて対応も原理的には可能だが美しくない
interfaceとabstract

javaで出てくるinterfaceとabstractの違いをもう一度思い出したい。

#interface
- 数をまとめて宣言(定義)するだけ
- (実装はimplementsして使用する)
- (クラスでないのでインスタンス生成できない)
- 仮引数にinterface型を定義すると、その型を継承しているクラスは全て引数として受け取れる

#abstract
- interface機能 ＋ 実装もできる
- 仮引数にabstract型を定義すると、その型を継承しているクラスは全て引数として受け取れる
- インスタンス生成できない
abstractクラスを継承したクラスを実装して使用する
No signing certificate “iOS Distribution” found が出てビルドできない

結構時間をロスしたのでメモ
# 原因
Xcode 9.3のバグのようで、証明書とチームIDの自動結び付けが機能しなくなっていた。
正確にはXcode 9.3のバグではなく、Xcodeのバージョンアップをしたことで発生する事象の可能性がある。

Stackoverflowは[こちら](https://stackoverflow.com/questions/49643253/provisioning-profile-doesnt-include-signing-certificate-xcode-9-3?rq=1&utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa)


# 対応
Build Settings > Signing を直接設定することでビルドがすんなり通りました。


すべてプロビジョニングプロファイルを入れ替えるなどの対応方法でも解決できるようです。
http://blog.janjan.net/2017/02/24/xcode-distribution-provisioning-no-signing-certificate-ios-distribution-found/
Unity と Mac で開発する Oculus Go アプリ #5 コントローラーを表示する

Oculus Go & Unity 初心者が開発するまでのメモ

## Oculus Utilities とは

Unityには元々用意されていない、次のようなOculus固有の機能が使えるようになります

* Oculus標準カメラ
* ヘッドセット周り
* コントローラー
* 位置トラッキング

そのため、Oculus Goや Rift、Gear VR等で開発する場合には、必要なUtilitiesです

## Oculus Utilities をプロジェクトに追加する

### [Oculus Utilities for Unity](https://developer.oculus.com/downloads/package/oculus-utilities-for-unity-5/) から `ovr_unity_utilities_1.26.zip` をダウンロードしてくる

<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/33505/0bed492d-96c3-a765-bd52-1021a6869064.png">
Unityの ver5.1〜 は、Oculus Goもサポートしている

### `OculusUtilities.unitypackage` をダブルクリックしてパッケージのインストールを進める

次のウィンドウが開くので、そのまま `import` する
<img width="250" src="https://qiita-image-store.s3.amazonaws.com/0/33505/e8cd7b37-8ee3-df51-ba1b-155d471b6c6a.jpeg">

進めていくと、古い Oculus Utilities があったらしいので、そのまま `YES`
<img width="300" src="https://qiita-image-store.s3.amazonaws.com/0/33505/59c68e57-213d-b323-7ac9-f784b8a682e6.png">

Unity の再起動を求められるので `Restart`
<img width="300" src="https://qiita-image-store.s3.amazonaws.com/0/33505/9189051f-642f-2497-7135-17f3bd1dfa24.png">

インストールされた！！！
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/33505/e5e5013e-2e3b-3051-c264-d5239683fa36.jpeg">

## カメラの準備

### [OVRCameraRig](https://developer.oculus.com/documentation/pcsdk/0.4/concepts/unity-details/#unity-prefabs-ovrcamerarig) を Hierarchy に追加する

Project にある `Assets > Oculus > VR > Prefabs` を選択し、 Prefabsにある `OVRCameraRig` を Hierarchy に移す
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/33505/7253df79-02c5-ae1f-1a94-014db14f8aa4.jpeg">

### Main Camera は消す

今回はOculus GoでのVR開発のため `OVRCameraRig` を使います、そのため `Main Camera` は不要です

## コントローラーの準備

HandAnchorに `TracedRemote` をセットする
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/33505/04b36941-9113-a46c-a37c-a5327a108c18.jpeg">

## done

コントローラー表示された
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/33505/26318d13-0a01-edd4-2cf4-83ed698e5c7d.png">

けど、ポインタでないな・・・
同ページ内にリンクを掲載する場合の「リンク省略」

## 結論
```
<a href="http://www.test.hoge/poko/piyo.html">テスト</a>
```
ページが同じサーバー内にある時は、http://www.test.hoge を省略することができます。

```
<a href="/poko/piyo.html">テスト</a>
```
## 参考
http://www.tohoho-web.com/wwwbeg5.htm
Typescript基本文法メモ


Typescriptに特徴的な部分のみ


## 連想配列

インデックスシグニチャでの型宣言
（シグネチャ=引数や返り値の組み合わせ）

```ts
let obj: { [key: string]: string; } = {
    "hoge": "ほげ",
    "huga": "ふが",
}
obj.piyo = "ぴよ";
```

型推論により、`hoge`と`huga`以外のプロパティを受け入れなくなっている

```ts
let obj = {
    "hoge": "ほげ",
    "huga": "ふが",
}
obj.piyo = "ぴよ"; // エラー
```



## 共用型

複数の型を宣言する。どれかに該当すれば良い

```ts
let hoge: string | boolean;
hoge = "hoge";
hoge = true;
hoge = 1; // エラー
```



## 省略可な引数

引数の最後に`?`をつける。オプション。

```ts
function say(serif?: string) {
    console.log(serif);
}
say();
```



## オーバーロード

```ts
// 最初に型チェックのためにシグニチャだけで関数を宣言する
function show(a: number): number;
function show(a: string, b: boolean): string;

// 上記に宣言したシグニチャの全てに対応する関数を実装する
function show(a: any, b: any): any {
  if (typeof a === "string") {
    return b ? "[true]" + a : "[false]" + a;
  }
  if(typeof a === "number"){
    return a;
  }
}

console.log(show("hoge", true)); // [true]hoge
console.log(show("hoge")); // [false]hoge
console.log(show(1)) // 1
```



## コンストラクタとプロパティの生成・初期化の省略記法

コンストラクタの引数に必ずアクセス修飾子をつけること

```ts
class Person{
  constructor(private _name: string, private _age: number){}
  show() {
    console.log(`名前：${this._name}　年齢：${this._age}`);
  }
}
```



## モジュール

内部モジュール = 名前空間
外部モジュール = ES2015のモジュール





## 構造的部分型

型の構造に着目。型を公称しなくても構造が一致すれば派生型とみなす。
（ある型のプロパティを持ってさえいればその型の派生とみなす）

```ts
interface Result{
    a: number;
    b: number;
}

function getTotal(result: Result): number {
    return result.a + result.b;
}

// a,bをnumberで持ってさえいれば、
// 他のプロパティcを持っていてもResult型とみなされる
var result = {
    a: 100,
    b: 50,
    c: "hello"
}

console.log(getTotal(result));
```



## 型としてのthis

this（自分自身）という型を返すことで、
メソッドチェーンが可能になる。

```ts
class MyClass{
  constructor(val: number){
    this._val = val;
  }
  get val(): number{
    return this._val;
  }
  add(val: number): this{
    this._val += val;
    return this;
  }
  minus(val: number): this{
    this._val -= val;
    return this;
  }
}

var myClass = new MyClass(10);
console.log(myClass.add(5).minus(3).val); // 12
```







> 参考
[速習TypeScript: altJSのデファクトスタンダートを素早く学ぶ！](https://www.amazon.co.jp/%E9%80%9F%E7%BF%92TypeScript-altJS%E3%81%AE%E3%83%87%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%80%E3%83%BC%E3%83%88%E3%82%92%E7%B4%A0%E6%97%A9%E3%81%8F%E5%AD%A6%E3%81%B6%EF%BC%81-%E9%80%9F%E7%BF%92%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%B1%B1%E7%94%B0%E7%A5%A5%E5%AF%9B-ebook/dp/B0733113NK)
[TypeScript入門 (全19回) ](https://dotinstall.com/lessons/basic_typescript)
svn で複数行コミットメッセージを行う方法(Linux)

svn commit で複数行コミットメッセージを行う方法

複数行のコミットメッセージを書きたい場合ってあると思います。

例えば以下のような改行を含んだコミットメッセージを入れたい場合

```
A対応

・aの修正
・bの修正
```

普通にそのまま入力して実行すると "A対応" のメッセージは入りますが、改行が含まれているので途中で実行されてしまい、後ろの空行、 "・aの修正"、 "・bの修正" の三行が別のコマンドとして実行されてしまいます。

そこで思いついた方法がバッククォートを使ってコマンド内でシェルを実行する方法です。


先にcommitmsg.txtを作っておきます。

```
$ vi commitmsg.txt
A対応

・aの修正
・bの修正
```

svnコマンドとバッククォートのシェルを組み合わせて実行

```
$ svn commit -m "`cat commitmsg.txt`" commitfile
```

コミットログも問題なさそうです。

```
$ svn log -r HEAD commitfile
------------------------------------------------------------------------
r59 | testuser | 2018-05-29 12:50:24 +0900 (火, 29  5月 2018) | 9 lines

A対応

・aの修正
・bの修正
------------------------------------------------------------------------
```
yank 後にそれをインデント


どうも yank (<kbd>C-y</kbd>) した後にそれをインデントする操作をよくやっているような気がしました。なのでそれら操作をくっつけてみました。とりあえず <kbd>C-y</kbd> キーにバインドして様子を見ていますが便利です。

```~/.emacs.d/init.el
;; yank 後にインデント
(defun my-yank-and-indent-it ()
  "Yank and indent it."
  (interactive)
  (yank)
  (save-excursion
    (exchange-point-and-mark)
    (indent-region (point) (mark))))
(global-set-key (kbd "C-M-y") 'yank)                ; yank を C-M-y に移して
(global-set-key (kbd "C-y") 'my-yank-and-indent-it) ; 普通の yank に割り当てられているキーをこれに

(with-eval-after-load 'make-mode
    (define-key makefile-mode-map (kbd "C-y") 'yank))
```

## 2018/6/4 追記
Makefile でインデントするとコマンド行先頭のタブがなくなってしまいます。なので make-mode 時の <kbd>C-y</kbd> は普通の yank に設定しました。

## 2021/3/30 追記
遅ればせながら[leaf.el](https://github.com/conao3/leaf.el)を使い始めました。ということでleafを使った設定を書いておきます。

```~/.emacs.d/init.el
(leaf yank-and-indent
  :init
  (defun yank-and-indent ()
    "Yank and indent it."
    (interactive)
    (yank)
    (save-excursion
      (exchange-point-and-mark)
      (indent-region (point) (mark))))
  :hook
  ((emacs-lisp-mode-hook ruby-mode-hook web-mode-hook) .
   (lambda ()
     (local-set-key (kbd "C-y") #'yank-and-indent)
     (local-set-key (kbd "C-M-y") #'yank))))
```

明示的に有効にするモードを指定するようにしました。:hookキーワードにモードフックのリストがありますのでそこで有効にしたいモードのフックを追加してください。関数名が変わっちゃってますがすいません、気分で変えました。
B-TREEインデックスの圧縮効果を試す（Oracle Database 12c Release 2)


# インデックスの圧縮
Oracle Databaseの標準インデックスフォーマットであるB-Treeインデックスにはッセグメントを圧縮する機能が提供されています。ここでは圧縮指定により、セグメント・サイズがどの程度削減されるかを検証します。
  Oracle Database 12cのインデックス圧縮指定はCREATE INDEX文に以下の指定を行います。

|CREATE INDEX文指定| 説明 |備考|
|:---|:---|:---|
|COMPRESS n| 接頭辞圧縮を行う n には列数を指定||
|COMPRESS ADVANCED LOW|高速なアクセスを維持しながら圧縮を行う|COMPATIBLE 12.1.0以上|
|COMPRESS ADVANCED HIGH|アクセス性能よりも圧縮率を優先する|COMPATIBLE 12.2.0以上|

Oracle Database 12c Release 2ではCOMPRESS ADVANCED HIGH句を指定できるようになりました。

# 検証方法
検証にはTPC-DSベンチマークのCUSTOMERテーブルを使いました。レコード数は100,000件です。
テーブル構造は以下の通りです。インデックスには一意な値が異なるC_CUSTOMER_SK列、C_CUSTOMER_ID列、C_FIRST_NAME列、
C_LAST_NAME列、C_BIRTH_YEAR列等を使いました。

|列名|データ型|DISTINCT値|
|:---|:---|---:|
| C_CUSTOMER_SK |           NUMBER(38)|100,000|
| C_CUSTOMER_ID |　            CHAR(16)|100,000|
| C_CURRENT_CDEMO_SK|       NUMBER(38)||
| C_CURRENT_HDEMO_SK |      NUMBER(38)||
| C_CURRENT_ADDR_SK   |     NUMBER(38)||
| C_FIRST_SHIPTO_DATE_SK |  NUMBER(38)||
| C_FIRST_SALES_DATE_SK |   NUMBER(38)||
| C_SALUTATION          |     CHAR(10)||
| C_FIRST_NAME           |    CHAR(20)|4,131|
| C_LAST_NAME           |     CHAR(30)|4,972|
| C_PREFERRED_CUST_FLAG |      CHAR(1)||
| C_BIRTH_DAY           |   NUMBER(38)||
| C_BIRTH_MONTH         |   NUMBER(38)|69|
| C_BIRTH_YEAR          |   NUMBER(38)||
| C_BIRTH_COUNTRY       | VARCHAR2(20)||
| C_LOGIN               |     CHAR(13)||
| C_EMAIL_ADDRESS       |     CHAR(50)||
| C_LAST_REVIEW_DATE    |     CHAR(10)||

検証には以下のSQL文を使いました。

```
SQL> CREATE INDEX インデックス名 ON CUSTOMER (列指定) 圧縮指定;
SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS('TPCDS', 'インデックス名');
SQL> SELECT blocks FROM user_segments WHERE segment_name='インデックス名';
```

# 検証結果
B*Treeインデックスの圧縮効果は以下の通りです。

## C_CUSTOMER_SK列
NUMBER型で、一意のデータが格納された列です。一意データなので接頭辞圧縮を指定するとかえってブロック数が増加しています。
一方でCOMPRESS ADVANCED HIGHを指定すると大幅にブロック・サイズが削減できています。

|圧縮指定|ブロック数|
|:---|---:|
|圧縮無|128|
|COMPRESS|192|
|COMPRESS ADVANCED LOW|128|
|COMPRESS ADVANCED HIGH|56|

## C_LAST_NAME列
CHAR(30)型で、データの種類は比較的多いのですが、同じデータもある列です。圧縮効果はありますが、どの圧縮方法でも同じデータ量になっています。

|圧縮指定|ブロック数|
|:---|---:|
|圧縮無|320|
|COMPRESS|128|
|COMPRESS ADVANCED LOW|128|
|COMPRESS ADVANCED HIGH|128|

## C_BIRTH_YEAR列
NUMBER型でデータ種類が少なく、インデックスが効きにくい列です。COMPRESS ADVANCED HIGH指定以外では圧縮効果がない結果になっています。

|圧縮指定|ブロック数|
|:---|---:|
|圧縮無|128|
|COMPRESS|128|
|COMPRESS ADVANCED LOW|128|
|COMPRESS ADVANCED HIGH|44|

## C_FIRST_NAME列とC_LAST_NAME列の組み合わせ
文字列型の複合インデックスの圧縮例です。通常の圧縮でも効果がありますが、COMPRESS ADVANCED HIGHを指定すると大幅に縮小できています。

|圧縮指定|ブロック数|
|:---|---:|
|圧縮無|448|
|COMPRESS 1|320|
|COMPRESS 2|448|
|COMPRESS ADVANCED LOW|320|
|COMPRESS ADVANCED HIGH|128|

## C_CUSTOMER_SK列とC_CUSTOMER_ID列の組み合わせ
NUMBER型で一意なデータの複合インデックスの圧縮例です。通常の圧縮では効果が無く、COMPRESS ADVANCED HIGHを指定する縮小できています。

|圧縮指定|ブロック数|
|:---|---:|
|圧縮無|256|
|COMPRESS 1|320|
|COMPRESS 2|320|
|COMPRESS ADVANCED LOW|256|
|COMPRESS ADVANCED HIGH|128|

上記の結果から、Oracle Database 12c Release 2の新機能であるCOMPRESS ADVANCED HIGH指定は多くの場合、圧縮効果が高いことがわかります。
一方で、マニュアルによるとこの指定はインデックスへのアクセスは低速になると記述があるため、あまり参照されない過去データ等で利用が推奨されるのではないかと思われます。
s3test使用


## clone the project
```
git clone git@github.com:joke-lee/s3-tests.git
```
## create the s3test.conf
```
#cat s3test.conf
[DEFAULT]
port = 80
host = eos-beijing-1.cmecloud.cn
is_secure = no

[fixtures]
bucket prefix = {random}

[s3 main]
user_id = s3test1
display_name = s3test1
access_key = s3test1
secret_key = s3test1
api_name = beijing2 #rgw_zonegroup

[s3 alt]
user_id = s3test2
display_name = s3test2
access_key = s3test2
secret_key = s3test2
email = s3test2@ceph.com
api_name = beijing2 #rgw_zonegroup


#cat s3test.https.conf
[DEFAULT]
port = 443
host = eos-beijing-1.cmecloud.cn
is_secure = yes

[fixtures]
bucket prefix = {random}

[s3 main]
user_id = s3test1
display_name = s3test1
access_key = s3test1
secret_key = s3test1
api_name = beijing2 #rgw_zonegroup

[s3 alt]
user_id = s3test2
display_name = s3test2
access_key = s3test2
secret_key = s3test2
email = s3test2@ceph.com
api_name = beijing2 #rgw_zonegroup
```

## RUN
```
#v2 signature
S3TEST_CONF=./s3test.conf   ./virtualenv/bin/nosetests s3tests.functional.test_s3  -a '!fails_on_aws,!fails_on_rgw,!encryption,!tagging,!bucket-policy,!fails_on_rgw_jewel'  -v --with-html --html-report=/var/www/html/index.html --html-report-template=virtualenv/lib/python2.7/site-packages/nose_html_reporting/templates/report2.jinja2

#v4 signature
#setup dns
S3_USE_SIGV4=1 S3TEST_CONF=./s3test.conf   ./virtualenv/bin/nosetests s3tests.functional.test_s3  -a '!fails_on_aws,!fails_on_rgw,!encryption,!tagging,!bucket-policy,!fails_on_rgw_jewel'  -v --with-html --html-report=/var/www/html/index.html --html-report-template=virtualenv/lib/python2.7/site-packages/nose_html_reporting/templates/report2.jinja2

```

#### setup dns
```
#rgw ip 127.0.0.1
#rgw_dns_name = eos-beijing-1.cmecloud.cn
#rgw_dns_s3website_name = eos-website-beijing-1.cmecloud.cn
#rgw enable static website = true

yum -y install dnsmasq
cat > /etc/dnsmasq.conf << EOF
resolv-file=/etc/resolv.dnsmasq.conf
strict-order
resolv-file=/etc/dnsmasq.d/resolv.dnsmasq.conf
addn-hosts=/etc/dnsmasq.d/dnsmasq.hosts
address=/eos-beijing-1.cmecloud.cn/127.0.0.1
address=/*.eos-beijing-1.cmecloud.cn/127.0.0.1
address=/eos-website-beijing-1.cmecloud.cn/127.0.0.1
address=/*.eos-website-beijing-1.cmecloud.cn/127.0.0.1
EOF

systemctl restart dnsmasq
nslookup  eos-beijing-1.cmecloud.cn
```

## GET RESULT
```
cd /var/www/html/
python -m SimpleHTTPServer 80

# open chrome and visit http://localhost/index.html
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/253293/f07ad7da-a310-a3c4-47e5-b2bac47644a3.png)
自動で投稿を締め切るGoogleフォームの作成

# はじめに
Googleフォームは無料で使えるアンケートフォームで、何かしらの情報を不特定多数から受け付ける時に非常に気軽にかつ、柔軟に利用できて大変便利です。
ただ、フォームの受付開始、終了については設定画面から手動で行う必要があるため、例えば今回例に上げるような、数量制限のある予約フォームなどを作る場合、標準機能だけで対応するには、定期的に回答を目視で確認し、ある程度余裕を持った所で人間が停止の作業を行う必要がありました。

そこで銀の弾丸、GoogleAppsScriptの登場です。

# 要件

1. 数量は1～5の範囲で選択入力される。
2. 上限数量はフォーム回答スプレッドの別シートに設定値を登録する。
3. `上限-数量計` が回答できる数量の上限を下回ったら、フォームを閉じる
4. フォームの再開は手動で行う。

# 仕様の確認

GASの日本語仕様情報は陳腐化が激しく、また検索スキルも求められます。
素直にオフィシャルのリファレンスを読みます。
https://developers.google.com/apps-script/reference/forms/form

フォームの受付け切り替えは `setAcceptingResponses` にBool値を渡す事で実現できるとわかりました。

# 実装

まずはスプレッドの準備です。
今回はスクリプトをいじれなくても上限の変更や制限の解除ができるよう、スプレッド側に変数を入れることでフォームの有効無効を判断します。
また、下準備として各フォーム、スプレッドのIDを控えておきましょう。

## サンプルフォームの項目

* 氏名
* 購入数量

## スプレッドシート

以下各シートの内容例です。

### シート[フォームの回答1]

| 氏名       |       購入数量 |
|:-----------------|------------------:|
| 佐藤太郎             |              1 |
| 佐藤花子           |            3 |

### シート[設定]


| 現在の受注数       |      受注制限数 |       残 |数量上限|受注制限|
|:-----------------|------------------:|--:|--:|--:|
| `=SUM('フォームの回答 1'!B:B)` | 10        | `=B2-A2` | 5| `=IF(C2<D2,FALSE,TRUE)` |

この設定シートのE2セル（受注制限セル）がFALSEになったらフォームが閉じるようにします。

### スクリプトの実装

諸々の解説は抜きにして、実装内容です。
今回はフォームが閉じたことがわかるようにメールの送信もおまけにつけています。

```javascript
/*
 状態の取得
*/
function orderLimitCheck(){
  // 回答スプレッドの数量制限シートを開く
  var tgtSpread = SpreadsheetApp.openById('スプレッドのID');
  var tgtSheet = tgtSpread.getSheetByName('設定');
  // 受注制限状況を取得する
  var acceptToggle = tgtSheet.getRange(2,5).getValue();
  //フォームの状態を切り替える
  formOpenClose(acceptToggle);
  }

/*
 フォームの受付けを開始する。
 toggle : フォームの開始停止の切り替え、Bool値
*/
function formOpenClose(toggle){
  // フォームIDを指定してフォームを選択
  var tgtForm = FormApp.openById('フォームのID');
  // 切り替え要求のBoolと異なる状態であれば
  // toggleの状態にフォームを切り替える
  if(tgtForm.isAcceptingResponses()!=toggle){
    // フォームの受付け状態を切り替える。
    tgtForm.setAcceptingResponses(toggle);
    var logText = "受注フォームの受付け状態を"+toggle+"に切り替えました。";
    Logger.log(logText);
    sendLogMail("フォームの受付状況変更通知",logText);
  }
}

/*
  ログメールの送信
*/
function sendLogMail(title,body){
  // 送信先
  var to =  ['通知先メールアドレス１','通知先メールアドレス２']
  GmailApp.sendEmail(to,title,body);
}

```

### トリガの設定

![2018-05-29_14h08_44.png](https://qiita-image-store.s3.amazonaws.com/0/89777/0a7fdf61-0368-3265-b3f3-fe67a9e6633c.png)

GoogleAppsScriptのトリガには、`スプレッドシートからフォーム送信時` という強力な条件があります。
このトリガで上記スクリプトを実行することで、フォーム回答のたびに状態確認が走り、上限に達した瞬間にフォームを閉じることができます。

# 備考

トリガによってフォームが閉じられると、その時点でフォームを開いていたとしても、回答が送信されないようになっていて、回答が殺到した場合にもきっちり閉じてくれます。
やるね、GoogleAppsScript
[Node.js] OpenCVで物体の特徴点を抽出、マッチングさせてみた

##はじめに
大学の研究でOpenCVを使う機会があり、調べたところnpm moduleが出ていたので遊んでみた。
今回は、二枚の画像から特徴点を抽出し、マッチングさせていきます。

##OpenCVとは
　OpenCV（正式名称： Open Source Computer Vision Library）は、オープンソースのコンピューター・ビジョン・ライブラリです。コンピューターで画像や動画を処理するのに必要な、さまざま機能が実装されており、BSDライセンスで配布されていることから学術用途だけでなく商用目的でも利用できます。加えて、マルチプラットフォーム対応されているため、幅広い場面で利用されていることが特徴です。

##環境構築
1.モジュールをインストールする。
　```npm install --save opencv4nodejs ```
これで開発環境は整いました！

##使用例
```javascript:sample.js
const cv = require('opencv4nodejs');

const matchFeatures = ({ img1, img2, detector, matchFunc }) => {

  const keyPoints1 = detector.detect(img1);
  const keyPoints2 = detector.detect(img2);

  const descriptors1 = detector.compute(img1, keyPoints1);
  const descriptors2 = detector.compute(img2, keyPoints2);

  const matches = matchFunc(descriptors1, descriptors2);

  const bestN = 40;
  const bestMatches = matches.sort(
    (match1, match2) => match1.distance - match2.distance
  ).slice(0, bestN);

  return cv.drawMatches(
    img1,
    img2,
    keyPoints1,
    keyPoints2,
    bestMatches
  );
};

const img1 = cv.imread('画像のパス');
const img2 = cv.imread('画像のパス');

//SIFTで特徴点を抽出
if (cv.xmodules.xfeatures2d) {
  const siftMatchesImg = matchFeatures({
    img1,
    img2,
    detector: new cv.SIFTDetector({ nFeatures: 2000 }),
    matchFunc: cv.matchFlannBased
  });
  cv.imshowWait('SIFT matches', siftMatchesImg);
} else {
  console.log('skipping SIFT matches');
}

//ORBで特徴点を抽出
const orbMatchesImg = matchFeatures({
  img1,
  img2,
  detector: new cv.ORBDetector(),
  matchFunc: cv.matchBruteForceHamming
});
cv.imshowWait('ORB matches', orbMatchesImg);
```
一応Githubのリポジトリを貼っておきます。
https://github.com/toshi1127/node_openCV.git
##実行結果
####SIFTによる、キーポイント検出とマッチング
![match.png](https://qiita-image-store.s3.amazonaws.com/0/218201/8e938674-69e7-792b-900e-5d53c2ced45d.png)
####ORBによる、キーポイント検出とマッチング
![match.png](https://qiita-image-store.s3.amazonaws.com/0/218201/e46c4669-cc8e-19ec-7429-8f1d1679d6df.png)
Jinja2 テンプレートエンジンにおける nan/None の空白化や数値カンマ区切りといった編集方法

## はじめに

[前回](https://qiita.com/ynakayama/items/936da3aa8731959f7fda)の続きで [Flask](http://flask.pocoo.org/) の話です。

データ分析のみならず、[データセットの加工に便利](https://qiita.com/ynakayama/items/2769bc92bb71ebf23be6)なため、バックで [pandas](https://pandas.pydata.org/) を採用しているケースを想定しています。

Flask はテンプレートエンジンとして [Jinja2](http://jinja.pocoo.org/docs/2.10/) を採用しています。このとき pandas のデータフレームのほうで欠損値を持っていることって結構あるんじゃないかと思います。

データフレームの欠損値をそのまま Jinja2 でウェブページに出してしまうと恐ろしいことに None だとか nan と表示されてしまいます。事前に data.fillna(0) などで欠損値を埋めればいいのですが、今回はテンプレートエンジン側での回避方法を説明します。


## テンプレートで欠損値を表示しない

### 数値型・欠損値 の場合

```jinja
{{ if var == var else '' }}
```

数値型のデータに欠損値がある場合、そのまま表示させると nan (Not A Number) が表示されます。そこで nan 同士を比較すると False となる性質を利用し、変数同士を比較して空白に置き換えれば OK です。

### 文字列型・欠損値 の場合

```jinja
{{ if var != None else '' }}
```

文字列が None でないかどうか比較し None であれば空白を表示します。

## 空白以外に置き換える

たとえば欠損値であれば *** にしたい場合。

```jinja
{{ if var != None else '***' }}
```

置き換えたい文字列を指定します。

## その他のテクニック

これと組み合せて数値型をカンマ区切りするといった編集もできます。

### 小数点有り数値型をカンマ区切りにする

```jinja
{{ '{:,}'.format(var) }}
```

### 小数点無し（整数）の数値型をカンマ区切りにする

```jinja
{{ '{:,.0f}'.format(var) }}
```

## 組み合わせ

これを組み合わせるとこうなります。

例：小数点無し（整数）の数値型が欠損値 (nan) で無い場合はカンマ区切りにする。欠損値の場合は *** を表示する。

```jinja
{{ '{:,.0f}'.format(var) if var == var else '***' }}
```

Jinja2 のマクロを使うといいかもしれないですね。

以上です。
TypeScriptの翻訳機が知らないような機能を使う時は、アンビエント宣言をしておく

#症状

##ブラウザが実行できる機能をTypeScriptが知らないケース

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「TypeScriptさん、あなたはTextEncoderを知らないかも知らないけど僕の環境では動くんですよ！あなたが知らないからってエラー吐くのやめてもらえます？？」って、TypeScriptではどう書いたらいいんでしょうか。</p>&mdash; 岡竜之介 (@agajo) <a href="https://twitter.com/agajo/status/1000668511461560320?ref_src=twsrc%5Etfw">2018年5月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こちら、僕の最近のツイートですけれども。

例えば、TypeScriptで次のようなコードを書くと、

```typescript
let encoder:any = new TextEncoder()
```

```typescript
navigator.clipboard.writeText(this.modified_output);
```

これらのコードがJavaScriptに翻訳される際に、次のようなエラーがでることがあります。

```
Cannot find name 'TextEncoder'.
```

```
Property 'clipboard' does not exist on type 'Navigator'.
```

`TextEncoder`や`Navigator`の部分は、場合によって変わってきます。

これらのエラーメッセージは、どちらも「そんなものはない。」と言ってきているわけですね。

でもこれ、TypeScriptの翻訳マシンが`TextEncoder`や`navigator.clipboard`を知らないだけで、このエラーを無視して翻訳を実行してしまえば、ブラウザ上ではきちんと動くんですよ。


##htmlから他のjsファイルを読み込む予定があるケース

他にも、Google Analyticsの`ga`関数を使う場合や、jQueryの`$`関数を使う場合など、

それらの関数を定義している外部jsファイルを、html上で先に読み込むつもりでいる場合なんかも、

TypeScriptを翻訳する瞬間にはその外部jsファイルがないわけですから、

TypeScript翻訳機からしてみれば「そんなの知らないよ！」ということになって、同様のエラーが出ます。

#アンビエント宣言

対処法としては、「このコードではこういう機能を使います。翻訳機さんは知らないだろうけど、別の所でちゃんと定義される予定だから、エラーは出さないでね。」

という意味で「アンビエント宣言」というものを書いておけば良いです。

クラス定義内ではなく、.tsファイルの最初の方でアンビエント宣言を書いておきましょう。

書き方は、「行頭に`declare`をつけて、変数(関数、クラスなど)を宣言する」です。


僕は今の所、インポート文の後に書くようにしてます。

例えばこんな感じ。

```typescript
declare function TextEncoder():void;
declare var navigator:any;
declare let ga: any;
```


ちなみに英単語 "ambient" は形容詞で、「包囲した」「取り巻く」「周囲の」「周囲を取り巻く」といった意味です。

「こういうの名前の関数を使うけど、定義はこのファイルの外(周囲)にあるから、ここには出てこないよ。」という雰囲気ですかね。


アンビエント宣言は変数や関数に限らず、クラスやモジュールに対してもできます。

また、`.d.ts`という拡張子のファイルに宣言だけをまとめて書いておくことができるそうです。

#参考サイト

https://docs.solab.jp/typescript/ambient/declaration/
Windows7で動画キャプチャー


## はじめに
Windows10で動画キャプチャーするには、<kbd>Win+G</kbd>でキャプチャーのツールバーが表示され動画キャプチャーができます。
Windows7ではこの機能がありません。
Qiitaへ投稿するための動画キャプチャーのやりかたの備忘録を投稿します。
## アプリ
[ロイロゲームレコーダー](http://loilo.tv/jp/product/game_recorder)
## 動画キャプチャー
`Internet Explorerの動画キャプチャーを想定した手順です。`
ロイロイゲームレコーダーインストール後
### 録画するゲームをクリック
![TS_020.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/dde48d9a-2c47-afb1-1208-d769e57d9314.jpeg)
### Internet Explorerを選択
![TS_021.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/d2bf5a60-1e36-997b-95b1-9dd64cee8b8d.jpeg)
### 設定ボタンをクリック
![TS_022.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/4a0110fc-6756-2df7-10c7-779c50f57c5e.jpeg)
### 解像度を720p、録画モードをWindowsモードに設定
![TS_024.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/5558a277-82a0-bc98-dfbf-b920683ded39.jpeg)
### 録画ボタンをクリック
![TS_023.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/de57e0ab-ed05-7c4c-5298-72df8bbb77c5.jpeg)
この状態でInternet Explorerを操作後、録画ボタンを再び押下して録画を停止します。
録画はaviで記録されるため、aviをgifへ変換します。
## AVIからGIF変換
オンライン変換の[ACONVERT](https://www.aconvert.com/jp/video/mp4-to-gif/)でgifファイルを作成します。
### 変換元のAVIファイルを参照ボタンで選択します。
![TS_025.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/96d8b01d-d2c4-2e33-36fd-e530a2b91eb3.jpeg)
### ファイルを選択後、いますぐ変換ボタンをクリック
![TS_026.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/016d11fa-c209-9343-477e-0c010cae8132.jpeg)
### Conversion Failedになることがあります。
![TS_027.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/15b2e52b-52f3-a45b-b4fe-6e4dfd09fbf1.jpeg)
ブラウザーの違うタブをクリックして別のページを表示するとなるようです。
変換完了までそっとしておきます。めけずにもう一度実行すると変換できます。xv2xz-ggpfr.gifを右クリックで対象をファイルで保存でローカルに保存してQiitaへアップします。

## 動画キャプチャーサンプル
![bn792-9ouyq.gif](https://qiita-image-store.s3.amazonaws.com/0/239597/8c78d83a-84df-a681-ef5c-2795bc8cfb08.gif)

以上、おそまつ
ActionCableとVue.jsでチャットを爆速実装


鹿児島大学でアプリ開発サークルをやっている[@gakutomo](https://twitter.com/gakutomo)です。
今回はVue.jsを使ったWebアプリケーションにチャット機能を組み込みたかったのでRailsのActionCableを使って爆速実装してみました :rocket:


# ActionCableとは
WebSocketを扱うRails5の新機能
チャットのようなリアルタイムにデータ更新するアプリが作れる

## こういうやつ
![chat (1).gif](https://qiita-image-store.s3.amazonaws.com/0/201336/eb655bdd-5dd8-da96-6969-b188b41d9ad4.gif)


# 動作環境
## クライアント側

- macOS High Sierra
- Google Chrome
- Vue.js

## サーバ側

- CentOS 7
- Rails 5.2


# サーバ側の実装手順
Railsアプリケーションは作成済みとします
## チャンネルの作成

```bash:console
rails g channel message
```

## チャンネルの設定

```ruby:app/channels/message_channel.rb
class MessageChannel < ApplicationCable::Channel
  # チャンネル接続時に呼ばれる
  def subscribed
    stream_from "message_channel"
  end

  # メッセージをブロードキャストするためのアクション
  def speak(data)
    ActionCable.server.broadcast 'message_channel', message: data['message']
  end
end
```

## ルーティングを追加

```ruby:config/route.rb
Rails.application.routes.draw do
  # 以下を追記
  mount ActionCable.server => '/cable'
end
```

# クライアント側の実装手順
Vue.jsで実装します。RailsのWebPackerはうまくいかなかったので、ローカルでWebPack使って開発してます。

まず必要なパッケージをインストールします。

```bash:console
npm install actioncable
```

main.jsをエントリーポイントとして進めていきます

```js:main.js
import Vue from 'vue';
import ActionCable from 'actioncable';
import Chat from './chat.vue';

const cable = ActionCable.createConsumer('ws:hoge.com:3000/cable');
Vue.prototype.$cable = cable;

new Vue({
  components: {
    Chat,
  template: '<Chat/>',
  },
}).$mount('#app');
```

## 通信部分の実装

```vuejs:chat.vue
<template>
  <div>
    <input v-model="msgBox" placeholder="message here"></input>
    <button v-if="messageChannel" @click="speak">送信</button>
  </div>
</template>

<script>
export default {
data() {
  return {
    msgBox: "",
    messages: [],
    messageChannel: null,
  };
},
created() {
  this.messageChannel = this.$cable.subscriptions.create( "MessageChannel",{
    received: (data) => {
      this.messages.push(data)
    },
  })
},
methods: {
  speak() {
    this.messageChannel.perform('speak', { 
      message: msgBox, 
    });
  },
},
}
</script>
```


# ハマりどころ
- スマホからだと以下の設定をしないと接続できなかった
- httpsからのWebSocketはwss://にしないといけない  
 
```ruby:config/application.rb
ActionCable.server.config.disable_request_forgery_protection = true
config.action_cable.url = 'wss://hogehoge.com/cable'
```

# 参考
[Rails 5 + ActionCableで作る！シンプルなチャットアプリ](https://qiita.com/jnchito/items/aec75fab42804287d71b)
[railsとvueでリアルタイムな注文システムを作ってみた](https://qiita.com/guri120/items/28d1e0755f879f9562e6)
[ActionCable の README を読んでチャットアプリを作ってみた](https://qiita.com/pekepek/items/3cc572615db7910d5fdb)
[フロントエンドで ActionCable を npm 経由で使う](https://qiita.com/mizchi/items/84ec7c0e5631d647d67a)
[Action Cable でプログレスバーを更新する](https://qiita.com/QUANON/items/0ba35cd0eb5d720f4237)
UXIFY Japan 2018 で講演しました：UIと合意形成

<p>4月27日に行われたUXIFY Japanで久しぶりにUXがらみの講演をして来ました。</p>
<p><a href="http://uxify.net/as/">Home – UXIFY</a></p>
<p>こちらのカンファレンスは、弊社<a href="https://www.infragistics.com/">インフラジスティックス</a>がワールドワイドで行なっているUXデザインにフォーカスしたカンファレンスで、今回初めて日本での開催をすることができました。</p>
<p>当日お願いしたスピーカーの皆さんは、参加者にはもうお伝えした通り前職の<a href="http://www.2ndfactory.com/">セカンドファクトリー</a>様つながりの現役・OGの皆さんです。皆さんそれぞれ全く違う観点でお話いただけて、とてもよいディスカッションの始まりになったと思います。お願いした私自身も感無量でした。</p>

<p>私自身は「UIと合意形成」というタイトルで、あえてはっきりした対象であるUIに絞ってお話をしました。<a href="https://infragisticsinc297-my.sharepoint.com/:b:/g/personal/dikehara_infragistics_com/EZbKBcnWFAtKo5UxYV3UPcEBb_WYPo3nYb_ghDo0zwiKhg?e=2gSe6m">資料はこちらから</a>どうぞ。PDFになります。動画はYouTubeにあります。</p>
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/119694/6ddffe9c-1083-08f8-0fa2-2312ce2a4332.png)](http://www.youtube.com/embed/I60Czzqv3sI)
<a href="https://youtube.com/watch?v=I60Czzqv3sI">UXify 2018 Japan - セッション4: UIと合意形成</a>
[2018/6/6追記：**国内のUX専門家が集結した「UXify 2018 Japan」レポート【前編】**](http://uxmilk.jp/72903)
[2018/6/7追記：**国内のUX専門家が集結した「UXify 2018 Japan」レポート【後編】**](http://uxmilk.jp/72927)


お時間のあるときにぜひ見ていただけると嬉しいです。当日のTwitterでも呟いたのでですが：
[**久しぶりにUXやUIに関する話をしました。動画も公開できるんじゃないかと思います。いきなり:勇者のパーティ▪プロマネ＝僧侶▪デベロッパー＝戦士▪デザイナー＝魔法使いとか出てきて戸惑うかもですが、新旧織り交ぜた頑張って整理…**](https://twitter.com/kenazuma/status/994091221286088704)
<p>プロジェクトチームをRPGのパーティに例えてお話をさせていただきました。カルチャーの違うロールの間で、しっかりしたコミュニケーションと共通のゴールを持つことが大事です。</p><p>また、対象になるUIに関する構造分解についての話もさせていただきました。途中で紹介しているプロセスは、いつもコンサルテーションなどでも使っているものになります。</p><p>当日のアンケートからは好意的なご意見を多数いただきました。参加いただきました皆さま、本当にありがとうございます。動画をご覧になった方からも、ぜひ感想など聞かせていただけると嬉しいです。</p>
TypeScript Sampleをやってみるその５


## はじめに
Jquery(ジェイクエリー)は[John Resig](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%A7%E3%83%B3%E3%83%BB%E3%83%AC%E3%82%B7%E3%82%B0)が開発したJavaScriptライブラリです。
JavaScriptの冗長なコードを簡便にするためのライブラリ群です。
もちろんTypeScriptからも利用可能です。
MicrosoftはJqueryを自社のスクリプトの標準としました。
このサンプルではブラウザに星を表示させ、垂直スクロールバーの操作によって星々が遠近感を伴って上下するイベントをJqueryを利用して実現しています。htmlに10行足らずのコーディングで実現している美しいコードの備忘録を投稿します。


## 前提

* [Visual Studio Code](https://code.visualstudio.com/download)がインストール済み
* [Node.js/npm](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)がインストール済み
* gitから[Sampleをダウンロードして](https://github.com/Microsoft/TypeScriptSamples/archive/master.zip)任意のディレクトリに解凍済み
* View In Browserがインストール済み(Market Placeより)
* OSはWindows7/10を想定

## サンプル Jquery
ブラウザへJqueryライブラリを利用しスクロール操作に合わせ星々の垂直描画を行うサンプル。

## ファイル構成
|パス|ファイル名|説明|
|:--|:--|:--| 
|.|package-lock.json|パッケージ依存関係ロックファイル(json)|
|.|package.json|パッケージ定義および依存関係ファイル(json)|
|.|parallax.html|ブラウザparallax出力のhtml|
|.|parallax.js|parallax.tsのコンパイルにて作成されたJavaScriptファイル|
|.|parallax.js.map|parallax.tsのコンパイルにて作成されたmaptファイル|
|.|parallax.ts|parallaxのTypeScriptファイル|
|.|README.md|このサンプルの説明と使用方法|
|.|tsconfig.json|TypeScriptのコンパイルコンフィグファイル|
※ parallax :　パララックス「視差」スクロール操作による視覚的エフェクト

## クラス図
![TS_019.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/b7f59a41-8821-9168-284c-b99c9364bf2c.jpeg)

## 実行
```
cd ./jquery
npm install
tsc
```
`parallax.htmlをエディターで表示`<kbd>Ctrl+F1</kbd> 

## 結果
![bn792-9ouyq.gif](https://qiita-image-store.s3.amazonaws.com/0/239597/dccdacce-2e06-c3c8-a9ec-00b40b76ba26.gif)
スクロールバー操作に従って、星が移動するように見えます。

## ポイント
どうしてこんなにシンプルなコード書けるのか？
その秘密は、node_modules\@types\jquery\index.d.tsにあります。
Jqueryで使用する型やInterfaceの定義ファイルを以下のコマンドでインストールできます。これでJqueryのすべてのメンバーをTypeScriptから利用可能になります。

```
npm install -D @types/jquery
```
あたかもTypeScriptのメンバーのようにJqueryのライブラリを利用することできます。
もう一つのインストール方法として、package.jsonに記述してインストールすることも可能です。

```json:package.json抜粋 
 "dependencies": {
    "jquery": "^3.1.1"
  },
  "devDependencies": {
    "@types/jquery": "^2.0.40",
    "typescript": "^2.1.6"
  },
```
上記 `package.json` を `npm install` コマンドでインストールすると、node_moduleには以下のディレクトリがインストールされます。
@typesディレクトリのサブディレクトリにjqueryがインストールされます。
※@typeのみサブディレクトリ表示

```
node_modules/
├───.bin/
├───@types
│   └───jquery
├───jquery/
└───typescrip/t
```
Jqueryを利用するには、mode_moduleに以下の二つをインストール

* @Types/jquery
* Jquery

## ノート
htmlのJqueryの基本構造をメモしておきます。
![TS_028.jpg](https://qiita-image-store.s3.amazonaws.com/0/239597/2a45e9bb-91bb-a8bc-c8a5-61bae1ea547e.jpeg)

## まとめ
JavaScript1の冗長なコーディングからの脱却を実現したJqueryの開発者がロチェスター工科大学の革新殿堂入りしたのも納得です。これから導かれるブラウジングスクリプトの未来志向は明らかにJavaScriptから進化を意味しています。最終的な完成がTypeScriptになるのかはわかりません。たぶんたった一人の革新的な発想を持つ開発者によってさらなる劇的な革命の予感を禁じえません。

以上、おそまつ
AIの時代になぜ英語を勉強しなければいけないのか

<p>前回英語について書いてからずいぶん間が開いてしまいましたが、今回は何故英語が必要になるのかについて書きます。</p>

["A-Go" (English) as a tool for developers](https://www.slideshare.net/kenazuma/ago-english-as-a-tool-for-developers)

<p>こちらのスライドの6ページ目以後を見てください。おそらく、程なくして実用的な音声認識 + 自動翻訳はかなりの精度（個人的には60%くらいのレベルに数年で到達するように思います。）を実現してくれるでしょう。そうなると、もう英語を勉強する必要はないんじゃないか、と思うのも無理はないと思います。それでも、私は今英語を勉強することに意味があると思っています。</p>
# 文化的背景・考え方を知るための英語
<p>ある文化や思考の過程は、長い年月をかけて言語と相互作用を持って練り込まれていて、言語を学ぶことで相手の背景にある基本的な考え方を知ることができます。</p>
<p>例えば、日本語と英語の間でよくある「Yes/No」問題というものがあります。ここに座ってもいいですか？= "Do you mind if I sit here?" と聞かれた場合、問題ない、肯定したいという気持ちが "Yes" という単語と紐づいて Yes と答えてしまいそうになりますが、座っていいのであれば No, please となります。</p>
<p>多くのケースで、日本語でのはい・いいえ、は自分を含む少し広い環境や状況に対して肯定・否定をすることが多く、英語の Yes / No においては個人が自分がどう考えるのかを表現することに使われることが多いです。このような単純な例以外にも、単語の成り立ちや慣用句などからは文化的な背景を読み取れることも多く、単純に「翻訳」することにあまり意味がなかったり、うまく意味が通らないものもあります。映画の字幕に違和感を覚えたりするのはそういった違いが原因になっていることも多いです。相手をよりよく知るためにも、言語を学ぶことはよい気付きを与えてくれます。</p>
# 「論理コミュニケーション養成ギプス」としての英語
<p>少し自分の業界に近い話をします。落合陽一さんの著書「これからの世界を作る仲間たちへ」で、落合先生はこう書かれています。</p>
<p><em><strong>「大事なのは英語力ではありません 。たとえばコンピュ ータが翻訳しやすい論理的な言葉遣いが母語でちゃんとできること 、つまりそのような母語の論理的言語能力 、考えを明確に伝える能力が高いことのほうが 、はるかに重要です 。」</strong></em></p>
<p>これには完全に同意です。最近Amazon Echoに話しかける時にすら感じますが、はっきりと順序と論理が通った発言をすることは、「コンピュータが翻訳しやすい論理的な言葉使い」をするのにとても大事だと思います。一方、日本で日本語を使いながら曖昧な表現とハイコンテクスト（相手との間に暗黙的な文脈の相互理解があること）な状態に「浸かって」生きてきた我々にとって、日本語で曖昧さを排除することがとても難しくなっています。</p>

<p>社内でミーティングをする場合にも、日本語をベースにしていると代名詞やなんとなくの表現が多くなって来ることに気づきます。一方、英語で話すことを矯正すると、そもそも曖昧な表現を知らない（！）し、英語の構造上結論を先延ばしにもしにくいので、英語が「論理コミュニケーション養成ギプス」のような働きをしてくれます。これは、日本における慣習を説明しなければいけないようなケースでも同じで、大会社が「うちはこういう会社だから」みたいな話をしたとしても、「こういう」とは一体どういう状態なのか、しっかり説明できる状態でなければ英語で伝えようもありません。</p>
<p>実は、日本語をベースとしたコミュニケーションであったとしてもうやむやにできないことが、なんとなく共有した状況や雰囲気で曖昧になってしまうことは多々あります。この状態だと、弊社の本社メンバーや他の拠点のメンバーには伝えようがありません。コンピュータに翻訳しやすい状態とは、曖昧さを排除した状態だと理解しています。その曖昧さすらも学習させる可能性がありますが、そうだとしても一度その曖昧な状態を通訳して教えているはずです。私としては、英語をそのようなものとして捉えています。</p>
<p>また、伝える相手が人間だけでなくコンピュータだという前提に立った時に、その論理の組み立て順は「コンピュータを作っている人の論理順序に従っている」ことが多くなるでしょう。そう考えた時にも、現在のコンピュータの大半が英語圏からやってきたものであり、その論理構造や順序をとらえることが重要になってくると考えています。 </p>
# お金に変わるものとしての英語
<p> また、今のところ英語をある程度使える（少なくとも英語に抵抗感がなく、今すぐに喋れないとしても短期間に本気で習得することを決めている、というレベルで良い）ことによって、簡単に年収が上がってしまう事実もあります。昨今の「働き方改革」をしっかり意識している会社（というよりそれが当たり前である会社）は、英語を業務に必要としていることが多いと思います。私自身も採用をしているのでわかりますが、英語を条件にした途端に人材の母集団は急激に減ります。この状況があとどれくらい続くかどうかはわかりませんが、少なくとも短期的に勉強する対象としてはリーズナブルではないかと思います。</p>

<p>文化的な認識の違い、論理構造や順序の違い、70億人相手にする時に相手が私たちに合わせてくれるか、あるいはこちらが相手に合わせにいくかは自分の気持ち次第だと思っています。</p>


<p>私は現在、英語を喋ってみるコミュニティ「<a href="https://www.meetup.com/ja-JP/meetup-group-en-jp/events/246234476/">en_jp</a>」を運営しています。月一程度でmeet up を渋谷で行なっています。すでに喋れる人、毎日英語を使っている人から、人前で英語を喋ることはほぼない人まで様々なレベルの人が来ますが、とにかくこれまで学んで来た英語を「使う機会」を提供しようとして始めているものです。是非、恐れずに今持っている英語を使っていただき、間違っていれば修正すればいいと思います。みなさんとお会いできるのを楽しみにしております！</p>
Chrome拡張機能:サムネイルをクリックしたらページ遷移せずに元画像を表示する

# はじめに

## やりたいこと
サムネイル画像をクリックしたら、ページ遷移せずに元画像を上からかぶせるようにプレビュー表示する。

## 制限事項
- 元画像が別ドメインにあると、content_scriptsから取得できない。
- content_scriptsからページ内のイベントハンドラを上書きできない。

content_scriptsからページ内にscript要素を埋め込んで、ページ上でスクリプトファイルを実行する。

# 手順1:ページ内で読み込ませるスクリプトファイルを登録する
ページ内で読み込ませるスクリプトファイルを、manifest.jsonの`web_accessible_resources`に追加する。

```json

"web_accessible_resources": [
    "bower_components/jquery/dist/jquery.min.js",
    "scripts/preview.js"
  ],

```

# 手順2:ページ内にscript要素を埋め込む
`chrome.runtime.getManifest().web_accessible_resources`にて、スクリプトファイルの一覧が取得できる。これを`chrome.extension.getURL()`でURLに変換し、script要素を生成する。

```javascript:content_scripts.js
const scripts = chrome.runtime.getManifest().web_accessible_resources;

const next = () => {
  let script = scripts.pop();

  if (!script) {return;}

  $('<script></script>', {
    type: 'text/javascript',
    src: chrome.extension.getURL(script),
    on: {ready: next()}
  }).appendTo('body');
};

next();
```


# 手順3:プレビューの実装

```javascript:preview.js
//リンクをたどって元画像のURLを取得する
const getImageUrl = async (url) => {
  ...
  return Promise.resolve(imageUrl);
};

//メインの処理
const initialize = () => {
  //元画像を表示するコンテナを生成する
  const container = $('<div></div>', {
    id: 'PreviewContainer',
    click: function(){
      //クリックされたら非表示にする
      $(this).hide();
      //履歴を一つ戻る
      window.history.back();
    }
  }).appendTo('body');
  container.hide();

  //サムネイルのリンクを無効にする
  $('#ThumbnailContainer').on('click', 'a', false);

  //サムネイル画像をクリックしたら元画像を表示する
  $('#ThumbnailContainer').on('click', 'img', async function(){
    //元画像のURLを取得
    let imageUrl = await getImageUrl($(this).parent('a').attr('href'));

    //元画像をコンテナの背景画像として表示する
    let container = $('#PreviewContainer');
    container.css('background-image', 'url(' + imageUrl + ')');
    container.show();

    //履歴を一件追加
    window.history.pushState(null, null, null);
  });

  //戻るボタンが押されたら元画像を非表示にする
  window.addEventListener('popstate', function (e) {
    if (container.css('display') === 'block') {
      $('#PreviewContainer').hide();
    }
  }, false);
};

//待機
const setTimeoutAsync = delay => {
  return new Promise(resolve => {
    setTimeout(resolve, delay);
  });
};

//jQueryの読み込み待ち
const limit = 5;
const checkJquery = async (count) => {
  if (!$ && count < limit) {
    await setTimeoutAsync(100);
    checkJquery(count++);
  } else {
    initialize();
  }
};
checkJquery(0);
```

元画像をクリックするとプレビュー表示が消えるようにしたが、癖で戻るボタンのショートカットを実行してしまうことが多かったので、戻るボタンでもプレビュー表示が消えるようにした。
【HTML】Canvasの高速化【JavaScript】

# Canvasで描画をしていて遅いってことはありませんか？
仕事で実際に試した方法を記載いたします。
iPadの第4世代のsafari、AndroidのChrome、Windowsのie11,Edgeで効果があることを確認しております。

# 1: requestAnimationFrameを使おう
requestAnimationFrameはsetTimeoutのようなAPIです。
requestAnimationFrameの使い方については、<a href="http://liginc.co.jp/web/js/130758">こちら</a>を参照してください。

### 1-1: setTimeoutやsetIntervalの代わりにrequestAnimationFrameを使おう
これはそれほど効果ありませんが、setTimeoutやsetIntervalより、requestAnimationFrameの方が多少良いそうです。

### 1-2: mousemove/touchmoveなどの動作イベントでもrequestAnimationFrameを使おう
これが最も効果があると思います。
canvasに描画しているオブジェクトをドラッグするプログラムを考えます。
描画を mousemove / touchmove のタイミングで行うのではなく、
mousemove / touchmoveでは描画に必要な情報を更新し、
requesAnimationFrameで描画するようにすると、カクツキが無くなります。
これは、mousemove / touchmove のイベントはマウスをぐりぐり動かすと1秒に数百回発生するためです。
requesAnimationFrameで描画すると、リフレッシュレートのタイミングで描画されるので、1秒に描画する回数(FPS)が60-120ぐらいになります。

### 1-3: requesAnimationFrameで描画を間引こう
Webで表示するなら、FPSは30ぐらいで十分だと思いますが、1-2のようにrequesAnimationFrameで描画するようにすると、FPSが75とか120とか、結構大きくなります。
ですので、時間を測定しFPSが30になるぐらいに調整すると、1秒当たりの描画回数が減ります。

# 2: backBuffer(DOMに追加されないメモリ上のCanvas)を使おう
動的にCanvasを作成し、それに事前に描画しておき、最終的に表示したいCanvasにレンダリングすると表示が速くなります。
例えば、Canvas上にある位置に丸、三角、四角が表示されていて、それが3つある場合を考えてみます。
丸、三角、四角は画像であるとします。
以下のようなケースです。
![frontbuffer.png](https://qiita-image-store.s3.amazonaws.com/0/163605/fd2d0f33-0ba6-4efe-a484-df886a061b62.png)
普通に実装すると、画像の読み込み後、canvasに丸、三角、四角を3回ずつ描画することになります。

ですが、ここでメモリ上にcanvasを作成して(backBufferと呼ぶことにします。)、それに丸、三角、四角をまとめて描画しておけば、
そのbackBufferをcanvasに3回描画すればよいことになります。

![backbuffer.png](https://qiita-image-store.s3.amazonaws.com/0/163605/d89b2afc-0d6e-6bb0-6405-f3c90e284e20.png)

# 3: クリアする矩形のサイズ又は回数を減らそう
canvasに描画する前にclearRectメソッドを呼び出してcanvas全体をクリアしていると思いますが、
全体をクリアするのではなく必要な箇所のみクリアするとパフォーマンスがよくなります。
また複数のcanvasを使用している場合、canvasをクリアする回数を減らすとパフォーマンスがよくなります。

# 4: WebGL使えばいいんじゃね？
正解です。書き直す工数のある方はwebGL2使いましょう。
2DのWebGLのライブラリとしてはpixi.js,createJSが有名です。

# 更新履歴
2024/08/21: 1-3を追記。1-2を加筆修正。
はじめてのプログラミング言語にpythonを選んだ人が覚えるべきこと

## 開発環境構築

なにはともあれ開発環境を用意します。  
仮想環境やらバージョン管理から始めようとすると、スタート地点でさじを投げたくなるのでIDE一本で解決しましょう。

pycharm 
https://www.jetbrains.com/pycharm/
![1.png](https://qiita-image-store.s3.amazonaws.com/0/47598/7d3371ed-3379-26fc-3158-1d83be4178c2.png)

こだわりたい方は[こちら](https://qiita.com/yamionp/items/f88d50da8d6b548fc44c)などを参考に設定をブラッシュアップしましょう。

## プログラムを書いて実行してみる

pycharmを立ち上げてプロジェクトを作成します。

![2.png](https://qiita-image-store.s3.amazonaws.com/0/47598/15611c65-1eaf-7de2-d2bd-6c99b38dd58b.png)

続いてpythonファイルを作成します。このファイルへ実際にプログラムを記述していきます。
ここでは例としてファイル名はhello.pyとしました。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/47598/bd528e02-c94b-20b1-ed2a-f18531c464f1.png)

早速プログラムを書いてみます。

```python
print('hello world')
```

記述した内容が正しければ、期待した実行結果を得ることができます。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/47598/4f734fba-9ff0-baaf-e534-f2553f5a3849.png)


### 演習

hello worldをhello japanへ変更して実行してみましょう。
出力結果はどうなるでしょうか？

## 変数と型

変数とは値を保持する入れ物です。
例えば先程のhello worldを変数を用いて記述すると以下のようになります。

```python
variable = 'hello world'
print(variable)
```

variableが変数の名前で右辺が変数の中身です。


> プログラミングで使う変数とは、データに名前を与えて、一定期間記憶出来るように加工したものです。
> 数学の変数も「3x+1=0」の「x」の部分を指しますが、基本的にプログラミングの変数とは違うものとして考えましょう。  

[引用:【Python入門】変数の宣言と使い方を解説 ](https://www.sejuku.net/blog/25210)

変数同士を用いて計算することも可能です。

```python
first_val = 'hello'
second_val = 'world'
combined_value = first_val + second_val
print(combined_value)
```

上記は文字列の連結を行っています。

勿論、数値の計算も可能です。

```python
a = 10
b = 20
c = a + b
print(c)
```

### 値の型

値には型が存在します。

```python
a = 10
b = '20'
c = a + b
print(c)
```

例えば上記のコードを実行すると  

```python
TypeError: unsupported operand type(s) for +: 'int' and 'str'
```

というエラーが発生します。
内容は「数値と文字は加算できないです。」です。

pythonではシングルクォーテーションで囲われた文字は文字列だと認識されます。  
型は無数に存在しますが、まずは文字列型と数値型を意識すればokです。

### 演習

変数の中身を書き換えてエラーが発生しないように修正してみましょう。

続きます