OmniAICreator/Qiita-1.07M huggingface dataset:
GemfileとGemfile.lockについて

<h2 id="Rubyの開発者を目指し基礎を学んでいる:relaxed:">Rubyの開発者を目指し基礎を学んでいる:relaxed:初心者の私が知識をまとめてみました。</h2>

<p><strong>目的:</strong></p>
<ul>
<li>自己理解</li>
<li>情報共有:sweat:</li>
<li>情報整理</li>
</ul>

<h2>
<span id="code---コードの挿入" class="fragment"></span><a href="#code---%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%8C%BF%E5%85%A5"><i class="fa fa-link"></i></a>そもそもgemとは？
</h2>
<p><strong>概</strong>
要としてはGemfileはgemのファイルだから。。。あれgemてなんだっけ？てなったのでまずは先にこちらについて調べました。</p>

<p>
"gem toha" でググりました。ソースはこちら、、👉
https://blog.codecamp.jp/rails-gem
gem
<p>パッケージ管理ツールみたいです。Rubyの。gemコマンドとして使うとライブラリという便利なプログラムの集まり。。つまり"gem"を<strong>簡単に</strong>インストールやアンインストールをしてくれます。（以前まとめました。https://qiita.com/taoki11111/items/583430dc40ab20d56abb）<strong>Railsもgem"Rubyのライブラリ"です。</strong>:head_bandage:以前私はLinux環境(CentOS7)を使用していたのですが、その時のパッケージ管理ツールでは"rpm"でした。Macはbrew？あとでまとめる必要がありそう。bundleはCentOSではyumに当たると思います。may be...</p>


<h2>
<span id="code---コードの挿入" class="fragment"></span><a href="#code---%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%8C%BF%E5%85%A5"><i class="fa fa-link"></i></a>GemfileとGemfile.lockとは？
</h2>
<p><strong>今</strong>
回はGemfileとGemfile.lockの違いについてまとめています。</p>

<p>
結論としては、Gemfileに必要なgemがGemfile.lockに記述されていることがわかりました。
<p>最初はGemfileのバックアップだと思っていました。Githubとかにバックアップ取っておけばその意味はなさないですね。:cold_sweat:</p>

<p>使用感としては、追加したいgemがあるから、Gemfileに追加したいgemを追記し、bundleインストールを行う。そうすると自動的にGemfile.lockに追加したgemの名前やバージョンが追記される仕組みになっているようです。</p>

<p>
<h2>
<span id="code---コードの挿入" class="fragment"></span><a href="#code---%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%8C%BF%E5%85%A5"><i class="fa fa-link"></i></a>to be continued...</h2>
<li id="fn2">
<p>
今回は短くまとめましたが、どうやらbundle install やbundle exec あたりとの関係が深そうです。沼にはまりそう。:tired_face:</a></p>
</li>
[Alexa] 初めてのスキル開発＠ASK SDK v2 for Node.js

# 本ページの概要
「[ASK SDK v2 for Node.jsを使ったスキル開発の手順の説明](https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/wiki/%5BJapanese%5D-Developing-Your-First-Skill)」を参考に、sdk v1でスキルを作成したことがある筆者が試した際の注意点を共有します。



# ASK SDK v2 for Node.js
[セットアップ方法はこちら](https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/wiki/%5BJapanese%5D-Setting-Up-The-ASK-SDK)にあります。

ハンドラーの定義方法が結構変わっている気がします。Intentごとに独立させやすくなっているような。


#注意点
基本的には、説明ページの通りで問題なくv2を試すことができましたが、本当に初めて触る方だと困るかもしれない点をあげておきます。

## node.jsのバージョン

手順のページでは、以下のようにasyncを利用しています。そのため、Lambdaファンクションの**ランタイムはnodejs8.10**を選択しましょう。

```
exports.handler = async function (event, context) {
```

マネジメントコンソールの場合は、ファンクション設定の「関数コード」から設定。

![WS000125.JPG](https://qiita-image-store.s3.amazonaws.com/0/179480/df56a399-5ff7-3e38-5bc3-fc23bfc00810.jpeg)


恐らく、ASK CLIを利用してデプロイすれば自動的に最新のランタイムが選択されるのではないかと思いますが、私はServerless Frameworkを利用しており、現時点での最新版（v 1.27.3）のnode.js用テンプレートだと6.10がserverless.ymlに設定されているので、一回コケました。


## ErrorHandlerの追加

メインのhandlerの定義で、ErrorHandlerを追加するaddErrorHandlers(ErrorHandler)を宣言しています。

＃他のHandlerと別けてError処理の定義ができるようになったようですね。


```javascript
exports.handler = async function (event, context) {
  console.log(`REQUEST++++${JSON.stringify(event)}`);
  if (!skill) {
    skill = Alexa.SkillBuilders.custom()
      .addRequestHandlers(
        LaunchRequestHandler,
        HelloWorldIntentHandler,
        HelpIntentHandler,
        CancelAndStopIntentHandler,
        SessionEndedRequestHandler,
      )
      .addErrorHandlers(ErrorHandler)
      .create();
  }
  
  return skill.invoke(event,context);
}
```

説明ページ内では、ErrorHandlerの宣言の説明が省略されているようですので、以下も追加しましょう。

```javascript
const ErrorHandler = {
    canHandle(handlerInput) {
        return true;
    },
    handle(handlerInput) {
        return handlerInput.responseBuilder.speak('うまく処理できませんでした。')
        .getResponse();
    }
};
```


#終わりに
[v1からの移行や、互換性を保つためのアダプタ](https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/wiki/ASK-SDK-Migration-Guide)も提供されているようですね。既存のスキルをわざわざ書き直すかどうか、メリット／デメリットはまだ見極められていないので、新しいスキルをv2で少し作成してみてから検討したいと思います。
PythonからOracle接続をSID指定ではなく、SERVICE_NAME指定で接続する

PythonからOracleに接続するには、cx_Oracleを使用します。

#SID指定で接続
サンプルでは、cx_Oracle.makedsn でサーバ名、ポート、SIDを指定して戻り値を
cx_Oracle.connect　に渡してます。

```python

import cx_Oracle

#サーバ名 / IP
HOST = "svdb"
#ポート
PORT = 1521
#SID
SID = "orcl1"


tns = cx_Oracle.makedsn(HOST, PORT, SID)
conn = cx_Oracle.connect("scott", "tiger", tns)
```

cx_Oracle.makedsn(HOST, PORT, SID) で返される値を確認

```
tns = cx_Oracle.makedsn(HOST, PORT, SID)
print(tns)


(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=svdb)(PORT=1521))(CONNECT_DATA=(SID=orcl1)))
```

SIDを指定した設定値になる

#SERVICE_NAME指定で接続
cx_Oracle.makedsnのドキュメント
- http://cx-oracle.readthedocs.io/en/latest/module.html#cx_Oracle.makedsn

>cx_Oracle.makedsn(host, port, sid=None, service_name=None, region=None, sharding_key=None, super_sharding_key=None)


今までは引数の３番目がSIDだったので、SIDを指定していたわけですね。
service_nameを指定でいけそう

```python

HOST = "svdb"
#ポート
PORT = 1521
#SERVICE_NAME
SVS = "orcl"

#SERVICE_NAMEを指定
tns = cx_Oracle.makedsn(HOST, PORT, service_name =SVS)
print(tns)


(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=svdb)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))
```

SERVICE_NAME指定ができた！


最後に接続してみる

```python
import cx_Oracle

HOST = "xxxxx"
#ポート
PORT = 1521
#SEVICE_NAME
SVS = "orcl"

#SERVICE_NAMEを指定
tns = cx_Oracle.makedsn(HOST, PORT, service_name =SVS)
conn = cx_Oracle.connect("scott", "tiger", tns)

cur = conn.cursor()

#SERVICE_NAMEを確認
cur.execute("""select name from v$database""")

rows = cur.fetchall()

for r in rows:
    print("SERVICE_NAME:%s" % (r[0]))

#SIDを確認
cur.execute("""select instance_name from v$instance""")

rows = cur.fetchall()

for r in rows:
    print("SID:%s" % (r[0]))
```

実行結果
サービス名で接続できた

```
SERVICE_NAME:ORCL
SID:ORCL1
```

#気がついたこと
cx_Oracle.makedsnを使用することで構成情報が簡単に作成できます。
作成された構成情報には、FAILOVER や LOAD_BALANCE が記載されません。

- https://docs.oracle.com/cd/E16338_01/network.112/b56287/tnsnames.htm#CJAGGHIG

なので
直接書くことできるんじゃないかと検証

```python:
import cx_Oracle

#tns構成情報を作成
tns=" \
    (DESCRIPTION = \
    (ADDRESS = (PROTOCOL = TCP)(HOST = srv102n1-vip)(PORT = 1521)) \
    (ADDRESS = (PROTOCOL = TCP)(HOST = srv102n2-vip)(PORT = 1521)) \
    (LOAD_BALANCE = yes) \
    (FAILOVER=on) \
    (CONNECT_DATA = \
      (SERVER = DEDICATED) \
      (SERVICE_NAME = orcl) \
    ) \
  )"

#作成した構成情報を設定
conn = cx_Oracle.connect("scott", "tiger", tns)

cur = conn.cursor()

#SERVICE_NAMEを確認
cur.execute("""select name from v$database""")

rows = cur.fetchall()

for r in rows:
    print("SERVICE_NAME:%s" % (r[0]))

#SIDを確認
cur.execute("""select instance_name from v$instance""")

rows = cur.fetchall()

for r in rows:
    print("SID:%s" % (r[0]))
```

実行結果
接続できた！！

```
SERVICE_NAME:ORCL
SID:ORCL1
```

SERVICE_NAMEではなく、SID指定する方法は以下の投稿を参照ください。

- [Windows環境のPythonからOracleに接続してみる](https://qiita.com/kngsym2018/items/04514d623248a070adee)
ubuntu16.04 LTS用のLive USBをmacで作成する


## この記事でやること
Ubuntu16.04 LTS用のLive USBを作成(on macOS)

※本記事に記載された事項に関して一切の責任を負いません。
くれぐれも気をつけて実行してください。

## ステップ
1. USBメモリ(16GB以上推奨)を用意
2. ubuntu16.04 LTSイメージ(https://www.ubuntu.com/download/desktop) をダウンロード
3. USBメモリを初期化&ISOファイルの書き込み


## 詳細
### 1. USBメモリ(16GB以上推奨)を用意
コンビニなどでも入手しやすいTOSHIBAのUSBメモリ(16GB)を利用した。
https://www.amazon.co.jp/%E6%9D%B1%E8%8A%9D-TOSHIBA-USB%E3%83%95%E3%83%A9%E3%83%83%E3%82%B7%E3%83%A5%E3%83%A1%E3%83%A2%E3%83%AA-Windows-16GB-1%E5%80%8B/dp/B071V5VYKP

### 2. ubuntu16.04 LTSイメージをダウンロード
(2018/6/3現在)

ダウンロード元:
https://www.ubuntu.com/download/desktop

今回は、alternative downloadのBit Torrentを利用した
- 右側緑ボックスで囲まれた「Download」の下の方に書いてある「see our alternative downloads」をクリック(赤下線部)
<img width="1020" alt="Screen Shot 2018-06-03 at 23.53.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/123976/35787f03-27eb-de6e-fc28-75c11ba4c204.png">


- Bit TorrentからUbuntu 16.04 LTSの「Ubuntu 16.04 Desktop (64-bit)」を選択してダウンロード

utorrentなどでISOファイルがダウンロードできると、指定のフォルダに「ubuntu-16.04.4-desktop-amd64.iso」があるはず。(配置ディレクトリを覚えておく)

### 3. USBを初期化&ISOファイルの書き込み
- terminal(iTerm2)を開く
- cdコマンドで先ほど落としたISOファイル先まで移動
- USBメモリの初期化  
まず、USBメモリのディスク名を確認(※大事！選択を間違えるとOSが破損する恐れがあります。)

```
diskutil list


/dev/disk0 (internal):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                         500.3 GB   disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:          Apple_CoreStorage Macintosh HD            499.3 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3

/dev/disk1 (internal, virtual):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:                  Apple_HFS Macintosh HD           +499.0 GB   disk1
                                 Logical Volume on disk0s2
                                 xxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx
                                 Unlocked Encrypted

/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.5 GB    disk2
   1:                 DOS_FAT_32 TOSHIBA                 15.5 GB    disk2s1
```

/dev/disk2がUSBに該当するので覚えておく


- USBをFAT32にフォーマット  
```sudo diskutil eraseDisk FAT32 NAME MBRFormat /dev/disk2
```

- USBをunmountする  
```diskutil unmountdisk /dev/disk2
```

- USBにISOファイルを書き込む  

```  
sudo dd if=ubuntu-16.04.4-desktop-amd64.iso of=/dev/rdisk2 bs=2m conv=sync

774+1 records in
775+0 records out
1625292800 bytes transferred in 308.765736 secs (5263838 bytes/sec)
```  

割と時間かかることもあるので根気よく待つ。
上記のようにtransferredの標準出力が表示されたら完了。


以上
sedコマンドで任意の文字列を置換 coneta #3

###**sedコマンドによる文字列の置換**

　通常は区切り文字に`/`を使用します。

~~~bash
sed 's/被置換文字列/置換文字列/g'
~~~

　`/`を含む文字列を置換するときは、区切り文字に`/`は使えません。
　面倒ですが、`/`を含む文字列の`/`を`\`でエスケープすれば置換することができます。
　以下は`a/b`を`A/B`に置換する例です。

~~~bash
sed 's/a\/b/A\/B/g'
~~~


###**/を含む文字列の置換**

　`\`でエスケープせずに`/`を含む文字列を置換する場合、区切り文字に`/`以外の文字を使用します。

~~~bash
sed 's@被置換文字列@置換文字列@g'
~~~

　この例では`@`が区切り文字です。
　他の文字を使うこともできますが、いずれにしても、
区切り文字を含まない文字列しか置換できません。

###**任意の文字列の置換**
　制御文字を通常の文字列に使用することは、ほとんどありません。
　区切り文字に制御文字を使用することで、事実上任意の文字列を置換することができます。
　以下は、区切り文字に制御文字`^D`を使用した例です。

~~~bash
sed 's^D被置換文字列^D置換文字列^Dg'
~~~
　他の制御文字を使うこともできます、EOTを使っているのは単なる個人的な習慣です。
　制御文字の入力方法は以下を参考にしてください。
【参考】
　　[viコマンドで制御文字を入力 coneta #2]
(https://qiita.com/EjiriAkira/items/4c8c2deba8b5d283e323)



###**制御文字列を直接使わない**
　制御文字をsh変数に格納、参照することにより、間接的に制御文字を使用する方法です。

~~~bash

delimiter=$(echo -n -e '\x04') sed 's'${delimiter}'被置換文字列'${delimiter}'置換文字列'${delimiter}'g' 
~~~


###**環境**


ホスト　Windows10 COREi7 
VM　　　VirtualBox バージョン 5.2.8 r121009 (Qt5.6.2)
　　　　　CentOS Linux release 7.4.1708 (Core)
　　　　　3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018
GNU bash, バージョン 4.2.46(2)-release (x86_64-redhat-linux-gnu)
sed (GNU sed) 4.2.2

---
ソフトウェアをテストする際に気を付ける点

ただ闇雲にテストしていてもバグを見つけることは難しいです。
そこでどこを重点的にテストするれば良いか説明します。

##　テストの前提
まずテストはまったくバグの無いソフトウェアを作ることはできません。
なので全てをテストしようとするのではなく、十分なテストをすることが大切です。

まずはいくつかテスト手法を紹介します。
##　ホワイトボックステスト
ホワイトボックステストとはプログラムの理論構造が正しいかを分析するテストです。
ホワイトボックステストですべての処理をテストすることでカバレッジ100%となります。
しかしカバレッジ100%になるまでテストするには、多くの予算と時間がかかる上、カバレッジ100%にしてもバグの無いプログラムとはならないので、一般的なソフトウェアなら60~90%で十分という説が多いです。
カバレッジを何%にするかはROIを考慮して決めるといいと思います。
> ROIとは、Return On Investmentの略語で、投資したコストに対する効果を見る指標です。計算式としては下記になります。
ROI＝利益÷投資コスト×100

[TDD再考 (2) – 何故、ほとんどのユニットテストは無駄なのか？](https://ubiteku.oinker.me/2015/07/27/why-most-unit-testing-is-waste/)



### ステートメントカバレッジ
if文など含む処理はフローチャートで表すことができます。
そのフローチャートにある命令文（ステートメント）を少なくとも1回は実行するようにテストケースを書きます。
しかしif文の処理が間違えている場合などにはバグを見つけることはできないので、このテスト手法は弱いテスト手法です。

### ブランチカバレッジ
ブランチカバレッジは、分岐コードに対してそれぞれの判定条件がTRUE,FALSEの結果を少なくとも一回ずつも打つようにテストケースを書きます。
そうすることによりステートメントカバレッジでテストしきれなかった部分をテストすることができますが、テストケースの数がかなり増えてしまうというデメリットがあります。

### カバレッジでテストできないバグ

* プログラムのループに関するバグ
* 要求仕様自体が間違っていたり、機能が備わっていないバグ
* データに関するバグ
* タイミングに関するバグ

## ブラックボックステスト
ブラックボックステストとはプログラムの仕様が正しいかをテストすることです。
ブラックボックステストは、ソースコードを利用したり見ることなく、様々な入力を行うことで、テストを行います。
ブラックボックステストでよく使われる手法として同値分割法と境界値分析法があります。
詳しくは[同値分割・境界値分析の解説](https://qiita.com/softest/items/648d8bb4021cd1256b02)に書いてあります。

## テストする際に気を付ける点
* 自分が行ったテストで、どこまでテストが出来ていてどこがテスト出来ていないかを把握する。
* テストケースを書くときはいつ、誰がやっても同じうような結果が得られるように書くように心がける。
* 境界値にバグが潜んでいることが多いので、境界値周辺を念入りにテストする。
* 複雑な処理をしている箇所にバグがあることが多いので、複雑な処理をしている箇所を念入りにテストする。
* 適切なテスト手法を使うようにする。


##　まとめ
テストとして十分なパターンを出してテストする。
ただしパターンをすべて出していては量が多すぎて時間が足りなくなるので、バグが出そうな箇所や、絶対にバグを出してはいけない箇所を、選別して、テストする必要があります。
Railsチュートリアルの画像は参考にならない、という話

なぜかRailsチュートリアルは明示的に5.1.4をインストールさせるくせに
[v5.1.4以降](https://github.com/rails/rails/blob/813af4655f9bf3c712cf50205eebd337070cee52/railties/lib/rails/commands/server/server_command.rb#L67)
に変化した`rails server`の起動時メッセージが古いままの画像を提示している。

というかよく見ると軒並み画像は5.1.2のまま更新されていない。
なぜ`Gemfile`だけ更新したのか謎

---

ついでに、インストール方法はまだいいとして
(sudoの罠くらいは説明して欲しい、とは思う)

起動方法として`rails server`を提示するのはいかがなものかと思います。

Rails5以降は`bin/rails server`を使うべきだし、
cloud9ならば`bin/rails s -b $IP -p $PORT` にすべき
Windows10(64bit)にVagrant+VirtualBoxで開発環境作る1

# 概要

個人で開発する用の環境を作るのでそのメモ

普通のWeb用環境を想定

（あとQiitaの練習）

## 追記

[その2](https://qiita.com/halnique/items/33b5fcd002c7bedc9db7)も書きました

# ゴール

とりあえず以下のような環境を作りたい

- Windows 10 64bit
- Vagrant
- VirtualBox
- Git for Windows
- CentOS
- Nginx
- PHP
- MySQL
- Redis

# Vagrant, VirtualBox, Git for Windowsインストール

それぞれ公式からDLしてインストール  
- [Vagrant](https://www.vagrantup.com/) (2.1.1)
- [VirtualBox](http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html) (5.2.12)
- [Git for Windows](https://gitforwindows.org/) (2.17.1)

※ 括弧内は執筆時のバージョン

インストールはウィザードに従って行うので割愛

また、コマンドプロンプト使えないので代用でGit for WindowsにくっついてくるGit Bashを使う

```bash
$ vagrant --version
Vagrant 2.1.1
$ /c/Program\ Files/Oracle/VirtualBox/VBoxManage.exe --version
5.2.12r122591
$ git --version
git version 2.17.1.windows.2
```

ここまででこんな感じ

# CentOSのイメージを使ってVM構築

1. 適当な作業ディレクトリを作る(`~/work/sample`とか)
2. その中にvagrantディレクトリを作る
3. vagrant initでVagrantfileを作る

```bash
$ mkdir -p ~/work/sample
$ cd ~/work/sample
$ mkdir vagrant
$ cd vagrant
$ vagrant init centos/7
$ vagrant up
```

これでCentOS 7の公式イメージでVMが作れる

※ Vagrantfileを色々いじるのはまた今度

しばらく待って、終わったらひとまず空っぽのVM完成

```bash
$ vagrant ssh
[vagrant@localhost ~]$ pwd
/home/vagrant
[vagrant@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
```

# この先

VM上で設定いじったり色々インストールしたりしていく

# 最後に

頑張って継続していく
django2.0.3でモデルに複数のForeignKeyを指定したかった

```
class User(models.Model):
    name = models.CharField(max_length=60)

class Product(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL)
    user2 = models.ForeignKey(User, on_delete=models.SET_NULL)
```

こんなmodelを作りたかった。

しかしこんなエラーメッセージが表示される。
```
    RECURSIVE_RELATIONSHIP_CONSTANT,
AssertionError: ForeignKey(<django.db.models.fields.related.ForeignKey>) is invalid. First parameter to ForeignKey must be either a model, a model name, or the string 'self'
```

ググってみると、related_nameを追加すればいいとあるがやはりダメ。
しかし、Djangoの公式ドキュメントを見たら一発解決。

```
class Product(models.Model):
    user = models.ForeignKey('User', related_name='user_from')
    user2 = models.ForeignKey('User', related_name='user_from')
```
'User'とクォーテーションで囲ったらイケた。
ForeignKeyを一つしか定義してないときはクォーテーションで囲わなくても大丈夫だったからまさかこんなので直るとは思っていなかった。まずググる前に公式ドキュメントを見るのが一番だと痛感した。
表作成方法

# データベースで使用するような形の表形式だよ♪

```html:grid.html
<!DOCTYPE html>
<html>
    <head>
        <title>表形式テスト</title>
        <script src = "grid.js"></script>
        <meta charset = "UTF-8">
    </head>
    <body>
        <script>Main( );</script>
    </body>
</html>
```
---
<p><strong>要点説明だよ♪</strong></p>
```html
<tr>行の役割があるよ♪</tr>
<td>列の役割があるよ♪</tr>

ここで, 線の太さ, 線の色, 線の種類をしていしているよ♪
<table style="border-color : #000000; border-style : solid; border-width : 1px;">
```
---
```javascript:grid.js
// 関数の定義
function Main( ) {
    var name = new Array( "食パン", "カレーパン", "メロンパン", "フランスパン" );
    document.write( '<table style="border-color : #000000; border-style : solid; border-width : 1px;">' );
        document.write( "<tr>" );
            document.write( "<td>id</td><td>食品名</td>" );
        document.write( "</tr>" );
            for( var j = 0; j < name.length; j++ ) {
                document.write( "<tr>" );
                for( i = 0; i < 1; i++ ) {
                    document.write( "<td>" + j + "</td><td>" + name[ j ] + "</td>" );

                }
                document.write( "</tr>" );

            }
    document.write( "</table>" );

    return 0;

}
```
---
<p><strong>実行結果だよ</strong></p>
![2018y06m03d_223058779.png](https://qiita-image-store.s3.amazonaws.com/0/261898/9747fdcc-12ea-cc4f-4f98-cda3c329e412.png)
---
PDFの抽出/結合を自動処理する

複数のPDFそれぞれから特定のページを抽出してひとつのPDFに結合する。
大量処理、定期的な作業などに使えそうだったのでメモ。

## 環境
* Python3　　スクリプト環境
* PyPDF2　 　Pythonのライブラリ
* JSON　　 　設定ファイルの書式

## コード
### 設定ファイル
Jnl_convert.json

```json
{
    "": "出力用のファイル名"
    "outputfile": "Jnl_0000.pdf",

    "": "入力用のPDFリスト"
    "pdf_list":[
        {
            "": "input/Jnl_00001.pdf の 1ページ目のみを抽出",
            "inputfile": "input/Jnl_00001.pdf",
            "start": 1,
            "end": 1
        },
        {
            "": "input/Jnl_00002.pdf の 2ページ目のみを抽出",
            "inputfile": "input/Jnl_00002.pdf",
            "start": 2,
            "end": 2
        },
        {
            "": "input/Jnl_00003.pdf の 3～5ページを抽出",
            "inputfile": "input/Jnl_00003.pdf",
            "start": 3,
            "end": 5
        },
    ]
}
```


### スクリプト
generate.py

```python
# -*- coding: utf-8 -*-
import sys
import PyPDF2
import json

args = sys.argv

# 引数のチェック
if(len(args) != 2):
    print("usage: $ python {0} <input_jsonfile>".format(args[0]))
    quit()

# 入力用JSONファイルのオープン
with open(args[1], 'r', encoding='utf-8') as f:
    conf = json.load(f)

output_pdf_obj = PyPDF2.PdfFileWriter()

for pdf in conf['pdf_list']:

    source_pdf = open(pdf['inputfile'], "rb")
    source_pdf_obj = PyPDF2.PdfFileReader(source_pdf, strict=False)
    startpage = pdf['start'] - 1
    endpage = pdf['end']

    for i in range(startpage, endpage):
        print("   add: {0} , page {1}".format(pdf['inputfile'],i))
        output_pdf_obj.addPage(source_pdf_obj.getPage(i))
        pass

    # ここでcloseすると正常に動かない。ライブラリ適当に使ってはまるやつ。
    # source_pdf.close()
    pass

with open(conf['outputfile'], "wb") as output_pdf:
    output_pdf_obj.write(output_pdf)

print("output: {0}".format(conf['outputfile']))
```
### 実行結果

```bash
$ python3 generate_Jnl.py Jnl_convert.json
   add: input/Jnl_00001.pdf , page 0
   add: input/Jnl_00002.pdf , page 1
   add: input/Jnl_00003.pdf , page 2
   add: input/Jnl_00003.pdf , page 3
   add: input/Jnl_00003.pdf , page 4
output: Jnl_0000.pdf
```
AWS Summit Tokyo 2018で気になった内容メモ_ゲームのバックエンドを支えるスケーラブルかつ柔軟なAWSでのインフラ構築

AWS Summit Tokyo 2018の「ゲームのバックエンドを支えるスケーラブルかつ柔軟なAWSでのインフラ構築」のセッションを聴いて、個人的に気になった部分をまとめています。
まだ資料が公開されておらず、個人のメモをベースに書いているため、内容が全て網羅されているレポートではありません。
資料、動画が公開されたら別途ちゃんとしたレポートを書きます(多分)

# ゲームのバックエンドアーキテクチャ
## アンチパターン
- モノリシック
- モノリシック スケーリング

モノリシックは一つのモジュールが死んだ時に全てに影響が及ぶのでイマイチという話。

## サービスオリエンテッドアーキテクチャ
- 各モジュール単位でサーバを分割する
- 各モジュール毎にELBを立ててそれぞれ負荷分散もできる

## ゲームAPIバックエンドサーバのよくある構成
- 最適なリージョンを選択
- 2つ以上のAZで運用
- アプリ用EC2
- Elastic Load Balancer
- RDS
- Amazon Aurora

# DBの更新頻度が課題になりやすい
- 現状はAuroraをシャーディングして使うパターンが多い
	- シャーディングは辛い
	- サーバの増減を自分たちで対応、かつ対応時にダウンタイムが発生する
- DynamoDBがおすすめ
	- フルマネージド
	- NoSQLデータストア
	- プロビジョン度スループット
	- セカンダリインデックス
	- PUT/GET keys
	- TTLサポート
	- ドキュメント型サポート
	- 400KBアイテム
	- PITR可能なバックアップ
	- Amazon DynamoDB Accelerator(DAX)

## なぜDynamoDBがゲームに向いてるか？
- パーティションキー=プライマリキー
- スキーマを変更することなくテーブル設計変更可能
- TTLを利用して古いデータの削除が可能
	- リセマラデータとか、古いデータは削除できる
- サーバレスのため、インスタンスの増減は自動でやってくれる
    - ダウンタイムがなく、かつ常に適切な量のリソースを使うため、コストの最適化もできる

## DynamoDB Grobal Tables
- マルチリージョンで、世界中のサーバに非同期にレプリケーションを貼ることができる
- 世界展開する予定のプロダクトにはおすすめ

# DynamoDBを使ったマイクロサービス構成
マイクロサービス構成についての話。
その中でgRPCを使ったパターンについての話があった。

## gRPCを使ったAPI接続の注意点
- ALBはHTTP/2への対応を行っているが、ALBのバックエンドはHTTP/1.1となる
- NetworkLoadBalanserがおすすめ
- gRPCの導入事例としてはグラニの「黒騎士と白の魔王」がある
    - 黒騎士ではCLBを使っていたが、ローンチの時にNLBがリリースされていなかったため
    - 現在はALBやCLBを選択するメリットはない
    - 
## DynamoDBを使ったマイクロサービスアーキテクチャ採用事例
- PUBG
	- 300万ユーザのアクセスにも対応した
- Nexon


# 感想
とりあえずDynamoDBがゲームでもおすすめというのが印象に残った。
RDBMSとNoSQLという壁はあるが、そこが問題にならないのであれば確かに適している。
海外展開も想定すると、DynamoDB Grobal Tablesも気になるところ。
PUBGという事例があるのも強い。
よく自分が使うgrepコマンド

自分がよく使うgrpeのやりかた。
忘れはしないだろうけど、一応自分用にメモとして残しておく。
(最近、自分の記憶力を信用していない)

```bash
# "hogehoge"という単語を、カレント直下のディレクトリを再帰的にたどって検索。なお、node_modulesとdistディレクトリは除外。
grep -inr hogehoge ./ --exclude-dir={node_modules,dist}
```

``--exclude-dir``で除外ディレクトリを設定できるが、
最初はまったのは、``--exclude-dir={node_modules, dist}``というようにスペースが入っていると、私の環境(zsh)の場合エラーになるということ。

```zsh
zsh: parse error near `}'
```


最初、何が原因でエラーになっているのかがよく分からなかった。
意外とネットで調べてみてもすぐに答えが見つからなかったので、こういうのって常識中の常識なのかも知れない。
探し方が悪かった可能性は否定しない。
(よって、30分ほど答えが見つからないまま悩んでいた。。)
yarn addしたmoduleのsubmoduleがempty問題


## 環境
- `リポジトリA`と`リポジトリB`がある。
- `リポジトリB`のsubmoduleに`リポジトリC`を設定している
- （`リポジトリA`はmonorepo環境であり、lerna&yarnで管理）

```
・リポジトリA

・リポジトリB
   └── リポジトリC(submodule)

・リポジトリC
   └── hogehoge
```

## 何が起きたか

1. `リポジトリA`のpackage.jsonに`リポジトリB`を追加する
2. `yarn install`する
3. `リポジトリB`の`リポジトリC`ディレクトリが空っぽになっている

```
リポジトリA
├── package.json
│    "devDependencies": {
│    "リポジトリB": "git+ssh:~",
│
└── node_modules/
    └── リポジトリB/
        └── リポジトリC(submodule)
             └── (Empty)
```

## なんで？
どうやらyarnで追加したnode_modules内部のsubmoduleが正常にfetchできないみたい。
[Submodules of git dependencies are not fetched · Issue \#1488 · yarnpkg/yarn](https://github.com/yarnpkg/yarn/issues/1488)

## 対処１
git cloneで一時しのぎすればいいよ、というコメントがあったので強引感はあったものの試してみる。

>While i hope this issue is getting some research invested into it, this placeholder workaround might serve as a temporary solution for all of us waiting

>In package.json of a module being fetched, add a following script
"postinstall": "grep url .gitmodules | sed 's/.*= //' | while read url; do git clone $url; done"

今回の場合「`リポジトリA`から`リポジトリB`を実行する」ときはbin経由で呼ぶつもりだったので、その実行ファイルのshellスクリプトにgit cloneを書いてしまえばイケそう。

```text:こういうこと
リポジトリA
├── package.json
│
└── node_modules/
    └── リポジトリB/
        └── リポジトリC(git clone)
             └── hogehoge
```

## さらなる問題
対処１でうまくいったように見えたので、別でyarn addしてみたところ問題発生。
パーミッションエラーが発生してyarn addできない。
なぜだかgit cloneしたディレクトリが読み取り専用になっていてyarnから操作できなくなっている。

```text:なんでやねん
リポジトリA
├── package.json
│
└── node_modules/
    └── リポジトリB/
        └── リポジトリC(git clone) <= permission dinide

```


## 対処２
git cloneはやめ、シンボリックリンクで対処することに決めた。
リポジトリAにリポジトリCのsubmoduleを設定し、
リポジトリB配下にリポジトリCのシンボリックリンクを貼る。

```text:つまりこう
リポジトリA
├── リポジトリC(submodule)
│     └── hogehoge
│
└── node_modules/
    └── リポジトリB/
        └── リポジトリC(シンボリックリンク)
             └── (hogehoge)
```

シンボリックリンクをはる処理は、実行ファイル内に書いてしまえばOK。
（シンボリックリンク作る前に空のディレクトリは削除している）

```.shell:実行ファイル.sh
# リポジトリAのsubmoduleにシンボリックリンクを貼る
# /リポジトリA/node_modules/リポジトリB/リポジトリC/ => /リポジトリA/packages/リポジトリC/

# cd リポジトリA
rm -fd node_modules/リポジトリB/リポジトリC
ln -nfs packages/リポジトリC  node_modules/リポジトリB/

(実行したい処理)
```

解決。
Vim ことはじめ

なんとなくVimを使ってみたくなったので、初学者が慣れるまでにやったことをまとめてみます。

# Vimの特徴
 - マウスを使用しない（ように設計されている）。
 - カーソルキーを使わない。
 - コマンドを覚える必要がある。
 - 慣れればめちゃ便利（らしい）

# なぜVim?
 - Linuxサーバー内だけで編集して実行できる
 - 幅広い拡張性
 - 起動が早い
 - （慣れれば）素早くファイルが編集できる
 - なんとなくかっこいい ..etc     
 参考：[なぜvimを使うのか](http://kaworu.jpn.org/vim/%E3%81%AA%E3%81%9Cvim%E3%82%92%E4%BD%BF%E3%81%86%E3%81%AE%E3%81%8B)

# Vim使い方
コマンドの種類は無数にあるので、まずは以下で紹介するコマンドから使えるようになると良いと思います。

## モードの切り替え
Vimには編集モードとコマンドモード（通常モード）があります。

|モード                |コマンド                          |
|----------------|-------------------------------|
|編集モード(カーソルの位置から)|`i`|
|編集モード(カーソルの後ろから) |`a`|
|編集モード(改行してカーソルの下から) |`o`|
|編集モード(カーソルの位置から置換) |`R`|
|コマンドモード |`Esc`|

## 終了コマンド
|終了パターン                |コマンド                          |
|----------------|-------------------------------|
|変更を保存せず終了|`:q!`|
|変更を保存して終了 |`:wq` ( or `ZZ` )|

> :で始まるコマンドをexコマンドと呼びます。

## カーソル移動

|方向                |コマンド                          |
|----------------|-------------------------------|
|←|`h`|
|↑ |`k`|
|→ |`l`|
|↓ |`j`|
|単語ごとにカーソルを進める|`w`|
|単語ごとにカーソルを戻す |`b`|
|行の最初へ|`0`|
|行の最後へ |`$`|
|次のページへ |`ctrl + f`|
|前のページへ |`ctrl + b`|
|ファイルの末尾へ |`G`|
|ファイルの頭へ |`gg` (or `1G`)|
|n行目へジャンプ |`ngg` (or `nG`)|
|前方検索|`/〇〇`|
|後方検索|`?〇〇`|
|(検索後)次の候補へ|`n`|

 カーソルの移動が早くできる＝編集が早くできるなので、このあたりのコマンドはvimを使う上で**超重要**です。
> ファイルを開いたときにとりあえず:set numberや:set autoindentコマンドを打っておくと編集が楽になるでしょう。

## 編集系コマンド

|編集方法                |コマンド                          |
|----------------|-------------------------------|
|一文字削除|`x`|
|一語変更|`cw`|
|一語変更(こっちの方が個人的にはよく使う)|`ciw`|
|カーソル位置から行末まで変更 |`c$`|
|一語削除 |`dw`|
|カーソル位置から行末まで削除 |`d$`|
|一行コピー（ヤンク）|`yy`|
|一行カット |`dd`|
|ペースト |`p`|
|直前のコマンド繰り返し |`.`|
|アンドゥ |`u`|
|リドゥ |`ctrl + r`|
|ビジュアルモード |`v`|
|矩形選択 |`ctrl + v`|
|矩形選択後、挿入 |`I` or `A`(escで終了)|

# とりあえずチュートリアルを
上記のコマンドを使うことを意識してチュートリアルをやってみると良いと思います。
Macか大体のLinuxであれば以下のコマンドでvimのチュートリアルが始まると思います。

```none
$ vimtutor
```

もしくはvimを起動して:Tutorialコマンドを(こちらであればWindowsでも動くと思います)

```none
:Tutorial
```

# vimをもっと便利に使うために
 - ホームディレクトリに.vimrcファイルを作る。
 - プラグインを導入する。
 - マクロを使う...etc
普段Mac使いの人がWindows環境を構築する際に入れたアプリについて

# はじめに
普段仕事も自宅もMacな私ですが、最近めっきりエンジニア系な仕事もしてないし、主にパワポとExcelとMarkdownがメインで、たまにプログラミングぐらいなので・・・
もうもはやOfficeをMacで使う苦行をするくらいならWin環境も持ってしまえばいいのでは？と思い、Win環境も導入してみました。
その時のPCセットアップしたもの達をメモがてら。

## 対象ユーザー
- PM的な業務や、製品導入コンサルティングなどエンジニア100％ではない人
- 普段Macですっかり慣れちゃってる人


# セットアップしたアプリ

| 種類 | Macアプリ | Winアプリ | 備考 |
| --- | --- | --- | ---|
| ファイル管理 | Dropbox,OneDrive(Business) | Dropbox | |
| 文章管理 | Evernote | Evernote | |
| PDF操作 | Adobe Acrobat DC | Adobe Acrobat DC ||
| iOS開発IDE | XCode | なし ||
| Android開発IDE | Android Studio | Android Studio ||
| 開発用テキストエディタ | Microsoft Code Studio | Microsoft Code Studio | |
| 汎用テキストエディタ | CotEditor | Notepad++、Terapad | 全部 Code Studioでいいんじゃないか論もあり |
| Markdownエディタ | Bear、Boostnote,Haroopad | Boostnote | Boostnoteにこの期に切り替えようかな |
| アプリアンインストーラー | AppCleaner | 不要 ||
| Launcher | Alfred3 | 標準の検索機能(Win+S) ||
| FTP/S3 接続 | Transmit、Cyberduck | WinSCP | |
| チャットツール | Slack、LINE | Slack、LINE | |
| ブラウザ | Google Chrome | Google Chrome Canary | Win10のスクロールがうまくいかない問題多発、Canaryにしたら大丈夫だった|
| キーボードカスタマイズ | | changeKey | Alt と Ctrl を交換するために利用。コピペ違和感問題をこれで解決|
| クリップボード拡張 | Paste | Clibor | 見た目がイケてないけどまぁ実用的には耐える |
| 画面キャプチャ編集 | Skitch | Screenpresso | これはむしろWinのほうが機能多い|
| LocalProxyデバッガ | Charles | Charles ||
| Diffツール | CompareMerge | (調査中) ||
| Git操作 | SourceTree | SourceTree ||
| 日本語入力 | Google IME | Google IME | |
| パスワードリマインダ | LastPass | LastPass | |
| ウィンドウリサイズ | WindowTidy | Windowsのデフォルト機能 ||
| ターミナル | Hyper | (調査中,poderosaとか？) ||
| DB操作用 | Sequel Pro | (調査中) ||
| 動画閲覧 | VLC | VLC ||
| 

# その他設定した内容
- 左Altと左Ctrlの位置を入れ替え
- GoogleIMEの動作を変更し、無変換キー＝英数字、変換キー＝ひらがな入力 にするように


# まとめ
あれ、結構WinもMacも両方出てるじゃん・・・
VDOを試してみる　その１

# VDO(Virtual Data Optimizer)について
VDOはRHEL 7.5から導入されたcompressionとdeduplicationを提供するパッケージ。ブロックストレージとファイルシステムの間で動作するため、xfsやext4などのファイルシステムでもZFSのような一部機能が実現可能になる。

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/vdo

# 確認してみる
VDOでのdedupによりパフォーマンスにどの程度の影響が出るか気になるため手元環境で確認してみることにする。

## VDOの導入
CentOS7.4からCentOS 7.5にアップグレードした後にvdoパッケージを導入しようとすると既にインストール済みになっていた。アップデート時に自動的に降ってきていた様子。サービスも自動的に有効になっていた。

```
# yum install vdo kmod-kvdo
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
(snip)
パッケージ vdo-6.1.0.168-18.x86_64 はインストール済みか最新バージョンです
パッケージ kmod-kvdo-6.1.0.168-16.el7_5.x86_64 はインストール済みか最新バージョ ンです
何もしません
```

## VDOボリュームの作成
[RedHatのガイド](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/storage_administration_guide/vdo-quick-start)に従ってVDOボリュームを作成しようとするとエラーになる。

```
# vdo create --name=vdovolume \
  --device=/dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0\:0 \
  --vdoLogicalSize=1T
Creating VDO vdovolume
vdo: ERROR -   Device /dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0:0 excluded by a filter.
```

エラーの詳細を確認してみる

```
# vdo create --name=vdovolume \
  --device=/dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0\:0 \
  --vdoLogicalSize=1T \
  --verbose
Creating VDO vdovolume
    grep MemAvailable /proc/meminfo
    pvcreate -qq --test /dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0:0
vdo: ERROR -   Device /dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0:0 excluded by a filter.
```

どうやら`pvcreate`を実行してディスクをテストしているようなので、そちらでエラーの原因を追いかけてみると`pvcreate`はディスクボリュームに対しては実行できないらしい…fdiskで適当にパーティションを作成してテスト…ok

再度VDOボリュームの作成をしてみようとするもエラー発生。

```
#  vdo create --name=vdovolume \
  --device=/dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0\:0-part1 \
  --vdoLogicalSize=1T
Creating VDO vdovolume
vdo: ERROR - Kernel module kvdo not installed
vdo: ERROR - modprobe: FATAL: Module kvdo not found.
```

あれこれ確認するもうまくいかなかったが、CentOS 7.4から7.5にアップグレードしてから一度も再起動していないことを思い出して再起動。その後に実行するとうまくいった。

```
#  vdo create --name=vdovolume \
  --device=/dev/disk/by-id/usb-I-O_DATA_HDPS-U_XXXXXXXXXXXX-0\:0-part1 \
  --vdoLogicalSize=1T
Creating VDO vdovolume
Starting VDO vdovolume
Starting compression on VDO vdovolume
VDO instance 0 volume is ready at /dev/mapper/vdovolume
```

```
# vdostats
Device               1K-blocks      Used Available Use% Space saving%
/dev/mapper/vdovolume 244197540   3187900 241009640   1%           N/A

# vdostats --human-readable
Device                    Size      Used Available Use% Space saving%
/dev/mapper/vdovolume    232.9G      3.0G    229.8G   1%           N/A
```

とりあえずここまで。
Gitコンフィグについて

###### システム設定
`git config --system --list`
実体はGitのインストールディレクトリのgitconfig配下

###### ユーザ設定
`git config --global --list`
実体はユーザのホームディレクトリの.gitconfig

###### リポジトリ単位の設定
`git config --local --list`
実体はリポジトリ内のgitconfig配下

###### 設定の仕方
`git config --local <キー> <値>`
Androidでチュートリアル表示用のライブラリを作ってみました。


以前こちら [Androidライブラリを作って公開する - Qiita](https://qiita.com/Nabesuke/items/06bc67b6667483a97030) で登録したライブラリについてです。
ライブラリ自体はちょっと前にできあがってたんですが、アップしたり使い方まとめたりが面倒で放置していました。Androidのチュートリアル用ライブラリって中々いいのが無いんですよね。だったら作っちゃえと。
GitHubは[こちら](https://github.com/nabesuke0/BalloonTutorial)です。  
  
弊社のアプリに作ったものをライブラリ用に作り直したものになります。  
kotlin製ですが、もちろんjavaでも使えます。

# 肝心のライブラリについて
こんなやつです。  
  
![sample_tutorial.gif](https://qiita-image-store.s3.amazonaws.com/0/49308/e81a0dfe-9957-3d7f-d5ca-2dd1cfc33975.gif)


  
# 作るにあたって気をつけたこと
完ぺきにできている！とは口が裂けても言えませんが、以下のことに気をつけて作りました。

* ライブラリの依存関係を少なくする
* 簡単に表示できる

### ・ライブラリの依存関係を少なくする
最近ライブラリの一斉アップデートをかけたがために、弊社アプリではたくさんの依存関係のエラーが起きました。しかもエラーの内容がわかりづらいんですよね。それでなんど環境を破壊しようと思ったことか。
結果 `exclude module: hogehoge` の嵐になりました。

そういうことを踏まえてこのライブラリは以下のような依存関係になっています。

```build.gradle
dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

}
```

### ・なるべく簡単に表示できるようにする。
チュートリアルの生成タイミングを気にしなくていいように対象のViewが描画完了した後にチュートリアルを出すようにしています。  
  
ビルダーパターンで表示用の値を設定できるようにしています。  
まだ設定に必須のプロパティなどを統合できてなかったり問題はありますが、、。  

#  使い方
## 簡単に使うなら

- dependenciesに以下を追加してください

```build.gradle
dependencies {
	implementation 'jp.studio.edamame:balloontutorial:0.2.2'
}
```

- 実装はこんな感じ

```kotlin
TutorialBuilder.init(activituy, target = binding.buttonTutorialCircle)
        .holeType(TutorialBuilder.HoleType.CIRCLE)
        .radiusOfDp(50f)
        .descriptionByString("Circle type")
        .buildAndLayout() // 描画
```

こんな形で値を設定していただければ使えます。

## 詳細設定
### ビルダーを初期化

```kotlin
TutorialBuilder.init(activituy, target = targetView)
```

 `.init(activity, targetView)` で初期化します。

### 対象ハイライトする形を指定する

```kotlin
.holeType(type: TutorialBuilder.HoleType)
```

- 四角形

```kotlin
.holeType(TutorialBuilder.HoleType.SQUARE)
```

- 円形

```kotlin
.holeType(TutorialBuilder.HoleType.CIRCLE)
.radiusOfDp(50f) // 円形の場合は半径を指定する(dp)
```
        
### 吹き出しを設定

```kotlin
.descriptionByString("説明が入ります") // 吹き出しの文字
.textColor(@ColorInt color: Int) // 文字色
.balloonColor(@ColorInt color: Int) // 吹き出しの色
```

### タップの動作を指定

```kotlin
.onClickedOutSide { } // ターゲットの外側をタップされたとき
.onClickedTarget { } // ターゲットをタップされたとき
```

### アニメーションの時間を指定
- msecで指定

```kotlin
.durationForBaseAnimation(150) // 背景の表示
.durationForHoleAnimation(300) // ハイライトの表示
.durationForBalloonTextAnimation(200) // 吹き出し
```

# おわり
いずれ連続でチュートリアル出せるような仕組み追加しようかなと考えてます。
以上です。
app-module-pathに苦しめられた話

## 何が起きたか
[app-module-path](https://github.com/patrick-steele-idem/app-module-path-node)を使用しているリポジトリBをpackage.jsonに設定したら、リポジトリB内の参照パスが解決できずに困った

```
リポジトリA
├── package.json
│    "devDependencies": {
│    "リポジトリB": "git+ssh:~",
└── node_modules/
    └── リポジトリB/
        └── package.json
        "dependencies": {
        "app-module-path": "^1.1.0",
```

## 概要
このライブラリは、対象ディレクトリの相対パスをNODE_PATHに追加してくれるもの

```js:これが
require('../../../../hoge')
```

```js:こう書ける
require('hoge')
```

## 問題
ただしv1.1.0の場合、対象ディレクトリパスに`node_modules`が含まれているときはNODE_PATHに追加してくれない。

- `/example/node_modules/hoge` => NG
- `/example/hoge` => OK

>indexOfを使って追加するか否かを判定しているせい
 `if (from.indexOf('node_modules') === -1) `

つまりリポジトリをpackage.jsonに追加してると、
もれなく`node_modules`配下に追加されちゃうので、使い物にならなくなる。

## 解決法
v2.2.0にアップデートすればOk。

`indexOf`を使用した判定（ディレクトリパスを含む）から
`basename`を使用した判定（ディレクトリパスを含まない）に変えてくれたおかげで解決する。
> [basenameリファレンス](https://nodejs.org/api/path.html#path_path_basename_path_ext)

対象のissueはこちら：[Fix for applications installed globally · Issue \#19 · patrick\-steele\-idem/app\-module\-path\-node](https://github.com/patrick-steele-idem/app-module-path-node/issues/19)

## まとめ
相対パスくらいめんどくさがらずに書いてた方がライブラリのバグに巻き込まれなくて済んだ
Macのタグをつけるコマンド、外すコマンド

Macの拡張属性のタグを、コマンドから付けたい。
付けたくないですか？
私は付けたいです。

# タグとは

MacのFinderにOSX 10.9から搭載されている機能です。（その際にラベル機能が失われました）

![タグサンプル.png](https://qiita-image-store.s3.amazonaws.com/0/33347/64c469db-c3df-69bc-de1b-3cc2abb86f5f.png)

Spotlightで検索するのとは異なり、タグでフィルターを掛けて調べたりできます。
画像のように複数つけることも出来ますし、もちろんファイルにもつけることができます。
上記の画像で言えば、Finder左の「タグ」でグリーンを選択すると「学校」「息子」「旅行」が引っかかります。

# やりたいこと

成功したファイルと失敗したファイルに対し、動的にタグを付けたい。

![タグサンプル3.png](https://qiita-image-store.s3.amazonaws.com/0/33347/123b301c-0850-9341-d3d0-53ab76a6265e.png)


やりたいことのイメージは画像のとおりです。
成功したら青。
失敗したら赤。
同一ファイルに複数付けることが出来るというタグの機能の一部しか使わないですが、見た目にも調べやすくなるからかそのような要望がありまして。

# いざ、タグを付ける

赤色のタグを付ける

```shell
$ xattr -wx com.apple.FinderInfo "0000000000000000000D00000000000000000000000000000000000000000000" filename
```

青色の場合は`"0000000000000000000900000000000000000000000000000000000000000000"`です。
filenameにはスペース区切りで連続してファイルのパスを書けば、複数一括で同じタグを付けることができます。

# タグを消したい
一度テストをして赤タグを付けたものに対して、再テスト時に成功したなら青タグを付けたいです。
タグは複数付けることが出来るので、付けるだけだと赤と青の両方が付いてしまうため、削除も必要です。

```shell
$ xattr -c filename
```

でも、このコマンドだとその他の拡張属性が全て消えてしまう気がするんですよね。
今回はそれでも構わないそうですが、気になるところ。

そこは宿題ということで。
JWTについて

# Json Web Token

JWT→ジョットと発音する

JWTは、ヘッダー（Header）、ペイロード（Payload）、署名（Sinature）をピリオドで区切った文字列。

###### ヘッダー

```json
{
  "typ": "JWT",　　// 固定値
  "alg": "HS256"　// 署名アルゴリズム HS256で良い
}
```
これをBase64urlエンコードする。

###### ペイロード
JSONをBase64urlエンコードした文字列
個々の項目名をクレームと呼ぶ

* 予約クレーム

|クレーム|説明|
|:--|:--|
|iss|JWT発行者|
|sub|JWT発行者から払い出されたユーザ識別子。文字列またはURIで表わされる。⇒社員番号を設定|
|aud|JWTを利用することが想定された主体の識別子一覧|
|exp|JWTの有効期限を示す。⇒有効期限を設定|
|nbf|JWTが有効になる日時を示す|
|iat|JWTを発行した時刻を示す|
|jti|JWTのための一意な識別子。JWTのリプレイを防ぐことに利用する|
|typ|typヘッダパラメータと同じ値空間および同じ規則が適用される|

* パブリッククレーム

IANA JSON Web Token Claim Registryに登録された上記以外のクレーム

* プライベートクレーム

上記以外の独自に作ったクレーム

###### 署名
エンコード済みヘッダー、ピリオド（"."）、エンコード済みペイロードを連結したものを入力値として、"alg"の署名アルゴリズムで署名し、Base64urlエンコードした文字列

###### クライアント側の実装例
サーバから受け取ったJWTをクッキー or ローカルストレージに保存する
API実行時にJWTをヘッダのAuthorizationキーの値に設定する。
`Authorization: Bearer <JWT>`
※Bearerスキームが一般的

ローカルストレージの使い方

```javascript
localStorage.setItem("message", "こんにちはlocalStorage"); // 設定
localStorage.getItem("message"); // 取得
localStorage.clear(); // 削除
```

セッションストレージの使い方（ウインドウやタブを閉じるまで有効）

```javascript
sessionStorage.setItem("message", "こんにちはlocalStorage"); // 設定
sessionStorage.getItem("message"); // 取得
sessionStorage.clear(); // 削除
```

###### 認証サーバ側の実装例
認証OKの場合、redisにユーザIDをキーにデータを登録する。JWTを生成してクライアントに送付する。

リクエストヘッダのJWTを検証する。
JWTが不正 or 有効期間(24時間)が切れていた場合、ログイン画面を表示する。
ユーザIDに紐づくセッション情報がredisに存在するかどうかを確認する。
redisデータが存在しない、redisデータの有効期限が切れている(60分)場合、ログイン画面を表示する。
ログアウト時にredisのセッション情報を削除する。
Autodesk Forgeことはじめ

# はじめに
AutodeskのForgeはいってみればBIMのリポジトリとビューワ、APIが一体化したサービスである。オープンソースのBIMサーバもあるが、変換機能などAPIの拡充具合を考慮するとこのサービスを使うのが一番良いように思う。RevitやIFC、OBJなど多様なファイルへのインポート、エクスポートも可能だ。現在無料だし。

# 認証について
Autodeskアカウントを作って、Forgeのサービスにログインし、まずはApplicationを作る。ここで作ったClient IDとClient Secretがポイントで、OAuthの認証に利用される。URLは何でもよいのでとりあえず入れておく必要がある。
まずは面倒だけれど、サンプルに沿ってcurlで認証をしてみよう。認証のAPIの仕様は以下となっている。
https://developer.autodesk.com/en/docs/oauth/v2/reference/http/authenticate-POST/

## アクセストークンの取得
まずは取得したID、Secretを使ってアクセストークンを取得しないといけない。-d以下のパラメータにそれらを記述する。一番最後のscopeは、アクセスしているアプリ、ユーザの権限を示すもので、空欄で区切っていくつか入力できる。今回はすべてのデータにへアクセス、アップロードなどが可能なdata:readとdata:writeを二つ指定している。

```
curl -v 'https://developer.api.autodesk.com/authentication/v1/authenticate' 
  -X 'POST'
  -H 'Content-Type: application/x-www-form-urlencoded'
  -d 'client_id=xxxxxxxxxxxxxxxxx&client_secret=xxxxxxxxxxxxx&grant_type=client_credentials&scope=bucket:create data:read data:write'
```

これがうまくいくと、以下のようにアクセストークンが得られる。これをメモしておく。

```
{"access_token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","token_type":"Bearer","expires_in":3599}`
```

# ファイルのアップロード
取得したアクセストークンを使って、IFCなどのBIMデータをアップロードする。ちなみにアップロードしたファイルにはリテンションポリシーが設定できる。transientとすると24時間でデータが消えるようになる。APIの仕様は以下。
https://developer.autodesk.com/en/docs/data/v2/reference/http/buckets-POST/

## Bucketの作成
アップロードに先立って、ファイルの入れ物(Bucket)を作成する。先ほどのアクセストークンを使って、リクエストする。bucketKeyは何でもよいのだが、他と被っていると怒られる。GUIDやクライアントIDなどを生成して、後ろに適当につけるとよい。

```
curl -v 'https://developer.api.autodesk.com/oss/v2/buckets' 
  -X 'POST' -H 'Content-Type: application/json'
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
  -d '{"bucketKey":"mybucket_xxxxxx","policyKey":"transient"}'
```

成功すると以下の感じのレスポンスがある。

```
{"bucketKey":"mybucket_xxxxxx","bucketOwner":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","createdDate":1528027336176,"permissions":[{"authId":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx","access":"full"}],"policyKey":"transient"}
```

## ファイルのアップロード
Bucketができて、ようやくBIMデータのアップロードができる。Contents-Lengthは必須だそうだが、普通のクライアントは自動的に追加すると思われる。ここではHelloWall.ifcというファイルをアップした。

```
curl -v 'https://developer.api.autodesk.com/oss/v2/buckets/mybucket_xxxxxx/objects/HelloWall.ifc'
  -X 'PUT'
  -H 'Authorization: Bearer xxxxxxxxxxxxxxxxxxxxx'
  -H 'Content-Type: application/octet-stream'
  -H 'Content-Length: 100000000 ファイルのサイズ(byte)'
  -T 'HelloWall.ifc'
```

これもうまくいくと以下のようなレスポンスがある。

```
{
  "bucketKey" : "mybucket_xxxxxx",
  "objectId" : "urn:adsk.objects:os.object:mybucket_xxxxxx/HelloWall.ifc",
  "objectKey" : "HelloWall.ifc",
  "sha1" : "6b6acf973e033af4aea85158b106adedef30cd1f",
  "size" : 6033,
  "contentType" : "application/octet-stream",
  "location" : "https://developer.api.autodesk.com/oss/v2/buckets/mybucket_xxxxxx/objects/HelloWall.ifc"
* Connection #0 to host developer.api.autodesk.com left intact
}]
```

ここまでの作業は一応手でやってみたが、サンプルプログラムでは自動的にその辺をやっている。NodeJSのサンプルビューワを起動すると、先ほどのファイルがアップされているのがわかる。
<img width="938" alt="無題.png" src="https://qiita-image-store.s3.amazonaws.com/0/51703/658670f7-310d-2c61-2b22-8499268bf5b5.png">

まずはここまで。
デスクトップPCにBluetoothを使ってモーションコントローラーの認識に苦戦した話。

環境的なもの　

Windows10　現時点で最新アップデート済み

Bluetoothアダプタ→　[【Newiy Start】bluetooth アダプタ windows10 apt-x対応 bluetooth レシーバー usb アダプター 小型 Ver4.0 EDR/LE対応(省電力) Class2 ブルートゥース ドングル(改良版)](https://www.amazon.co.jp/gp/product/B078W4L79S/ref=oh_aui_detailpage_o04_s00?ie=UTF8&psc=1)

----

・付属のCDからインストール　

【上手くいかない】

SRS-X1とかなら普通に接続できた。　コントローラー類は認識はするがペアリングができなかった。


---
・調べるとCDからインストールしなくても使えるらしい

→　試してみる
→　接続されている　という点での認識はしている
→　でもタスクバーにアイコンはでていない
→　結果：うまくいかない

---
・原因分からずmiracastに対応してないから？

→　アクションセンター（windows10なら右下にある吹き出しマークみたいなやつ）から接続選ぶ
→　Bluetoothが有効になってないといわれる、　デバイス自体は認識しているしドライバも最新だし、正常動作ともかいているのに。
→　繋げられたからわかったこと：　miracastは関係ない

---
#どうやって解決したか

→　デバイスマネージャを開く
→　CSR8510　A10を探す。　もしくはBluetoothという項目
→　ドライバのアンインストールする
→　さしなおす、すると違う項目で似たようなのが出てくる（キャプチャし忘れた）
→　自分の場合2~3回同じことした

するとこれがでてきた


![無2.png](https://qiita-image-store.s3.amazonaws.com/0/158551/73c903e2-877a-c276-5d57-eb624444da46.png)
1つか2つしかでてこなかったのに抜き差し繰り返してたらこんなにでてきた。

もしやとおもってタスクバー見たらこれもでてきた

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/158551/e49d00d3-54a4-5f40-b293-ce123c72a62f.png)

そしてパソコンのBluetoothと他のデバイスってところを見るとBluetoothのスイッチ　【〇⊃】　なんかこういうやつが追加されて
結果繋げるようになった！！！

とりあえずうれしかった！

これ関係で3日以上悩んでた。。
[C#] 配列をシャッフルする方法

#配列の要素をシャッフルしたい
配列の要素をシャッフルして試験したいときありませんか？
自分はありました。
そのときに使ったプログラムをメモします。

```C#
using System;
using System.Linq;

namespace random
{
    class Program
    {
        static void Main(string[] args)
        {
            /// <summary>
            /// 試行パターン番号配列の基本配列
            /// </summary>
            //int[] basicArray = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
            int[] basicArray = Enumerable.Range(1, 20).Select(n => (int)n).ToArray();
            /// <summary>
            /// 試行パターン番号配列
            /// 試行パターン番号配列の基本データの要素の順番をシャッフルした結果
            /// </summary>
            int[] trialPatternArray = basicArray.OrderBy(i => System.Guid.NewGuid()).ToArray();

            // コンソールに出力
            foreach (int element in trialPatternArray)
            {
                System.Console.WriteLine(element);
            }
            Console.ReadKey();
        }
    }
}
```

実行結果は以下の通り。

```result
3
11
15
1
20
18
19
12
16
6
2
14
17
13
5
4
10
8
9
7
```

これで配列要素をシャッフルできます。
How-to: Arch Linux Extra/emacs 24.2-4 で日本語を入力する

> [!NOTE]
> この記事は 2013/02/24 に [momoto.github.io](http://momoto.github.io/) へ投稿した内容を Qiita へ移行してきたものです

　Arch Linux の Emacs で日本語を入力するための設定の記録です。この方法では、Emacs の他、UIM等の入力メソッドフレームワークと、Anthy や Mozc 等の入力メソッドがインストールされている必要があります。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/58/1c6079d4-94bb-59de-7d8d-676c181545a5.png)

UIM と Anthy (UTF-8) を使用する場合、次のパッケージをインストールします:

 -  [extra/anthy](https://www.archlinux.org/packages/extra/x86_64/anthy/)
    Hiragana text to Kana Kanji mixed text Japanese input method

 -  [extra/uim](https://www.archlinux.org/packages/extra/x86_64/uim/)
    Multilingual input method library

上記のパッケージをインストールした状態で、下記の設定をEmacs設定用ファイルに追記します。

```:Emacs設定用ファイル
;; uim /usr/share/emacs/site-lisp/uim-el/uim-leim.el
(require 'uim-leim)
(setq default-input-method "japanese-anthy-utf8-uim") ; Anthy (UTF-8)
;(setq default-input-method "japanese-mozc-uim")      ; Mozc
```

Mozcを使用する場合、次のパッケージをインストールします:

 -  [pnsft-pur/emacs-mozc](https://aur.archlinux.org/packages/emacs-mozc/)
    Mozc for Emacs

 -  [pnsft-pur/ibus-mozc](https://aur.archlinux.org/packages/ibus-mozc/)
    IBus engine module for Mozc

 -  [pnsft-pur/mozc](https://aur.archlinux.org/packages/mozc/)
    A Japanese Input Method for Chromium OS, Windows, Mac and Linux (the Open Source Edition of Google Japanese Input)

上記のパッケージをインストールした状態で、下記の設定をEmacs設定用ファイルに追記します。

```:Emacs設定用ファイル
;; emacs-mozc /usr/share/emacs/site-lisp/emacs-mozc/mozc.el
(require 'mozc)
(setq default-input-method "japanese-mozc")
(setq mozc-candidate-style 'overlay) ; Mozc overlayモード
```

## 参考

- [Input Japanese using uim – ArchWiki](https://wiki.archlinux.jp/index.php/uim_を使って日本語を入力)
- [Mozc – ArchWiki](https://wiki.archlinux.jp/index.php/Mozc)
How-to: Arch Linux 2012.12.01 をインストールする

> [!NOTE]
> この記事は 2013/01/05 に [momoto.github.io](http://momoto.github.io/) へ投稿した内容を Qiita へ移行してきたものです

　Arch Linux 2012.12.01をインストールした手順の記録です。インストールメディアは [archlinux-2012.12.01-dual.iso](https://www.archlinux.org/releng/releases/2012.12.01/) を使用しています。 [Installation Guide (日本語) – ArchWiki](https://wiki.archlinux.jp/index.php/インストールガイド) の内容と重なる部分が多いですが、自分なりに注釈を加えて記録します。

　インストールにはインターネットに接続できる環境が必要です。また、パーティションの構成やインストールするブートローダをあらかじめ決めておく必要があります。次の手順ではパーティションテーブルに GPT を使用し、ブートローダには GRUB2 をインストールしています。

## 1. キーボード配列の指定

使用しているキーボード配列を指定する。ここで行う設定はインストールを行う間の一時的なものであるため、インストール後には改めて設定する必要がある。

```:日本語のキーボード配列（JP106）の設定
root@archiso ~ # loadkeys jp106
```

## 2. ストレージデバイスの設定

接続しているストレージデバイスのパーティショニング、フォーマット、マウントを行う。

パーティショニングはインストールメディアに含まれているパーティショニングツールを使用して行う。その際、パーティションテーブルの規格（MBR、GPT）によって使用するツールは異なる。

```:/dev/sdxのパーティショニング
root@archiso ~ # gdisk /dev/sdx
```

フォーマットは `mkfs` を使用して行う。ここでフォーマット対象のパーティションとファイルシステムを指定する。

```:作成したパーティションのフォーマット
root@archiso ~ # mkfs.ext4 /dev/sdx1
```

マウントは /mnt に root パーティションが対応するようにして行う。boot パーティションであれば /mnt/boot へマウントする。

```:作成したパーティションのマウント
root@archiso ~ # mount /dev/sdx1 /mnt
```

## 3. Arch Linux システムのインストール

　Arch Linuxのシステムをインストールする。インストール後に行える設定（ホスト名やタイムゾーンの設定）については省略する。

　pacstrapを使用して、[base](https://www.archlinux.org/groups/x86_64/base/) と [base-devel](https://www.archlinux.org/groups/x86_64/base-devel/) のパッケージをインストールする。その際、国内のミラーサーバーからパッケージをダウンロードするように mirrorlist を編集する。日本のミラーサーバーには [tsukuba.wide.ad.jp](http://ftp.tsukuba.wide.ad.jp/Linux/archlinux/) と [jaist.ac.jp](http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/) がある。

```:mirrorlistの編集とシステムのインストール
root@archiso ~ # vi /etc/pacman.d/mirrorlist
root@archiso ~ # pacstrap /mnt base base-devel
```

`genfstab` を使用して、fstabを生成する。

```:fstabの生成
root@archiso ~ # genfstab -U -p /mnt >> /mnt/etc/fstab
```

`arch-chroot` を使用して、新しいシステムの環境へ移動する。移動後には再度、使用しているキーボード配列を指定する。

```:ルートディレクトリを変更
root@archiso ~ # arch-chroot /mnt
```

ブートローダのインストールと設定を行う。ここでの手順はブートローダによって異なる。

```:GRUB2のインストール
sh-4.2# pacman -S grub2-bios
sh-4.2# grub-install /dev/sda
sh-4.2# grub-mkconfig -o /boot/grub/grub.cfg
```

```:Syslinuxのインストール
sh-4.2# pacman -S syslinux gptfdisk
sh-4.2# vi /boot/syslinux/syslinux.cfg
sh-4.2# syslinux-install_update -i -a -m
```

## 4. アンマウントと再起動

　chroot環境を終了させて、上の手順でマウントしたパーティションをアンマウントする。その後、システムを再起動してインストールが完了する。

```:chrootの終了、パーティションのアンマウント、再起動
sh-4.2# exit
root@archiso ~ # umount /mnt
root@archiso ~ # reboot
```

## インストール後のシステム設定

再起動の後、インストール時に省略した設定を行う。

```:ホスト名の設定
echo myarchlinux > /etc/hostname
```

```:タイムゾーンとハードウェアクロックの設定
ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
hwclock --systohc --utc
```

```:新しいユーザーの追加とそのパスワードの設定
# useradd -m -g users -G wheel -s /bin/bash guest
# passwd guest
```

## 参考

- [インストールガイド – ArchWiki](https://wiki.archlinux.jp/index.php/インストールガイド)
- [Arch ブートプロセス - ArchWiki](https://wiki.archlinux.jp/index.php/Arch_ブートプロセス)
- [パーティショニング - ArchWiki](https://wiki.archlinux.jp/index.php/パーティショニング)
How-to: Amazon Linux AMI の EC2 インスタンスを作成する

> [!NOTE]
> この記事は 2012/12/06 に [momoto.github.io](http://momoto.github.io/) へ投稿した内容を Qiita へ移行してきたものです

　Amazon EC2 インスタンスを作成し、SSH接続するまでの手順の記録です。

## Amazon EC2 インスタンスの作成

　Amazon EC2 Console Dashboardから「Launch Instance」を選択する。 必要な操作はすべてウェブインタフェースから行うので、ブラウザさえあればEC2インスタンスを作成することができる。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/58/35a44fe5-3c72-682d-8aa8-bc6cd2e8afb8.png)

　インスタンス作成ウィザードの種類を選択する。 2012年12月現在、選択できる種類はClassic、Quick Launch、AWS Marketplaceの三通り。 以下、Classic Wizardでインスタンスの作成を行う。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/58/71a472a3-187e-8f76-ce64-8a675421d608.png)

　AMI（Amazon Machine Image）を選択する。 選択できる主なOSにはRed Hat Enterprise、Ubuntu、Microsoft Windowsなどがある。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/58/805adb19-02b1-846d-149c-ed059f9a6a95.png)

　インスタンスの詳細を設定する。 設定できる項目は、インスタンスタイプ、カーネルID、RAMディスク、ストレージデバイスなど。

![04-01.png](https://qiita-image-store.s3.amazonaws.com/0/58/18fe5168-bb25-3953-153d-add4872f668f.png)

![04-02.png](https://qiita-image-store.s3.amazonaws.com/0/58/a02df35f-c096-a4dd-eb52-69e93a3c3e3f.png)

![04-03.png](https://qiita-image-store.s3.amazonaws.com/0/58/ac541ae4-11f4-f143-f020-97b97b6ef9de.png)

　インスタンスタイプは、その種類によって性能（CPUやI/O）や発生する費用が異なってくるため、稼働させるアプリケーションや予算にあわせて選択する。

　公開鍵暗号の鍵のペアを作成する。 ウィザードには鍵の名前を入力するだけでRSA暗号方式の鍵のペアが生成され、pemファイルをダウンロードできる。 このpemファイルがSSH接続に必要な秘密鍵になる。

![05.png](https://qiita-image-store.s3.amazonaws.com/0/58/1fb47c7d-42d2-9a3f-c9c1-8d7509d6da66.png)

　EC2のファイアウォール「Security Groups」を設定する。 グループごとにプロトコル（HTTPやSMTP）、ポート番号、IPアドレスを指定してインバウンドルールを設定することができる。

![06.png](https://qiita-image-store.s3.amazonaws.com/0/58/9c4a702a-874a-e9d0-dcaf-70b942c00f62.png)

　EC2インスタンスが完成。ダッシュボードの”Instances”から起動状態や公開ドメイン名などを確認できる。

![07-01.png](https://qiita-image-store.s3.amazonaws.com/0/58/f81fb751-9018-099e-3f13-077aa45710c8.png)

![07-02.png](https://qiita-image-store.s3.amazonaws.com/0/58/158013e2-e32e-6228-30d1-da5cc73de9f0.png)

## SSH接続

　SSHクライアントからEC2インスタンスへSSH接続を行う。 接続先に公開ドメイン名（Public DNS : ec2-***–***–***–***.compute-1.amazonaws.com）と、秘密鍵には先に取得したpemファイルを指定して、EC2インスタンスへ接続する。

![08.png](https://qiita-image-store.s3.amazonaws.com/0/58/dff9b17a-bd9f-4393-2e54-8e34a82ca2c4.png)

## EC2インスタンスの終了

　EC2インスタンスの利用を終える場合は、終了（Terminate）を指定する。停止（Stop）ではインスタンスは削除されない。 逆に、利用を一時的に停止するだけであれば Terminate ではなく Stop を指定する。

![09.png](https://qiita-image-store.s3.amazonaws.com/0/58/ef3a940b-97d1-9445-2b53-b85caf12aaf0.png)

## 参考

- [Amazon EC2 (仮想サーバー Amazon Elastic Compute Cloud) | アマゾン ウェブ サービス（AWS 日本語）](https://aws.amazon.com/jp/ec2/)