OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでGoogle Homeに任意の言葉を発話させる(flask版)

<img width="532" alt="Qiita投稿用_key.png" src="https://qiita-image-store.s3.amazonaws.com/0/15264/144645e0-c596-d431-aaa1-79ccfb6739ef.png">

# TL;DR(まとめ)

* gTTS,pychromecastでGoogleHomeに任意の言葉を発話させた
* Node.jsのgoogle-home-notifierを使わず、Pythonのみで構築した
* 発話mp3ファイルを提供するために、flaskサーバをRaspberry Pi上に用意した
 
# 前提(環境)
## 機材
Google Homeが存在するものとします。(ipは192.168.1.3)※Google Homeアプリから把握しましょう。
Raspberry Pi3B+を開発環境、及びmp3提供元とします。(ipは192.168.1.7)

## 主要ソフトウェア
python 3.5
pychromecast 3.0.0
gTTS 2.0.3
flask 1.0.2
pipでインストールしてください。venvで別環境作るほうが私は好きですが。

# 構築内容
pychromecastを使えば、任意のmp3ファイルを再生できます。
ただ、mp3ファイルをGoogle Home内に配置できません。
そのため、mp3ファイルはRaspberry Pi内に用意して、それをWebサーバが提供する形にします。
任意の言葉をmp3ファイルにするためには、gTTS(google text to speech)を使います。
必要なところから読んでください。

# 構築手順
## 各種Pythonモジュールインストール
事前準備1/3

```pythonモジュールインストール
$ pip install pychromecast, gTTS, flask
```

## 発話させるmp3ファイルを作成
事前準備2/3
任意のディレクトリに移動して、以下を実行します。
これだけで音声ファイルが出来上がります。便利。

```mp3ファイル作成
$ python
>>> from gtts import gTTS
>>> tts = gTTS(text='こんにちは', lang='ja')
>>> tts.save('greeting.mp3')
```


## Flaskサーバの立ち上げ 
事前準備3/3
mp3ファイルを配置した箇所と同じディレクトリに以下のmp3server.pyを作成しましょう。
FlaskでWebサーバを用意し、GETのリクエストに対応するmp3ファイルがあったらそれを返す形です。
hostを0.0.0.0にしておくことで、他のホストからアクセス可能にします。


```python:mp3server.py
import os
from flask import Flask, make_response
app = Flask(__name__)

@app.route("/mp3/<string:file_name>", methods=['GET'])
def getMP3File(file_name):
    response = make_response()

    if not os.path.exists(file_name):
        return response
    
    response.data = open(file_name, "rb").read()
    response.headers['Content-Disposition'] = 'attachment; filename=' + file_name 
    response.mimetype = 'audio/mp3'
    return response

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=8080)
```

作成したらWebサーバとしてバックグラウンド実行しておきましょう。

```shell
$ nohup python mp3server.py > ~/out.log &
```

## main
さていよいよmain部分です。以下main.pyファイルを作成したら
python main.pyで実行してください。「XXX」で囲まれている部分を環境に合わせて設定してください。
mp3ファイルが存在し、かつGoogleHomeの音量が適切に設定されていれば、「こんにちは」と話すでしょう。

```python:main.py
import pychromecast

def send_to_chromecast(file_name, target_cast_ip, mp3server_ip_port):
  # mp3 file path.(hosted on raspberry pi)
  mp3_url = 'http://' + mp3server_ip_port + '/mp3/' + file_name
  cc = pychromecast.Chromecast(target_cast_ip)
  cc.wait()
  mc = cc.media_controller
  mc.play_media(mp3_url,'audio/mp3')
  return

def main():
  file_name = 'greeting.mp3'
  send_to_chromecast(file_name = file_name, target_cast_ip='XXX192.168.1.3XXX', mp3server_ip_port='XXX192.168.1.7:8080XXX')

if __name__ == '__main__':
  main()
```

main()関数の部分でsend_to_chromecast()関数を呼び出していますが、
呼び出し直前部分でgTTSによる音声ファイル作成のコードを入れると任意の言葉を発話しますね。
なお、Flask部分をわざわざ分割したのは再利用性を気にしたためです。
実際後でmain.pyの方をcron実行したかったのでね。それにこの方がソースの説明も簡単ですし。

参考になれば幸いです。

# 参考
[Pythonを使って、Google Homeに喋らせてみる](https://qiita.com/attakei/items/c5de47f3c1f53992c353)
UIButtonをdeclarativeに扱う


vueとかanglureとか触ってるとSwiftでボタン定義するのすごくだるいなと思う。(mac book airなのでIBは触りたくない）


``` .html
<button ng-click="ctrl.onClick">anglure</button>
<button v-on:click="say('what')"> vue </button> 
```

だからButtonクラスを作ってちょっとだけ楽してみた。

``` .swift
final class ViewController: UIViewController {

    private lazy var button = Button(
        title: "click",
        backgroundColor: .blue,
        parent: view,
        onClick: onClickButton
    )

    private var onClickButton = {
        print("tap")
    }
}
```

---

ちなみにself参照するときはweakつけないとなーくらいに思ってたんでずけど、

``` .swift

  private var onClickButton = { [weak self] in
       self?.hogehoge()
  }
```

関数を渡してあげると、buttonが解放されなかった。なんででしょうか・・

``` .swift
final class ViewController: UIViewController {

    private lazy var button = Button(
        title: "click",
        backgroundColor: .blue,
        parent: view,
        onClick: tapButton
    )

    private func tapButton() {
        print("tap")
    }
}
```

<details><summary>ソースはこれです</summary><div>

``` .swift
final class Button: UIButton {
  
    convenience init(
        title: String = "",
        color: UIColor = .darkGray,
        backgroundColor: UIColor = .clear,
        parent: UIView? = nil,
        onClick: (() -> Swift.Void)? = nil
        ) {
        self.init(frame: .zero)
        
        addTarget(self, action: #selector(actionClick), for: .touchUpInside)
        setTitle(title, for: .normal)
        setTitleColor(color, for: .normal)
        self.backgroundColor = backgroundColor
        clickHandler = onClick
        parent?.addSubview(self)
    }
    
    private var clickHandler: (() -> Swift.Void)?
    
    @objc private func actionClick() {
        clickHandler?()
    }
}

```
</div></details>



Swiftでもこうやってかけるようにしてみようかな・・


``` .swift
    private lazy var label = Label(
        textColor: .darkGray,
        parent: view,
        bind: store.state.text
    )
```


## 昔ちょこっと試してた初期化方法(おまけ)

### lazyで初期化

基本的にはこれで初期化している。Extensionを使ってないから普通にSnipetにしてどこでも使える。

``` .swift
final class ViewController: UIViewController {

    private lazy var button: UIButton = {
        let b = UIButton()
        b.setTitle("button", for: .normal)
        b.addTarget(self, action: #selector(actionTap), for: .touchUpInside)
        ...
        return b
    }()
    
    @objc private func actionTap() {
        print("button touch up inside")
    }
}
```


### メソッドチェーンで初期化

メソッドチェーンでかけるExtensionを作ってKotlinのスコープ関数のように初期化してみたり

``` .swift
final class ViewController: UIViewController {

    private lazy var button = UIButton().apply { $0
        .setTitle("button", for: .normal)
        .addTarget(self, action: #selector(actionTap), for: .touchUpInside)
        ...
    }
    
    @objc private func actionTap() {
        print("button touch up inside")
    }
}
```


###　AddTargetのみ省略
RxSwiftの```button.rx.tap```が便利だったので
NotificationCenterやocjcの黒魔術を使ってaddTargetのみ省略したり

``` .swift
final class ViewController: UIViewController {
    
    private var button = UIButton()
    
    private func setUpButton() {
        button.setTitle("button", for: .normal)
        button.onTap = {
           print("button touch up inside")
        }
    }
}
```
Qiita投稿目的・練習

#Qiita投稿の目的
・社会人2年目として何かしらやるため
・自分のやったことの備忘録
・共有のplatformとして利用
・モチベーション

#投稿内容
・基本はクラウド（GCP、AWS、Azure）
・その他興味のある言語（Python、GO、GAS、JS等）

#A
##AA
###AAA
1.aaa
2.bbb
- []チェックポックス
-[x]checkbox
- [ ] チェックボックス
- [x] チェックボックス
**AAA**
*AAA*
~~AAA~~
`AAA`
>AAA
>>AAA
[title](http://...)
![alt](http://...)
-------------

```ruby:qiita.rb
puts 'code with syntax'
```

| Left align       |       Right align |    Center align    |
|:-----------------|------------------:|:------------------:|
| This             |              This |        This        |
| column           |            column |       column       |
| will             |              will |        will        |
| be               |                be |         be         |
| left             |             right |       center       |
| aligned          |           aligned |      aligned       |
ストレージからフォルダ丸ごとコピーするバッチファイル 

# はじめに
ほぼ毎朝フォルダごとローカルにコピーすることがあるので自動化しました。使うだけであれば**まとめ**をご覧ください。

# この記事で紹介すること
- フォルダのコピー
- 最新フォルダの特定
- まとめ
- 補足：自動化手順

# フォルダのコピー
ストレージ```\\hoge\hogehoge\kore```の```kore```フォルダ以下をバッチファイルのある場所にコピーしたい。
以下サンプルでデスクトップに```kore```フォルダが作られ、中身がコピーされる。

```bat(dos)
@rem 【コピー元パス】.
set StoragePass=\\hoge\hogehoge\kore
@rem 【コピー先パス】.
set LocalPass=C:\Users\namae\Desktop\kore
@rem 実行.
xcopy "%StoragePass%" "%LocalPass%" /s/e/i
```
オプション（```/s/e/i```）に関して詳しくは[こちら](https://www.palm84.com/entry/20150525/1432550334)

# 最新フォルダの特定
ストレージにどんどん新しいものが作られる状況があるはず。。
タイムスタンプを見て最新フォルダを特定しましょう

```
@rem 最新版のフォルダを検索.
@rem 初期値は十分に古ければ問題ない.
set Latest_Timestamp="2018/01/01 00:00"
set StoragePass=\\hoge\hogehoge

setlocal EnableDelayedExpansion
for /F %%a in ('dir /B /A:D /O-N "%StoragePass%"') do (
	set DirName=%%a
	for %%i in ( "!StoragePass!\!DirName!" ) do (
		if !Latest_Timestamp! lss %%~ti (
			set Latest_Timestamp=%%~ti
			set Latest_dir=!DirName!
		)	
	)
)
echo %Latest_dir%
pause
```

これで```\\hoge\hogehoge```にある最新のフォルダ名が得られる。

# まとめ
二つを組み合わせると**ストレージにある最新フォルダを丸ごとコピー**できるようになります。
パスの登録バッチと実行バッチを分けると不幸な事故を防げます。
同じフォルダに```user_settings.bat```,```copy.bat```,```get_latest_dir.bat```を置いて、```copy.bat```を叩きましょう。

```user_settings.bat
@rem 【コピー元パス】.
set StoragePass=\\hoge\hogehoge
@rem 【コピー先パス】.
set LocalPass=%~dp0
```

```get_latest_dir.bat
echo off
@rem copy.batの方でEnableDelayedExpansionを読んでいるのでここでは不要.
@rem setlocal EnableDelayedExpansion

@rem 最新版のファイルを検索.
set Latest_Timestamp="2018/01/01 00:00"

for /F %%a in ('dir /B /A:D /O-N "%StoragePass%"') do (
	set DirName=%%a
	
	for %%i in ( "!StoragePass!\!DirName!" ) do (
		if !Latest_Timestamp! lss %%~ti (
			set Latest_Timestamp=%%~ti
			set Latest_dir=!DirName!
		)	
	)
)

goto END

:END
```


```copy.bat
echo off
setlocal EnableDelayedExpansion
if not exist user_settings.bat (
    echo user_settings.bat が見つかりません。
    goto END
)

@rem 設定値の取得.
call user_settings.bat

@rem 最新版のファイルを検索.
call get_latest_dir.bat

@rem 指定フォルダ以下をコピー.
xcopy "!StoragePass!\!Latest_dir!" "%LocalPass%!Latest_dir!" /s/e/i/y
goto END

:END
pause
```
# 補足：自動化手順
バッチファイルを作ったけど毎回叩くのめんどくさいという人も多いと思います。
そんな時はタスクスケジューラを使えば指定した時間に実行してくれます。
意外と設定でミスってしまうことがあるので[こちら](https://delightmode.com/win-taskscheduler/)を見てやってみてください。
（私は作業フォルダーの設定を忘れて苦しみました。。）

# おわりに
初心者なので、解説もなくリンクを張った備忘録みたいになってしまいましたが、もっとこうしたほうが良いなどコメント頂けると嬉しいです。
Unity Hubを使ったUnityのインストール

#はじめに
Unity Hubを使ってUnityをインストールしたいと思います。

#Unity Hubのインストール
[公式サイト](https://unity3d.com/jp/get-unity/download)からUnity Hubのインストーラをダウンロードします。
![0.png](https://qiita-image-store.s3.amazonaws.com/0/311225/f91c1424-c92d-a89f-70a0-44e21e377361.png)
インストーラを起動します。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/311225/3ebd2dec-8dac-1aa0-8f2a-2b2e8a9793c0.png)
インストール場所を選びます。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/311225/d41dcb5a-52e8-99a9-014a-f9099a44eca0.png)
完了です。
チェックをつけておけばそのままUnity Hubを起動できます。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/311225/f5da3483-530c-2246-2127-42826b38c975.png)

#Unityのインストール
Unity Hubを起動すると以下のような画面となります。
「Download」か左の「Official Releases」を押します。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/311225/e5932bdb-f617-2ad8-1419-d1961b7c4258.png)
インストールできるバージョンの一覧が表示されます。
インストールするバージョンの「Download」を押します。
![6.png](https://qiita-image-store.s3.amazonaws.com/0/311225/5b21f119-50f5-d673-050d-d9435c2a361c.png)
ダウンロードするコンポーネントを選びます。
お好みで選んでください。後から変更もできます。
![7.png](https://qiita-image-store.s3.amazonaws.com/0/311225/768d561e-3d44-2146-d408-54ad6feaef1e.png)
日本語化する場合は、ここで日本語を選ぶこともできるようです。（私は選ばなかったのでわかりません…）
![e.png](https://qiita-image-store.s3.amazonaws.com/0/311225/7abeb46b-0b2b-25df-079e-f6bedf451fc7.png)
インストールが始まります。
![8.png](https://qiita-image-store.s3.amazonaws.com/0/311225/1d1299cf-0438-89e5-6f40-407fab278c96.png)
インストールが終わると、「On my machine」内にインストールしたバージョンが表示されます。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/311225/2e57ac34-886c-42a6-20a0-199be9b33c3c.png)
右のメニューから、コンポーネントの追加やアンインストールができます。
![13.png](https://qiita-image-store.s3.amazonaws.com/0/311225/34f8604b-4458-84d0-329c-af88edd74833.png)

上にある「新規」ボタンを押すと、新規プロジェクトを作成できます。
また、バージョンを複数インストールしていると、バージョンを選ぶ欄が表示されて、変更することができます。（バージョンが一つの時はこの欄は表示されませんでした。）
デフォルトでは「preferred」に設定しているバージョンが選択されています。
![14.png](https://qiita-image-store.s3.amazonaws.com/0/311225/967eadda-6527-d360-b0d6-3ca86a5a7413.png)

プロジェクトが作られて、エディターが開きます。
左上にバージョンが表示されています。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/311225/5577673e-a6a6-4bcd-75e6-1c5cfd955f70.png)

以上で、Unityを始める準備は終了です。
Alexa Skill を TypeScriptで実装する

# まえがき
AlexaのJS実装をTSに置き換えてみます。

# 前提
Alexa Skillを作成した事がある方。
TSで記述したいと思った方。

# インストール方法
## インストール
```sh
$ npm install -g typescript
```
## インストール確認
```sh
$ tsc --version
Version 3.3.4000
```

# プロジェクトの作成
## プロジェクト
以前の記事の【[Alexa ASK CLI コマンドで東京リージョンにデプロイする](https://qiita.com/whoshino/items/1995de08874a40615725)】のプロジェクトをものに対応したいと思います。

# TypeScriptの設定
## Nodeの型情報をインストールする
```sh
$ npm install @types/node
```
## 設定
```sh
$ tsc --init
```
## 設定変更
```sh
$ cat tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "sourceMap": true,
    "strict": true,  
    "esModuleInterop": true,
  },
  "files": [
    "index.ts"
  ]
}
```
※一部表示を省略しています。
## TSファイルに変更
```sh
$ mv index.js index.ts
```
## index.tsの修正
エラー内容を見つつ修正してください。

- 基本的には以下の対応となると思います
 - import分の変更
 - 型情報の追加
 - 適切な型にキャスト

## トランスパイル
```sh
$ tsc
```

# まとめ
TS化が完了しました。あとはdeployコマンドでデプロイを行えば完了です。
型情報があるってやっぱりいいですね。
今回使用したソースは[こちら](https://github.com/whoshino/alexa-skill-sample/tree/typescript)にあります。

# 参考
[初めてのスキル開発](https://ask-sdk-for-nodejs.readthedocs.io/ja/latest/Developing-Your-First-Skill.html?highlight=typescript)
Intel NUCにUbuntu18.04をインストールして、FreePBXでIP電話を運用する

# ものすごくざっくりとした経緯
ラズパイで運用していた社内のAsterisk（実際はWeb GUIつきのFreePBX）が不調に（しかも2回目）。
仕方がないので今度は完全に壊れる前にIntel NUCで作り直すことにしました。
あくまで自分用メモなので、あんまりアテにしないでください。これ本業じゃないし。

# 準備するもの
 - Intel NUC（今回はi3のモデルを使用）
 - メモリ（ラズパイより多ければOK）
 - SSD（正直適当なのでOK）
 - SDカードかUSBメモリ（OSのインストール用）

# Ubuntuのインストールディスクを作成
 1. 公式サイトからUbuntu Server 18.04 LTSのISOイメージをダウンロード。
 2. 作業端末はMacなので、[MacでUbuntuのインストールUSBディスクを作成する](https://qiita.com/kpkpkp/items/6664a1dba97198b984ec) と同じ手順で適当なSDカードやUSBメモリを使ってインストールディスクを作成する

# Ubuntuのインストール
 1. 作成したインストールディスクをIntel NUCに挿し、インストールを開始
 2. インストール手順は省略

# FreePBXのインストール
 1. FreePBXの公式Wikiにある [Installing FreePBX 14 on Ubuntu 18.04](https://wiki.freepbx.org/display/FOP/Installing+FreePBX+14+on+Ubuntu+18.04) に沿って、コマンドを叩いていく
 2. すべて終わったら、ブラウザに http://(ホスト名orIPアドレス)/admin/ と入力する
 3. 正しくインストールできていればFreePBXの画面が出る
 4. 旧FreePBXで使っていたモジュール類を「Admin > Module Admin」から入れていく

# 旧FreePBXからのデータ移植
 1. 「Backup & Restore」モジュールを入れていると、設定やDBの内容を他の環境に移植できる。新旧の環境に必ず入れておく。
 2. 旧環境でバックアップを作成し、手元にダウンロードしておく
 3. ダウンロードしたバックアップを新環境にアップロードする
 4. 新環境の「Backup & Restore」で復元する
 5. 旧環境と同じ設定が復元されていれば完了

# おまけ（もしバックアップから復元できないときのメモ）
## 内線の設定
 1. Applications > Extensions で内線を作る。
 2. 作成時は「Chan_SIP」を選ぶ
 3. 内線番号やSecretの値はお好みで

## Ring Groupの設定
一斉に着信音を鳴らすのに使う。

 1. Applications > Ring GroupでRing Groupを定義する
 2. 一斉に鳴らしたい内線を選んで保存しておく

## Trunkの設定
外線発信の準備として、Trunkを設定する

 1. Connectivity > Trunksで定義する
 2. Add SIP（chan_sip） Trunkを選ぶ（内線がchan_sipなので）
 3. Outbound CallerIDに凱旋番号を入れておく
 4. sip_settingsタブの設定は [FreePBX:5:トランク:ひかり電話(ホーム)](https://www.voip-info.jp/index.php/FreePBX:5:%E3%83%88%E3%83%A9%E3%83%B3%E3%82%AF:%E3%81%B2%E3%81%8B%E3%82%8A%E9%9B%BB%E8%A9%B1(%E3%83%9B%E3%83%BC%E3%83%A0)) あたりを参考にする


## Outbound Routesの設定
外線発信する際の設定をしないと発信できないので、設定しておく

 1. Connectivity > Outbound Routesで定義する
 2. Route CIDに外線発信番号を入れる
 3. Trunk Sequence for Matched Routesにさっき設定したTrunkを指定する
 4. Dial Patternsは、0120XXXXXX, 0N0XXXXXXXX, 0ZZXXXXXXX, 0ZZXXXXXXXX, 1XX を右から2つ目の欄に入れていく

## Inbound Routesの設定
外線着信時の設定をしておく

 1. Connectivity > Incoming Routesで定義する
 2. DID NumberやCallerID Numberは空欄
 3. Set Destinationに一斉に鳴らしたいRing Groupを指定する
 
## Blacklistの設定
営業電話が非常に多いので・・・

 1. Module AdminでBlacklistをインストールする
 2. かかってきた迷惑営業電話を片っ端からメモして追加すればOK
 3. Settingsタブで、Destination for BlackListed Callsの始末を指定する（Terminate CallやHangupで可）
中断したスポットインスタンスで終了ではなく停止にするには

以下の要件を満たす必要がある

- スポットインスタンス リクエストの場合は、タイプは one-time ではなく persistent （スポットインスタンス リクエストで起動グループを指定することはできない）
- スポット群 リクエストの場合は、タイプは request ではなく maintain
- ルートボリュームは、インスタンスストアボリュームではなく EBS ボリューム

よって、インスタンスストアボリュームは停止されたらデータ消えちゃうのでEBSボリュームにするのが👌
AWS コスト最適化（Design Cost-Optimized Architecture）のために抑えておきたい知識

# ストレージ
##EBSのストレージタイプ

|汎用SSD|プロビジョンドIOPS SSD|スループット最適化HDD|コールドHDD|
|:-:|:-:|:-:|:-:|:-:|:-:|
|I/O性能は最大10,000IOPS<br>OSのブート領域や中規模のDB用途<br>高いI/Oを持ちつつコスパよし|I/O性能は最大64,000IOPS<br>大規模DB用途<br>パフォーマンス野郎|ログ分析やビックデータ処理など<br>SSDより安い|とりあえずデータ保管したい<br>ログファイルなど<br>一番安い|

## S3かGlacierか問題
ちなむと、2018年に[GlacierはS3の一部(Amazon S3 Glacier)となりました](https://aws.amazon.com/jp/about-aws/whats-new/2018/11/s3-glacier-api-simplification/)

|S3|Glacier|
|:-:|:-:|
|0.025USD(最初の50TB)/GB<br>実際はデータ転送量とかでもう少しかかります|0.5円くらい/GB<br>実際はデータ転送量とかでもう少しかかります|
|バージョニングある|S3に一部となったのでバージョニングある<br>（っちゃあるけどそんなにPUTするならGlacierに置くな）|
|すぐに取り出せる|すぐに取り出せない<br>(迅速: ~5分, 標準: ~5時間, 大容量: ~12時間)|
|ライフサイクルあり|ライフサイクルあり|
|ナインイレブン|ナインイレブン|

Glacier(氷河)という名前の通り、全然触らないけど保管する必要があるコールドデータを保存するのに適したストレージ
S3と同じ堅牢性をもち、取り出しに時間がかかるけどデータ貯めるぶんには安いよ
S3のライフサイクルでGlacierにアーカイブするユーザが大半だったので、「もうGlacierはS3の一部にしちゃうか」ってなったっぽい

## どのS3を使うべきか

Glacierだとアプリケーションでは利用に値しません
そこで、S3の中でもお得に買い物をする必要があります
お値段以上S3

|スタンダード|標準低頻度|1ゾーン低頻度|低冗長化ストレージ|
|:-:|:-:|:-:|:-:|:-:|
|0.025USD/GB|0.0125USD/GB|0.01USD/GB|0.0264USD(最初の1TB)/GB|
||データの読み出し容量も課金対象|データへのアクセス頻度が低く、高い耐久性を必要とせず、かつ必要に応じてすぐに取り出したい|耐久性が99.99%一時格納目的で使われる|

# インスタンス
[EC2のオートスケールが複数インスタンスタイプの混在指定に対応、廉価なスポット利用が実現しやすくなりました](https://dev.classmethod.jp/cloud/aws/ec2-auto-scaling-groups-with-multiple-instance-types/)

これにより、オートスケーリングでリザーブドインスタンスやスポットインスタンスを組み合わせたりしてよりコスパよく運用できるようになりました。
例）昼間はめっちゃ使われるけど、夜間は使われず、Auto Scalingの下限まで落ちる
 -> 夜間だけ起動するリザーブドインスタンスを購入して、夜間はオンデマンド動かないようにするなど
新しいサーバにユーザを追加するコマンド

EC2インスタンスのユーザデータに設定したりとかで使えるのでメモとして残しておきます。
ユーザ追加してパスワード設定して`sudo`実行できるようにするコマンドです。
コマンドは`root`ユーザ、もしくは`sudo`可能なユーザで実行する必要があります。

```sh
# 追加するユーザとパスワード
NEW_USERNAME=taro
NEW_USERPASS=taro_pass

# ユーザ追加
useradd $NEW_USERNAME -m -d /home/$NEW_USERNAME -s /bin/bash
# パスワード設定
echo $NEW_USERNAME:$NEW_USERPASS | chpasswd
# sudoできるようにする(オプション)
echo '$NEW_USERNAME ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
```
忙しい人の為にRails Developers Meetup 2019 発表資料を分類 Day1

抜粋して分類する

# アーキテクチャ

* アプリケーションを作るときに考える25のこと
https://www.slideshare.net/takafumionaka/25-137790052

* DevOps, Immutable Infrastructure, microservices そして Chaos Engineering
https://speakerdeck.com/yoshiori/devops-immutable-infrastructure-microservices-and-chaos-engineering?slide=14

* オンライン予約徹底解説 
https://speakerdeck.com/m_nakamura145/onrainyu-yue-che-di-jie-shuo-number-railsdm2019

* 我々はマイクロサービスとどう向き合うべきか 
https://speakerdeck.com/ota42y/how-should-we-face-with-microservices-wo-hamaikurosabisutodouxiang-kihe-ubekika

* AskDoctorsの13年目を支える技術 
https://speakerdeck.com/owlworks/askdoctorsfalse13nian-mu-wozhi-eruji-shu

* 7年目を迎えたRailsアプリケーションの傾向と対策 
https://speakerdeck.com/taogawa/rails-developers-meetup-2019-day1

# 開発手法

* 少人数でサービスをすばやく開発するためのRails活用事例 
https://speakerdeck.com/tawachan/shao-ren-shu-desabisuwosubayakukai-fa-surutamefalserailshuo-yong-shi-li-rails-developers-meetup-2019

* Railsアップグレード、UIリニューアルを通じてのレガシーコード改善への道のり 
https://speakerdeck.com/debucchi/uiriniyuaru-regasikodogai-shan-falsedao-falseri

* Talentio をなんとかしようと頑張ってきた18ヶ月の旅路
https://speakerdeck.com/ogawa/talentio-wonantokasiyoutowan-zhang-tutekita18keyue-falselu-lu

* サービスを成長させる「仮説検証文化」のつくり方
https://speakerdeck.com/takatoshimaeda/railsdm2019

* Rails な受託の会社でぼくがやっていること
https://speakerdeck.com/takkanm/what-i-do-in-a-rails-consulting-company

* 万葉のRails新人研修のコードレビューコメントを分析してみました 
https://speakerdeck.com/nay3/mo-xie-falserailsxin-ren-yan-xiu-falsekodorebiyukomentowofen-xi-sitemimasita

* ユビレジのチーム開発 
https://railsdm.github.io/

# 技術特化

* Railsアップグレード百景 
https://speakerdeck.com/r7kamura/railsatupuguredobai-jing

* 毎日の開発に役立つRailsプラグインづくりの秘訣 
https://speakerdeck.com/a_matsuda/extending-rails-for-real-world-app-development

* SQLQL は GraphQL にとって、何なのか What's SQLQL for GraphQL?
https://www.slideshare.net/yancyajp/sqlql-graphql

* Ruby のコード解析の「静」と「動」 
https://speakerdeck.com/siman/railsdm2019
rails sでサーバーが起動しなかった時に確認したい初歩的なこと

なれてきた時こそ初心忘るべからず。自分への戒め投稿です！

# 今回の経緯
「rails s」でサーバー起動しようとしたら立ち上がらなかった。。
<img width="1459" alt="rails sエラー.png" src="https://qiita-image-store.s3.amazonaws.com/0/332038/e08147df-4394-96e8-753e-1c20cd8123ab.png">

# 原因と対応
原因としてはものすごい初歩的なミスで、ディレクトリが違ってたからです。
「todo_app」ディレクトリがコードのあるディレクトリと思っていたら、
その下に「memo_app」があったということでした。
「memo_app」に移動して「rails s」で正常に起動しました！
<img width="620" alt="rails sエラー対応.png" src="https://qiita-image-store.s3.amazonaws.com/0/332038/da3ee621-f228-d010-c854-a03cd6b13ec5.png">

以上です。思い込みはだめ。確認は大事ですね(;_;)
少しでも役に立ちましたら、フォローやいいねなど気軽にしていただけると励みになります。

# 参考
[参考][rails serverが起動せず"Usage:rails new APP_PATH [options]"が表示される (Ruby on Rails Tutorial)
](http://mochikichi.hatenablog.com/entry/2017/02/02/090637)
enum はなぜ便利なのか

![mySignals.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193431/05d706cc-1528-9ed8-c927-09431c0ec9b3.gif)

ネットの enum 解説を読んでもピンとこない方のために書きました。
##enum の読み方
enum （列挙型）の読み方は諸説ありますが「イーナム」が多数派のようです。
enum の語源は enumerate [ɪnjúːmərèɪt]（イニューマレイト：数え上げる）ですが、youtube を見ると英語圏でも「イーナム」と発音する人が多いです。
![HowToPronounceEnum.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193431/6e4d402a-e7c9-2390-ddc1-c10ba04051ce.gif)
##どんな時に使うか
enum は**「3つ以上の選択肢があるフラグ」**を表現する時に使います。
swift で使われている enum を「Jump to Definition」で探ってみると、

```swift

public enum NSTextAlignment : Int {
	case left
	case center
	case right
 }
```
とか

```swift
extension UIAlertAction {
	@available(iOS 8.0, *)
    public enum Style : Int {
		case `default`
		case cancel
		case destructive
    }
}
```
のように定義されています。
##BOOL はなぜ便利なのか
enum について説明する前に、BOOL がなぜ便利なのかを考えてみました。
BOOL は「真か偽か」の二値を表す時に使います。
私が35年前に使っていたMicrosoft BASIC には BOOL がありませんでした。（・・・と思います。記憶が間違っていたらすみません。）
その当時は真か偽かのフラグは「真を1、偽を0」の数値にしたり「YとN」の文字にしていました。しかしこの方法は間違いの元です。0か1かどちらが真なのか間違ったり、0と1以外の値も代入できてしまいます。真を表すのが「Y」なのか「YES」なのか「yes」 なのか間違うこともあり、それらを誤って代入してもエラーメッセージがでません。
その点、BOOL を使えば、真は常に true で、偽は常に false (swift では) なので間違うことがありません。BOOL 型の変数に true/false 以外の値を代入することはできません。真・偽のフラグは Int 型や String 型よりも BOOL 型の方が可読性がよくバグも起こりにくいです。
##3個以上の選択肢を持つフラグに enum を使う
真・偽のフラグには BOOL を使いますが、上述のように「left, center, right」などの選択肢が3個以上あるフラグを表現する時に enum は便利です。
これらのフラグを1, 2, 3 などの Int 型（マジックナンバー）にすると、わけがわからなくなります。
"left" "center" "right" などの String 型にすると単語のスペルを間違うことがあり、間違ったままでもコンパイルは通ってしまいます。
##Xcode の予測候補機能
Xcode には便利な予測候補機能があります。
以下のように .blue .red .yellow を持つ enum (Signal) があり、mySignal をインスタンスとします。
mySignal = . と打ち込むと、blue, red, yellow と予測候補が出てきます。mySignal に、.blue .red .yellow 以外の値が代入されることはありません。switch, case でも同様に予測候補を示してくれます。
![enum.gif](https://qiita-image-store.s3.amazonaws.com/0/193431/c62b1c90-093f-3207-e2c6-33433619bae0.gif)
###おわりに
以上に示したように「3個以上の選択肢があるフラグ」に enum を使うことによって安全性や可読性が向上します。swift の enum には更に強力な機能があるそうですが、私のスキルでは使いこなせないので割愛させていただきます。

[enum は MECE である](https://qiita.com/BMJr/items/c2a3d2e51f1a58e3ca54)

も参考にしてください。
SublimeText 3で「Error trying to parse settings: Expected string in Packages ~」と出た時の対処法

はじめましてsolveyと申します。Qiita初投稿です。

プログラミングの勉強を初めて半年のど素人ですが、エラー対処法を備忘録代わりにまとめてみました。
間違いなどあったらご指摘お願い致します。

使用環境はmacOS Mojaveです

SublimeTextを開くとこのようなメッセージが出てきました。<img width="819" alt="スクリーンショット 2019-03-31 11.32.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/369630/c89e4d8e-8902-4569-e045-c4e928f86ad3.png">

グーグル先生に聞いてみたところ、パッケージの書き方に何かエラーがあるとか。。
色々調べたら次のような方法で直りました。

「Finder」からoptionを押しつつ「移動」タブの中の「ライブラリ」を選択
↓
「Application Support」
↓
「Sublime Text 3」
↓
「Packages」
↓
「User」
と選択していくと

エラーをはきだしてるらしきファイルを発見

<img width="913" alt="スクリーンショット 2019-03-31 11.31.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/369630/92efa178-c4d8-2c77-6d33-06e2c18d6ca2.png">

ファイルを開くと末尾に「 } 」がないことが判明

<img width="822" alt="スクリーンショット 2019-03-31 12.04.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/369630/0387e1ec-14d6-ef27-4849-b9705c585c84.png">

「 } 」を付け足したら無事にエラーは出なくなりました。

以上です。閲覧していただきありがとうございました。
SteamVR1.0のTrackedObjectのindex問題を解決しよう

#はじめに

**SteamVR2.0ではこれしなくてもいいそうです！！！！！！！！！！！！！！！**

Unity+SteamVR+FinalIKがあればフルトラなんて簡単に出来るじゃーんと思っていませんか？僕は思っていました。
しかし軽いノリで安請け合いをキメたが最後、無限のねじれと戦う羽目になります。

- トラッカーと四肢の角度の調整（手首足首がねじれて死ぬ。最悪）
- トラッカーと四肢の対応（手足がねじれてブエルみたくなって死ぬ。最悪）

僕はこれらの地獄に飲まれて2敗しています。
前者については結構根気が必要なところがありますが、後者についてはSteamVRの仕様が結構な悪さをしてくれちゃってます。
というのも、SteamVRでのオブジェクトとコントローラの対応付けはSteamVRの接続順、となっているらしく、どのトラッカーをどこに割り当てるか？というような対応付けを固定させることがデフォルトでは出来ないみたいです。
というわけで今回は取り敢えずの解決策として、SteamVRの接続順に依存しない、トラッカーのシリアル番号を取得して対応付けを修正する実装を考えてみようと思います。
#実装
##指定したTrackedObjectに割り当てられたデバイスのシリアルナンバーを取得する

```C#
var buffer = new StringBuilder(256);
var error = ETrackedPropertyError.TrackedProp_Success;
SteamVR.instance.hmd.GetStringTrackedDeviceProperty((uint)trackedObject.index, ETrackedDeviceProperty.Prop_SerialNumber_String, buffer, (uint)buffer.Capacity, ref error);
if(error = ETrackedPropertyError.TrackedProp_Success){
    Debug.Log(buffer.ToString());
}
```

これでbufferにtrackedObjectのserialNumberが格納されます。
##指定したTrackedObjectのindexを設定する。
指定したTrackedObjectにindexを割り当てるには、

```C#
trackedObject.SetDeviceIndex((int)index);
```

indexはenumだけどSetDeviceIndexの引数はint指定なので注意です。
##これらを組み合わせて特定のデバイスに割り当てられるindexを固定する
全てのTrackedObjectに対しシリアルナンバーを取得し、指定されたシリアルナンバーだったらそのTrackedObjectのindexを指定のものに変更します。

```C#
using System.Text;←追加
using Valve.VR;←追加

public SteamVR_TrackedObject[] trackedObjects;//あらかじめすべてのTrackedObjectを入れておく
public string serialNumberTarget;//割り当て固定対象のシリアルナンバー
public SteamVR_TrackedObject targetObject;//割り当て固定対象のオブジェクト
//つまりserialNumberTargetとtargetObjectが対応づけされる
public void AssignTrackedObject(){
    SteamVR_TrackedObject.EIndex tmp;
    var buffer = new StringBuilder(256);
    var error = ETrackedPropertyError.TrackedProp_Success;
    for(int i = 0; i < trackedObjects.Length; i++){
        SteamVR.instance.hmd.GetStringTrackedDeviceProperty((uint)trackedObjects[i].index, ETrackedDeviceProperty.Prop_SerialNumber_String, buffer, (uint)buffer.Capacity, ref error);
        if(error == ETrackedPropertyError.TrackedProp_Success){
            Debug.Log(buffer.ToString());
            if(buffer.ToString() == serialNumberTarget){
                tmp = trackedObjects[i].index;
                targetObject.SetDeviceIndex((int)tmp);
            }
        }
    }

}

```

こうすることでindexに依らずシリアルナンバーとオブジェクトを対応付けることができます。

#おわりに（不具合…？）
UIでシリアルナンバーを書き換えられるコンフィグ画面を用意しておくと捗りそうです。結構面倒ですね…
低頻度でコントローラのトリガーが反応しないときがあります。現在再現が不可能でよくわからないことになっているのでぜひ手掛かりがある人は教えてください。
ハイブリッドプロジェクト開発(四)VSCodeでJavaScriptプロジェクトを開発します

#VSCodeの特徴
VSCodeとは、クロスプラットフォームで使える高機能のエディタです。拡張機能を導入することで、Cordva開発を効率的に行えるようにします。
VSCodeは以下の特徴をもっていますので、今回、開発ツールとして使ってプロジェクト開発を行います。
**軽量**
VSCodeは軽量なテキストエディタなので、プログラムの作成・修正を手軽に行うことができる。SublimeやAtomと雰囲気は似ている。
**デバッグ可能**
VSCodeではプログラムのデバッグを行うことができる。デバッグする言語によって拡張機能のインストールされたら、動作の重くなりがちなIDEを使わずにデバッグできます。
**多数言語サポート**
C/C++、#、VB、Java、JavaScript、Python、SQL、JSONなど多くの言語をサポートしている。サポートされている言語は「シンタックスハイライト」と呼ばれる機能でプログラム言語の構文がハイライト表示されるため、見やすく、また書きやすくプログラミングできます。
**コードの自動補完**
IDEなどに備わっている自動補完(Intellisense)機能があります。
**Git連携**
Gitとの連携機能が実装されており、Gitリポジトリにプッシュ、プルを行うことが可能です。

#Cordova拡張機能
VSCodeでCordova拡張機能(Cordova Tools Extension)を利用したら開発を効率良くなります。具体的には以下の機能を提供します。
• CordovaのプラグインAPI記述時の入力補完機能
• エミュレーター/シミュレーターによるデバッグ実行
• ビルド等のコマンド実行
• Ionicフレームワークのサポート他
Cordova拡張機能をインストールするには、VSCode画面左のメニューから拡張機能のメニューを選択します。検索欄に “cordova” と入れると、「Cordova Tools Extension」が出てくるので、これをインストールします。
![2019-03-30-18-01-35.png](https://qiita-image-store.s3.amazonaws.com/0/229009/9a0ba57d-564f-da58-97fb-39a724d0cec4.png)
インストール後、VSCodeを再起動しておきます。

#プロジェクトの開発
**プロジェクトをロード**
VSCodeのメニューから、ファイルの開くを選択して、前章で作ったHelloCordovaプロジェクトをVSCodeにロードします。
**中身を編集**
wwwの配下にあるindex.htmlを編集します。追加したソースは赤字です。
![スクリーンショット 2019-04-03 22.00.59.png](https://qiita-image-store.s3.amazonaws.com/0/229009/cb7deb13-76cb-09d9-ddfc-ee7efbab9411.png)
wwwの配下に新しいnextpage.htmlを作成します。
![スクリーンショット 2019-04-03 22.05.51.png](https://qiita-image-store.s3.amazonaws.com/0/229009/db37c7e4-6c7b-1452-15d1-6ebb454df424.png)
**プロジェクトをデバッグ**
デバッグモードを開き、歯車アイコンを選択して、Cordovaを選択します。
🌾もしデバッグできなくなっていたら、「launch.json」を消してデバッグ設定をやり直してください。
![スクリーンショット 2019-03-31 10.22.42.png](https://qiita-image-store.s3.amazonaws.com/0/229009/fc633531-6984-a8f6-44e4-6c6bbce0c947.png)
デバッグ右のプルダウンから、Simulate iOS in browser選択し、デバッグを実行して下図ような結果が出るはずです。
![スクリーンショット 2019-04-03 22.30.04.png](https://qiita-image-store.s3.amazonaws.com/0/229009/5f793221-cf8a-ab51-a8bb-0ee0678e4c75.png)
「次のページを開く」をクリックすると、
![スクリーンショット 2019-04-03 22.30.15.png](https://qiita-image-store.s3.amazonaws.com/0/229009/8dca1ea8-7e8f-df8f-346c-f8cd1417f670.png)

#XCodeで実行
前章と同じように、XCodeでHelloCordovaプロジェクトを開きます。
プロジェクトを実行すると、
![スクリーンショット 2019-04-03 22.34.39.png](https://qiita-image-store.s3.amazonaws.com/0/229009/2df9cf01-ba73-07b4-a017-3f9334b4ef9a.png)
![スクリーンショット 2019-04-03 22.34.49.png](https://qiita-image-store.s3.amazonaws.com/0/229009/95b1ead5-b6c8-01e8-e722-eae8161cf8a5.png)
ハイブリッドプロジェクト開発(一)環境解説

#ハイブリッドプロジェクトとは
ある時は、モバイルやタブレットに動いているアプリとブラウザーから閲覧しておくWebSiteの両方に対応するプロジェクトを開発することがあります。この問題の対処方法の一つは、ハイブリッドプロジェクトを開発することになります。
ハイブリッドアプリの定義は、厳密には定まっていません。IT業界内では、一般的にApache Cordovaなどのフレームワークを用いて、Web系の通常技術で開発したプロジェクトを示します。
#必要スキル
ハイブリドアプリの大部分はWebViewで表示するWebコンテンツになりますので、HTML5やCSS3、JavaScriptといったWeb開発に関するスキルが特に必要になります。
Apache Cordovaは、HTML5やCSS3、JavaScriptなどのWeb系スキルでアプリが開発できるので、ハイブリッドオブジェクトを開発するには人気があります。今投稿では主にCordovaの仕組みによってハイブリッドの開発環境の構築を行います。
開発ツールは、VSCodeを利用します。

----
✨✨✨ 次の文章： [ハイブリッドプロジェクト開発(二)Node.jsをインストールします](https://qiita.com/gakuseikai/items/d96df1126ff1361c3162)
Rails　チュートリアル　①

#＜Railsチュートリアル　メモ＞

気づいたことや覚えておきたいことをメモとして残します。


・REST
→インターネットそのものやWEBアプリケーションなどの、分散・ネットワーク化されたシステムやアプリケーションを構築するためのアーキテクチャ（コンピュータ システムの論理的構造）のスタイルの１つ。
アプリケーションを構成するコンポーネント（ユーザーやマイクロポストなど）を「リソース」としてモデル化することを指す。

#＜カウンニング用、UNIXコマンド＞
Railsチュートリアルより。
![スクリーンショット 2019-03-31 11.42.49.png](https://qiita-image-store.s3.amazonaws.com/0/378334/7401165d-9c6a-faa7-135b-6a35e077915f.png)
babel7で"@babel/preset-env"のオプション"useBuiltIns"を使う

# babel/polyfillがdeprecatedな件について追記（2019/06/16

どうやら、Babel v7.4.0以降では、`core-js/stable`が含まれているため、`corejs: 3`を使うならもう`@babel/polyfill`はお払い箱のようです。

[ここら辺](https://github.com/babel/babel/pull/7646)のPRに色々書いてあります。

`yarn remove @babel/core @babel/polyfill`してから`yarn add --dev @babel/core`してbabelを7.4.5系にアップデートしたら、以下のwarningが消えました。めでたし

> As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions): > import "core-js/stable"; > import "regenerator-runtime/runtime";

**以下の内容は、babel v7.4.5以前を使用している場合に限る古い内容であることに注意してください。**

------------------

[Reactとtsx](https://github.com/Mizumaki/React_TypeScript_template)でよく開発しています。

babel7からは[typescriptのサポート](https://qiita.com/nacam403/items/edf3e2c8ff364aff910f)が入って、しかし型チェックはしてくれないので[別でやる必要](https://qiita.com/tmzkysk/items/35ef6be9b5162a6bf2fe)があったりなどとまだ少し面倒くさいですが、それでもts-loaderさようならということでbabelを愛用しています。

# `@babel/preset-env` の `useBuiltIns` オプションは便利

[`@babel/preset-env`の`useBuiltIns`オプション](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins)は、勝手に必要なpolyfillを判断して自動で追加してくれる優れものなのですが、ドキュメントの読みが甘く、少し詰まりました。

こんな感じに、`core-js`ないじゃん！って怒られました。

```
ERROR in ./src/App.tsx
Module not found: Error: Can't resolve 'core-js/modules/es6.object.set-prototype-of' in '/mnt/e/Development/life/src'
 @ ./src/App.tsx 3:0-53
 @ ./src/index.tsx
 @ multi (webpack)-dev-server/client?http://localhost:3000 (webpack)/hot/dev-server.js ./src/index.tsx
```

むむむ。`@babel/preset-env`はnpm installしてるし、babel-loader内で`['@babel/preset-env', { useBuiltIns: 'usage' }],`これを指定しておけばほかはないもいらない想定だったんだけどなぁ。なぜ

# `@babel/polyfill`も必要

`@babel/polyfill`は過去の遺物、もう`useBuiltIns`があるから、それだけでOKと勘違いしていたのですが、違いました。

実は、`useBuiltIns`オプションを使用すると、`core-js`などのimport polyfillを自動的に追加してくれるのですが、肝心のソース自体は`@babel/polyfill`から引っ張ってくるようでした。

きちんと[ドキュメント](https://new.babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins)にも書いてありました。。

>  (via @babel/polyfill).

wtf

### 参考

[「Babel7.x時代のpolyfillの設定方法とuseBuiltInsの仕組み」](https://aloerina01.github.io/blog/2018-11-29-1)という記事が非常に参考になりました。
cssで要素を非表示にする方法。displayとvisibilityの違い。

#要素を非表示にしたい時には？
cssで要素を非表示にしたい時がある。Java Scriptでタブﾒﾆｭｰを実装する時などによく使われるだろう。
ここでは要素の非表示の方法を２つ紹介する。それぞれ用途が違うので注意し区別すること。
初心者はこう言った基本をしっかり身につけることで、後々Java Scriptの勉強に進んだ時に理解が速くなると思う。

#display: none;とvisibility: hidden;
display: none;とvisibility: hidden;両者で要素を非表示にすることができる。しかし両者にはおおきな違いがある。
まずdisplay: none;はもともと表示されていた要素は無かったことになる。「無かったこと」とは、はじめから存在しなかったと言う意味である。つまりその要素の後に他の要素があった場合、後の要素が前の要素の位置にせりあがると言うことである。noneの意味は「無し」。

一方、visibility: hidden;は要素自体は見えなくなるが、見えないだけで実際には要素がある。完全に要素が消えるのではなく、透明になっているような状態になる。つまり後に続く要素があっても無視されずに要素の位置は変わらないのである。hiddenの意味は「隠す」。
Google App Engine で始める Go 実践入門 Part 7 【リモートデバッグ】

連載を通して簡単なブログアプリを作成しつつ Go/GAE について学んでいきます。
今回は リモートデバッグ についての説明です。

- [Part 1. 『GO / Cloud SDK のインストール』](https://qiita.com/rema424/items/743bc508ef70cd980e17)
- [Part 2. 『GOPATH』](https://qiita.com/rema424/items/009f6345eb75a80bf369)
- [Part 3. 『プロジェクトの作成』](https://qiita.com/rema424/items/19b946c311f3b3b3f953)
- [Part 4. 『ディレクトリ構成』](https://qiita.com/rema424/items/1a6096c77b90ea350a26)
- [Part 5. 『Visual Studio Code』](https://qiita.com/rema424/items/b2ecdd2c7ec7fc1b0a7c)
- [Part 6. 『Hello World』](https://qiita.com/rema424/items/66ce1b02d7de588e63cf)
- [Part 7. 『リモートデバッグ』](https://qiita.com/rema424/items/996aaf0ab69670224af4) ← イマココ
- [Part 8. 『デプロイ』](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f)
- [Part 9. 『Makefile』](https://qiita.com/rema424/items/3a099dfb023aa06086f5)
- [Part 10. 『Circle CI』](https://qiita.com/rema424/items/4dcb37346cecc544dfaa)
- Part 11. 『Dependency Injection』
- Part 12. 『ローカルDB with Docker』
- Part 13. 『gorm』
- Part 14. 『Cloud SQL』
- Part 15. 『Cloud SQL Proxy』
- Part 16. 『HTML』
- Part 17. 『CSS/JS』
- Part 18. 『Google Analytics』
- Part 19. 『Google Search Console』
- Part 20. 『A/B テスト』
- Part 21. 『ユーザーの作成』
- Part 22. 『Firebase Auth』
- Part 23. 『記事の作成』
- Part 24. 『コメントの作成』
- Part 25. 『ページネーション』

# リモートデバッグ

VS Code と App Engine ローカル開発サーバーでリモートデバッグができるようにします。

ポイントは次の通りです。

- VS Code でデバッグ用の設定ファイルを作る
- サーバー起動時に `--go_debugging=True` をオプションで渡す
- Go の Debugger である `delve` をインストールする (インストール済み)
- `delve` コマンドを用いて Debugger をサーバーにアタッチする

まずは VS Code のデバッグ用設定ファイルを作成します。

```sh
touch .vscode/launch.json
```

```json:.vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Connect to server",
      "type": "go",
      "request": "launch",
      "mode": "remote",
      "remotePath": "${workspaceFolder}",
      "port": 2345,
      "host": "127.0.0.1",
      "program": "${workspaceFolder}",
      "env": {},
      "args": []
    }
  ]
}
```

次にサーバーを起動します。

```sh
dev_appserver.py module/blog/main/app.yaml --support_datastore_emulator=False --go_debugging=True
```

サーバーが起動したらターミナルをもう 1 枚開いて Debugger をアタッチします。
VS Code であればターミナルの分割 (Command + Alt + Ctrl + \\) を使うのが便利です。

```sh
dlv attach $(ps u | grep _go_ap[p] | head -1 | awk '{print $2}') --headless --listen=127.0.0.1:2345 --api-version=2
```

次に VS Code 上でブレークポイントを設置します。

デバッグを開始 (F5) します。

この状態でブラウザから `localhost:8080` にアクセスすると、ブレークポイントでプログラムがストップします。

![スクリーンショット 2019-03-24 12.10.48.png](https://qiita-image-store.s3.amazonaws.com/0/237863/3326d853-142c-700a-3fd7-0c9543db6b93.png)

[ローカル開発用サーバーのオプション | Google Cloud](https://cloud.google.com/appengine/docs/standard/go/tools/local-devserver-command?hl=ja)

# おわりに

次回のテーマは『[デプロイ](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f)』です。

よかったら Twitter フォローしてね。[@_rema424](https://twitter.com/_rema424)
よく使うgrepコマンド集

https://qiita.com/dich1/items/27ac0fa49118ebc5eab5

こちらの記事から切り出し

```カレント配下の(.)マッチするファイル内文字を、再帰的に検索し(-r)、行番号も表示する(-n).
grep -rn "対象文字列" .
```
```カレント配下の(.)マッチするファイル内文字を、再帰的に検索し(-r)、行番号と合致行に隣接する下の行(-A)を表示する(-n).
grep -rn -A数字 "対象文字列" .
```
```カレント配下の(.)マッチするファイル内複数文字(|)を、再帰的に検索し(-r)、行番号も表示する
grep -rn "検索文字1\|検索文字2" .
```
```カレント配下の(.)マッチするファイル内複数文字(|)を、再帰的に検索し(-r)、行番号を表示する
grep -rn "検索文字1" . | grep "検索文字2"
```
```カレント配下の(.)マッチするファイル内文字を、再帰的に検索し(-r)、出力行をファイルに吐き出す.
grep -r "対象文字列" . > hoge.txt
```
```特定のファイルのマッチするファイル内文字の出力行をファイルに吐き出す.
grep "対象文字列" ファイル名 > hoge.txt
```
Google App Engine で始める Go 実践入門 Part 3 【プロジェクトの作成】

連載を通して簡単なブログアプリを作成しつつ Go/GAE について学んでいきます。
今回はプロジェクトの作成についての説明です。

- [Part 1. 『GO / Cloud SDK のインストール』](https://qiita.com/rema424/items/743bc508ef70cd980e17)
- [Part 2. 『GOPATH』](https://qiita.com/rema424/items/009f6345eb75a80bf369)
- [Part 3. 『プロジェクトの作成』](https://qiita.com/rema424/items/19b946c311f3b3b3f953) ← イマココ
- [Part 4. 『ディレクトリ構成』](https://qiita.com/rema424/items/1a6096c77b90ea350a26)
- [Part 5. 『Visual Studio Code』](https://qiita.com/rema424/items/b2ecdd2c7ec7fc1b0a7c)
- [Part 6. 『Hello World』](https://qiita.com/rema424/items/66ce1b02d7de588e63cf)
- [Part 7. 『リモートデバッグ』](https://qiita.com/rema424/items/996aaf0ab69670224af4)
- [Part 8. 『デプロイ』](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f)
- [Part 9. 『Makefile』](https://qiita.com/rema424/items/3a099dfb023aa06086f5)
- [Part 10. 『Circle CI』](https://qiita.com/rema424/items/4dcb37346cecc544dfaa)
- Part 11. 『Dependency Injection』
- Part 12. 『ローカルDB with Docker』
- Part 13. 『gorm』
- Part 14. 『Cloud SQL』
- Part 15. 『Cloud SQL Proxy』
- Part 16. 『HTML』
- Part 17. 『CSS/JS』
- Part 18. 『Google Analytics』
- Part 19. 『Google Search Console』
- Part 20. 『A/B テスト』
- Part 21. 『ユーザーの作成』
- Part 22. 『Firebase Auth』
- Part 23. 『記事の作成』
- Part 24. 『コメントの作成』
- Part 25. 『ページネーション』

# 本エントリーでやること

- GCP プロジェクトの作成（GCP）
- App Engine の有効化（GCP）
- GitHub リポジトリの作成（GitHub）
- 開発用プロジェクトルートディレクトリの作成（ローカル PC）

# GCP プロジェクトの作成

https://console.cloud.google.com/getting-started

上記の URL にアクセスして「プロジェクトの選択」 > [新しいプロジェクト] からプロジェクトを作成します。

GCP の利用が初めての人は無料トライアルへの申し込みも行っておくと良いです。

プロジェクトの作成が完了したら [プロジェクトの選択] > [すべて] > [(作成したプロジェクトの名称)] と選択して、プロジェクトのダッシュボードへと移動します。

# App Engine の有効化

プロジェクトのダッシュボードを開いた状態で [ナビゲーションメニュー] > [App Engine] > [ダッシュボード] と選択して、App Engine のダッシュボード画面へ移動します。

App Engine のダッシュボード画面が開けたら、 [アプリケーションを作成] > [asia-northeast1] > [アプリを作成] > [キャンセル] と選択して、東京リージョンで App Engine を有効化します。

# GitHub リポジトリの作成

GitHub 上で新規リポジトリを作成します。 `README.md` や `.gitignore` も作成しておきましょう。

記事内では `go-gae-blog-app-example` という名称のリポジトリを使っていきます。

# 開発用プロジェクトルートディレクトリの作成

GitHub で作成したリモートリポジトリをローカルの `GOPATH` 配下にクローンします。
ディレクトリ名、ユーザ名、リポジトリ名は適宜自分のものに読み替えてください。

```sh
# ディレクトリ作成
mkdir -p $GOPATH/src/github.com/rema424

# ディレクトリ移動
cd $_

# リポジトリのクローン
git clone https://github.com/rema424/go-gae-blog-app-example.git
```

ここまでの作業が完了すると、ディレクトリ構成は次のようになっているかと思います。

```
$GOPATH
  └── src
        └── github.com
              └── rema424
                    └── go-gae-blog-app-example (プロジェクトルート)
                          ├── .gitignore
                          └── README.md
```

# おわりに

次回のテーマは『[ディレクトリ構成](https://qiita.com/rema424/items/1a6096c77b90ea350a26)』です。

よかったら Twitter フォローしてね。[@_rema424](https://twitter.com/_rema424)
Google App Engine で始める Go 実践入門 Part 2 【GOPATH】

連載を通して簡単なブログアプリを作成しつつ Go/GAE について学んでいきます。
今回は GOPATH についての説明です。

- [Part 1. 『GO / Cloud SDK のインストール』](https://qiita.com/rema424/items/743bc508ef70cd980e17)
- [Part 2. 『GOPATH』](https://qiita.com/rema424/items/009f6345eb75a80bf369) ← イマココ
- [Part 3. 『プロジェクトの作成』](https://qiita.com/rema424/items/19b946c311f3b3b3f953)
- [Part 4. 『ディレクトリ構成』](https://qiita.com/rema424/items/1a6096c77b90ea350a26)
- [Part 5. 『Visual Studio Code』](https://qiita.com/rema424/items/b2ecdd2c7ec7fc1b0a7c)
- [Part 6. 『Hello World』](https://qiita.com/rema424/items/66ce1b02d7de588e63cf)
- [Part 7. 『リモートデバッグ』](https://qiita.com/rema424/items/996aaf0ab69670224af4)
- [Part 8. 『デプロイ』](https://qiita.com/rema424/items/dbf851908dbfc95f9b6f)
- [Part 9. 『Makefile』](https://qiita.com/rema424/items/3a099dfb023aa06086f5)
- [Part 10. 『Circle CI』](https://qiita.com/rema424/items/4dcb37346cecc544dfaa)
- Part 11. 『Dependency Injection』
- Part 12. 『ローカルDB with Docker』
- Part 13. 『gorm』
- Part 14. 『Cloud SQL』
- Part 15. 『Cloud SQL Proxy』
- Part 16. 『HTML』
- Part 17. 『CSS/JS』
- Part 18. 『Google Analytics』
- Part 19. 『Google Search Console』
- Part 20. 『A/B テスト』
- Part 21. 『ユーザーの作成』
- Part 22. 『Firebase Auth』
- Part 23. 『記事の作成』
- Part 24. 『コメントの作成』
- Part 25. 『ページネーション』

# GOPATH について

Go の開発は GOPATH と呼ばれるディレクトリ配下で行うことが標準的です。
GOPATH となるディレクトリの場所は自分自身で任意で決めて良いことになっていますが、 `$HOME/go` をGOPATH に設定するのが一般的です。(Go 1.8+ ではデフォルトが `$HOME/go` となっています。)
direnv 等のツールを用いてプロジェクトごとにカレントディレクトリを GOPATH に設定して開発を行うスタイルもありますが、今回は素直に `$HOME/go` 配下で開発を行います。

GOPATH 配下のディレクトリ構成は次のように定められています。

```
$GOPATH
  ├── bin
  ├── pkg
  └── src
```

このディレクトリ構成を Node.js に例えると次のようになるかと思います。

- $GOPATH/bin はグローバルインストールした node_modules/bin が配置されるところ
- $GOPATH/pkg はビルドされたパッケージが配置されるところ (Nodeにはない概念)
- $GOPATH/src はグローバルインストールした node_modules と 自分のソースコードを配置するところ

src ディレクトリで実際に開発を行うことになりますが、src 直下にプロジェクトのルートディレクトリを配置するのではなく、ソースコードを管理しているリポジトリと紐づけて階層構造にするのが標準となっています。

```
$GOPATH
  ├── bin
  ├── pkg
  └── src
        └── [ホスティング先]
              └── [ユーザ名 or 組織名]
                    └── [リポジトリ名] （ここがプロジェクトのルートディレクトリになる）
```

例えば GitHub をホスティング先にしている私の場合は次のようになります。

```
$GOPATH
  ├── bin
  ├── pkg
  └── src
        └── github.com
              └── rema424
                    └── go-gae-blog-app-example
```

# おわりに

次回のテーマは『[プロジェクトの作成](https://qiita.com/rema424/items/19b946c311f3b3b3f953)』です。

よかったら Twitter フォローしてね。[@_rema424](https://twitter.com/_rema424)
よく使うsedコマンド集

https://qiita.com/dich1/items/27ac0fa49118ebc5eab5

こちらの記事から切り出し

```
オプション
-e スクリプトを追加
-i 上書き更新
```

```:Windows改行コード「\r\n」をLinuxの「\n」に変換する
sed -ie 's/\r//' ファイル
```
```:ファイルに対して該当行の前に(i)文字列を追加する
sed -ie '行数i 追加文字列' 対象ファイル
```
```:ファイルに対して該当行の前に(a)文字列を追加する
sed -ie '行数a 追加文字列' 対象ファイル
```
```:ファイルに対して該当行を削除(d)する
sed -ie '行数d' 対象ファイル
```
```:タブをスペースに変換するスクリプトを実行
sed -ie 's/<tab>/<space>/g' 対象ファイル
```
```:該当行の範囲の頭の「#」を外す
sed -ie "開始行数,終了行数s:^#::" 対象ファイル
```
```:ファイルに対してスペースと一緒に文字列を追加
sed -ie '行数i \ 文字列' 対象ファイル
```

```:ファイルに対して対象文字列に合致する行をコメントアウトする
sed -ie '/対象文字列/s/^/# /g' 対象ファイル
```
勾配降下法で特徴量スケーリングを理解するための簡単なプログラム

#特徴量スケーリングの意義

現在couseraの機械学習コースで学んでいて、特徴量スケーリングの話が出てきました。それによると特徴量スケーリングによって実行速度に違いが出るとのことなのでpythonで実装して実行時間を比較して見ます。

簡単にするために平面上で中心を目指すアルゴリズムを実装します。

初期値が同じ時に楕円のとき（疑似的なスケーリング前の関数）と真円のとき（擬似的なスケーリング後の関数）の実行時間を比べます。


```py
import time

class gradient_discent:
    
    
    def __init__(self,alpha):
        self.alpha = alpha
        
    def gradient(self,x,alpha):
        h = alpha *x
        x = x - h * 2
        return x

    def ellipse(self,x1,x2):
        y = x1**2 + 100000*x2**2#楕円の関数
        return y

    def circle(self,x1,x2):
        y = x1**2 + x2**2#真円の関数
        return y
    
    
x1 = 1 #x1の初期値
x2 = 1 #x2の初期値

test_feature_scaring = gradient_discent(0.0001)
y = test_feature_scaring.ellipse(x1,x2)

time1 = time.time()
while y > 0.001:
    x1 = test_feature_scaring.gradient(x1,test_feature_scaring.alpha)
    x2 = test_feature_scaring.gradient(x2,test_feature_scaring.alpha)
    
    y = test_feature_scaring.ellipse(x1,x2)

time2 = time.time()

time3 = time2 - time1
print("スケーリング前の実行時間" + str(time3))

x1 = 1 #x1の初期値
x2 = 1 #x2の初期値

test_feature_scaring = gradient_discent(0.0001)
y = test_feature_scaring.circle(x1,x2)

time1 = time.time()
while y > 0.001:
    x1 = test_feature_scaring.gradient(x1,test_feature_scaring.alpha)
    x2 = test_feature_scaring.gradient(x2,test_feature_scaring.alpha)
    
    y = test_feature_scaring.circle(x1,x2)

time2 = time.time()

time3 = time2 - time1
print("スケーリング後の実行時間" + str(time3))
```

#結果
スケーリング前の実行時間0.06296
スケーリング後の実行時間0.02598

#感想
実際に約２．５倍実行時間に差がついたので特徴量スケーリングを体感できたかなと思う。
Androidで安易にname, simpleNameを使って痛い目にあった話

## はじめに
先日リリース前に地雷を踏みかけ、そういえば以前にも似たような地雷を踏んだのを思い出したので書きました。

# 事例
## ケース1
### 発生した事象
単一Activity上で複数Fragment（それぞれA,B,C,Dとする）を切り替えるアプリを作っていた際に、BottomNavigationで切り替えるもReleaseビルドでのみDのFragmentに切り替えようとしているにも関わらずBのフラグメントが表示されてしまった。

### 原因
FragmentのtagにそのFragmentのClass.simpleNameを利用していたこと。

debugビルドではProguardが無効なので問題なくユニークな文字列として機能してくれたが、releaseビルドにおいて難読化された結果下記のようなマッピングとなっていた。

* A -> a.a
* B -> b.b
* C -> c.c
* D -> d.b

ここでnameで参照していればBとDは別のものだと認識できたもの、のsimpleNameを参照するとそれぞれbとしか見做されず、Fragment切り替えの際にfindByTagするとbとしてしか参照できずにBとDが同一視されてしまっていた。

### 対応策
* リリース前だったことと、次の事例とは異なりFragmentの識別だけ出来ればいいのでsimpleNameではなくnameを参照するようにコードを変更したところReleaseビルドでも問題なく動くようになった :ok_woman: 

## ケース2
### 発生した事象
アプリをアップデートすると１つ前のバージョンで設定したアプリ内の設定項目が変更されてしまう。

### 原因
SharedPreferencesのkeyに利用する文字列をベタ書きにせずClass.nameで生成していたこと。

simpleNameではなくnameなのでユニークなkeyにはなるものの、アップデートによるクラス数の増減があったことによってmappingが変わってしまい保存時のkeyで参照できなくなってしまっていた。

例） アップデートに伴いパッケージbにMというクラスが追加された。

Ver 1.0.0

* a/A -> a.a
* b/N -> b.a

Ver 1.0.1

* a/A -> a.a
* b/M -> b.a
* b/N -> b.b

### 対応策
* それ以降はSharedPreferencesのkeyはベタ書きで定義、利用することになった:ok_woman: 
* なお、このときはアプリはリリース済みだったため既存ユーザが保存した設定のkeyは難読化されたクラス名のままであった:innocent: 
    * 力技でSharedPreferencesのwrapperクラスに自前で新旧の難読化されたクラス名のmapping処理を書いて変換していた記憶（当時この件は先輩が対応してくださっていてうろ覚えです:bow:）

## おわりに
simpleName, nameはデバッグLogCatでの利用くらいに留めておいたほうが無難そうです。
まぁAndroidStudio先生にも怒られるのでTimber使えばsimpleNameを参照する必要もないのですが。

もし使う場合はProguardがかかっても問題ない内容かどうかを判断してから使うようにしないと危険なので気をつけましょう（自戒）

simpleName, nameに関する別の事例をお持ちの方はぜひ教えてくださいませ。
[JavaScript]正規表現(gオプション,iオプション)

# gオプション・iオプションについて
今回は正規表現で使えるオプションであるgオプションとiオプションについて解説していきたいと思います。

## gオプション
gオプションは置き換えたい文字列を指定した時にその文字が複数含まれている場合に、その全てを置き換えるオプションです。
まずはgオプションを使わない場合を見てみます。

```正規表現.js
var name = "私はゆーいちです、ゆーいちはエンジニアです"；
    name.replace(/ゆーいち/, "ゆー太郎");
   => "私はゆー太郎です、ゆーいちはエンジニアです"
```
このように二つ目の「ゆーいち」という文字列は置き換えら得ません。
通常、replaceメソッドを使って文字列を置き換える場合その文字列が複数あっても置き換えられるのは最初の１つだけになります。
それを解消してくれるのがgオプションです。

```正規表現.js
var name = "私はゆーいちです、ゆーいちはエンジニアです"；
    name.replace(/ゆーいち/g, "ゆー太郎");
   => "私はゆー太郎です、ゆー太郎はエンジニアです"
```

これで全て置き換える事ができました。
gオプションを定義するときは、replaceメソッドの**第一引数である//の後に書きます。**

## iオプション
次にiオプションです。
iオプションはmatchメソッドなどを使って文字列を検索するとき大文字と小文字を区別しないというオプションです。
まずはiオプションを使わない場合をみてみます。

```正規表現.js
var name = "私はYuichiです"；
    name.match(/yuichi/);
   =>null

```
このように「Yuichi」という文字列の最初の文字が大文字のため「yuichi」で検索してもマッチしません。
これを解消してくれるのがiオプションです。

```正規表現.js
var name = "私はYuichiです"；
    name.match(/yuichi/i);
   =>["Yuichi"]
```
これで「Yuichi」という文字列を抽出する事ができました。
iオプションを定義する場合もmatchメソッドの引数である//の後に記述します。

## 最後に
今回紹介した、gオプションは電話番号のハイフンを取りたいときや、空白を無くしたいときなどに使えるのではないでしょうか。

最後まで読んでいただきありがとうございました。
Railsチュートリアル　第２章

Railsチュートリアルの第２章のtoy_appに記載してある、
アプリケーションの計画はポートフォリオ制作の際に
見直しそうなので自分用にメモしておきます。


#＜アプリケーションの計画＞
①どのようなアプリケーションにするか計画を立て、生成。
```$ cd ~/environment
$ rails _5.1.6_ new アプリ名_app
$ cd アプリ名_app/```

②Gemファイルの編集
（Railsチュートリアルで掲載されていたものを拝借）
![スクリーンショット 2019-03-30 15.56.30.png](https://qiita-image-store.s3.amazonaws.com/0/378334/247eaf88-e7bd-4a20-35a1-16188bd06e2b.png)

変更したら、本番以外のgemをインストールする。
```bundle install --without production```

うまくいかなかった場合は、
```bundle update```

③Gitでこのアプリケーションをバージョン管理下に置く。
```$ git init
$ git add -A
$ git commit -m "Initialize repository"```

④Bitbucketで [Create] ボタンをクリックして、新しいリポジトリを作成。
　　　生成したファイルを新しいリモートリポジトリにプッシュする。

```$ git remote add origin git@bitbucket.org:<username>/アプリ名_app.git
$ git push -u origin --all```

⑤ビュー、コントローラー、ルーティング、モデルを変更したら
　　　　この変更をコミットして、Herokuにプッシュする。

```$ git commit -am "コメント"
$ heroku create
$ git push heroku master```


ついでに、MVCモデルの動きもメモ。

![スクリーンショット 2019-03-31 10.22.19.png](https://qiita-image-store.s3.amazonaws.com/0/378334/2da5c351-b691-462b-1b77-648a9d19cc4d.png)

この図（Railsチュートリアル）、めちゃくちゃ分かりやすい。

ブラウザが見たいよ〜といったもの（URLのリクエスト）を、
ルーターがコントローラーへ橋渡しをして
コントローラーはモデルへ繋げデータを取得しコントローラーに返す。
返ってきたものをコントローラーはビューに渡し、
ビューは該当するビューを選び、起動させる。
それをまたコントローラが受け取り、ブラウザに返す。
VBAに関してのメモ集

毎回ググってもいいんですが、勉強したことはアウトプットすることが
大事なので自分用の
メモとしてこっちにも記載しておきます。

順番とかは気になった順なので、あんまり整理されてはいません。

## 新しいBookを作成して指定するシートをコピーする。

新規ブックの作成とテンプレートのコピー
Workbooks.Add '新規にBook（Excelファイル）を作成
ThisWorkbook.Worksheets("テンプレート").Copy before:=ActiveWorkbook.Sheets(1) '新規ワークブックのsheet1の前にひな形をコピー
ActiveWorkbook.Sheets("Sheet1").Delete 'もし新規作成するときに生成されたシートが余計なら削除する。


## VBAの変数に関して

普通のプログラミング言語に慣れているとあんまり馴染みにないものが出てくる
変更に強い変数になるようにするには以下のように宣言するのが良い
Dim 変数名 As データ型名
変数名 = 値

## 個人用マクロを作成する

マクロを特定のBookに保存したくない場合は個人用マクロに保存する。
PERSONAL.xlsb
編集したい場合は「alt+F11」でVBAを開くことが出来る。

## シート上の図形をリサイズする。

アクティブシート上で以下をする
ActiveSheet.Shapes.SelectAll
これで全選択が可能。
obnizを使ってタブレットから鉄道模型を操作してみる～その２～

前回の投稿では、obnizとモータドライブ回路を連携して鉄道模型を動かした内容を紹介しました。
今回は、操作画面を整えたので紹介いたします。

前回の操作画面はこんな感じで、HTMLの基本的なパーツのみで構成していました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3331353534342f30303032316232662d613266312d323735632d643633362d6637316139343832313466392e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/315544/f17c942f-67bd-f68f-bc8d-9f3628e97d1d.png)




今回は、操作画面を4つの画面で構成しています。
1つ目はマスコン操作で列車をコントロールするための画面です。
マスコン操作によって加減速度を制御します。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/315544/93bcc3c2-a380-36b9-201d-2372e440c0c7.png)


自動運転ボタンについては、今後センサ等の列車位置検知回路を追加したときに、
自動で駅に止めるなどの制御に切り替えられるよう設置しました。
また、定速走行機能も追加しています。

2つ目はボリュームで列車をコントロールするための画面。
ボリュームでDuty比(速度)を制御します。
![22.png](https://qiita-image-store.s3.amazonaws.com/0/315544/f8d76ad5-a7fe-ab8d-8a75-dd8a5b12ec84.png)

3つ目はパラメータ設定画面です。
真ん中の空きスペースにはちょっとした絵を入れたいのですが、現在保留中です。
![32.png](https://qiita-image-store.s3.amazonaws.com/0/315544/fe36fda6-13fb-a381-3a91-2d5aadaa7af3.png)


4つ目はポイント(分岐器)の制御画面です。
とりあえず6個まで制御できるようにしました。
![42.png](https://qiita-image-store.s3.amazonaws.com/0/315544/906b93f4-6a21-7152-39e1-9e4731c1ff33.png)


今回は、1ページのHTML上に4つの画面を作成し、1画面ずつ表示するようにしました。
画面右のボタンを押し、表示したい画面を選択する事で、画面を切り替えます。


実際に運転したときの動画が下記になります。
（埋め込みができませんので、URLでの貼り付けとなります）
https://youtu.be/B2rlsFWa5a8


運転途中に画面を切り替えて、ポイントを操作することも可能です。