OmniAICreator/Qiita-1.07M huggingface dataset:
Ogre v2.1 とnanaの連携（windows）

備忘録です。

前回（Ogre v2.1のビルド）からの続き
https://qiita.com/ManukeFace/items/9e9cc8ed53294fcc9b88

#動機
最終的にはかっこよく可視化できる自前の物理シミュレーションのプリポストが作れたらいいなと

#環境
前回と同じ
・windows10
・visual studio community 2017 (15.7.5)
・CMake 3.12.0
・Ogre 2.1(Commits on Aug 5, 2018)
・nana 1.61

#今回やったこと
・Ogre側にnanaのフォームのウィンドウハンドルを渡してnanaのフォーム上に描画させた。
・Ogreのレンダリングループをnanaのタイマーイベントに移して処理させた。

#nana
http://nanapro.org/en-us/
Ogre側とランタイムは合わせるようにする以外は
公式HPから落としてCmakeで問題ないはず。
C++11以降の機能を使って書かれていて勉強になる。

#Ogreの参考プログラム
前回ビルドはできたものの、
・サンプルはラッパクラスがかませてあって何やってるのかよくわからない
・資料はv1.xのものがほとんど
・v1.xのチュートリアルはv2.1だとそのままでは動かないが
　どう修正したらいいのかは、何やってるのかよくわからないのでよくわからない
といったところで困っていたところ,プリミティブなプログラムを見つけたので
ここを参考にすることにした。
https://github.com/Ybalrid/Ogre2Test
ただ、上記の実行するとSinbadメッシュのテクスチャまわりで
例外が出るので、今回Sinbadメッシュ関連の部分はコメントアウトした。
（そのうち勉強しよう）

#main.cppでいじったところ
####コメントアウトする行
  225~249
  295~307

####nanaのインクルードを追加

```main.cpp
#include <nana/gui.hpp>
#include <nana/gui/wvl.hpp> 
#include <nana/gui/timer.hpp>
#include <nana/gui/widgets/button.hpp>
#include <iostream>
``` 
####nanaのフォーム作成とウィンドウハンドルの取得
Ogreの描画ウィンドウ作成前ならどこでもよい

```main.cpp
int main(void)
{
	auto run{ true };

	//Ogreに描画させるnanaのフォームfmを作成、サイズはOgreのウィンドウサイズに合わせる
	nana::form fm(nana::API::make_center(WindowSize.x, WindowSize.y));
	//ボタンを手前に表示させるためのnested_formを作成
	nana::nested_form nfm(fm, nana::rectangle{ 10, 10, 100, 20 }, nana::form::appear::bald<>());
	nfm.show();
	//exitボタンの作成
	nana::button btn(nfm, nana::rectangle{ 0, 0, 100, 20 });
	btn.caption(L"いぐじっと");
	//exitボタンの動作の登録
	btn.events().click([&fm] {
		fm.close();//フォームが一つなのでnana::exec()を抜けて終了
	});
	fm.show();
	//fmのウィンドウハンドルを取得
	auto fmHndl= reinterpret_cast<HWND>(fm.native_handle());
	//Ogreの描画ウィンドウ指定はunsigned intなので変換
	auto uifmHndl = reinterpret_cast<unsigned int>(fmHndl);
```

####Ogreの描画ウィンドウをnanaのフォームに設定
もとのmain.cppの173行目に書く

```main.cpp
	misc["externalWindowHandle"] = std::to_string(uifmHndl);
```

####描画更新のタイマー設定とnanaのメインループ開始
もとのmain.cppの295行目に挿入
20msecおきに描画を更新させるタイマーイベントを作成して、nanaのメインループ内で処理する。

```main.cpp
	//描画更新のためのタイマー
	nana::timer tmr;
	//描画更新イベントを登録
	tmr.elapse([&] {
		//内容は元のレンダリングループの処理そのまま
		then = now;
		orientation = animation(now = (static_cast<float>(root->getTimer()->getMilliseconds()) / 1000.0f));
		objectNode->setOrientation(orientation);
		root->renderOneFrame();
	});
	//更新タイミングの設定
	tmr.interval(20);
	//タイマーの開始
	tmr.start();

	//nanaのメインループ開始
	nana::exec();
```

#実行すると
アテナ像がくるくる回るはず。
いぐじっとボタンを押すと終了。
![Ogre2_1withNANA2.png](https://qiita-image-store.s3.amazonaws.com/0/147776/e4dd8061-6d97-1983-bb84-bad041cd55e4.png)

#以上
お疲れさまでした。
ところで、OSSとはいえ人様のソースをいじったものを全部のせても良いのかわからなかったのでそうしなかったのですが普通はどうするもんなんでしょう。
無料のWindows仮想マシンをQEMUで動かす

MicrosoftはIEやEdgeのテスト、開発環境構築用に無料で使えるWindows仮想マシンを配布しています。

[Free Virtual Machines from IE8 to MS Edge - Microsoft Edge Development](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)
[Windows 10 仮想マシンをダウンロードする - Windows アプリ開発](https://developer.microsoft.com/ja-jp/windows/downloads/virtual-machines)

仮想マシンソフトウェアはVMWare, Hyper-V, VirtualBox, Parallelsに対応してるのですが、

- VMWare : 無料で使えるのはWindowsにあるPlayerのみ
- Hyper-V : WindowsのPro, Enterprise, Education, Serverのみ
- VirtualBox : アップデートとかで頻繁に起動しなくなるから嫌い
- Parallels : 有料。しかも毎年お金を払わないといけないアップデートを要求してくる。

というわけでMacとLinuxをメインで使ってる僕には非常に困ったラインナップなのです。
KVM使わせろや

というわけで、Microsoft配布の仮想マシンをQEMUで動かします。

# 環境

x86_64のQEMUが使えるパソコンであれば何でもいいです。
仮想マシンはサイズが大きいのでしっかりしたインターネット環境と十分なディスクの空き容量も必要でしょう。
QEMUはパッケージマネージャーから普通にインストールすればいいと思います。

# 仮想マシンのダウンロード

[Free Virtual Machines from IE8 to MS Edge - Microsoft Edge Development](https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/)
[Windows 10 仮想マシンをダウンロードする - Windows アプリ開発](https://developer.microsoft.com/ja-jp/windows/downloads/virtual-machines)

ここらからHyper-V用の仮想マシンをダウンロードしてください。

"Microsoft Edge Development"からダウンロードできる仮想マシンはIEとEdgeの動作確認用なので、Windowsの標準ソフトウェア以外は何も入ってません。ただWindows動かしたいだけならこっちでいいでしょう。
"Windows アプリ開発"からダウンロードできる仮想マシンには最初からVisual Studioとかの開発環境がインストールされています。でも、その代わりサイズがでかいです。

この記事では"MSEdge on Win10 (x64) Stable (17.17134)"を使ってます。

ちなみに、これらの仮想マシンには使用期限があります。使用期限を過ぎると、最初から仮想マシンを構築し直す必要があります。なので、常用には向きません。あくまでテスト用として割り切って使用してください。

![edge.png](https://qiita-image-store.s3.amazonaws.com/0/242402/642cceec-51c1-9b86-784b-a32f15fd60b0.png)

ダウンロードができたらzipファイルを展開しましょう。

それで、仮想マシンといっても重要なのはWindowsが入ってるディスクイメージだけです。仮想マシンの構成ファイルとかは何とでもなります。なので、ダウンロードした中で使うのは"Virtual Hard Disks"フォルダにあるvhdxファイルだけです。
僕がダウンロードした仮想マシンでは"MSEdge - Win10.vhdx"という名前でした。

そして、QEMUではHyper-V用のディスクイメージであるvhdxをそのまま読み込むことができます。
起動するときに使うので適当な作業ディレクトリにコピーしておいてください。

# UEFIファームウェアを用意

※いつのまにか、通常のBIOSで起動するようになってました。この手順は必要ありません。

~~配布されてる仮想マシンは、UEFI環境上にWindowsをインストールしたものになっています。なので、UEFIで起動する必要があるのですが、実はQEMUはそのままだと仮想マシンでUEFIを使えません。~~
~~そこで、QEMU上で動くUEFIを使えるファームウェアを用意します。~~

幸いGithubでビルド済みのファームウェアを配布してくれている人がいたので、ありがたく使わせてもらいます。
[GitHub - BlankOn/ovmf-blobs: BIOS.bin for qemu to support UEFI](https://github.com/BlankOn/ovmf-blobs)

必要なのはbios64.binというファイルだけなので、これを先ほどのvhdxファイルと一緒の場所にコピーしてください。

# 起動

あとは、ターミナルでvhdxファイルのあるディレクトリに移動して

```sh
qemu-system-x86_64 -m 4096 -smp 2 -hda MSEdge\ -\ Win10.vhdx 
```

で起動できるはずです。
"-m"はメモリサイズ、"-smp"はコア数なので、お使いのホストマシンのスペックによって適宜変えてください。

また、KVMの使える環境ならば"-enable-kvm"を付けるといいでしょう。速くなります。

![画面共有ピクチャ2018年8月16日 15.24.58 JST.png](https://qiita-image-store.s3.amazonaws.com/0/242402/9a95f5f4-510e-9e3b-8b75-1b5da3c9f814.png)

もちろんMacでも使えますが、KVMは使えないので遅いです。
Hypervisor.frameworkは使えるのかな？
使えたら別記事にしたいと思います。

<img width="912" alt="スクリーンショット 2018-08-16 15.39.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/242402/c82bff29-4a87-a98b-2932-f2682d3bc7e6.png">
PleasanterでユーザーがログインIDを変更できないようにする

## デフォルトの設定状態
Pleasanterの初期設定のままだと、ユーザーが自由にログインIDを変更できてしまいます。

## ユーザーIDの入力欄の変更を無効にする
これはシステム管理上好ましくないので、特定のユーザー以外にはログインIDが変更できないようにすることにしました。

##拡張スクリプトを使って入力欄の変更を無効化
ということで、Pleasanterの拡張スクリプト用フォルダ（{WEBROOT}\pleasanter\App_Data\Parameters\ExtendedScripts)に、以下の拡張スクリプトを配置して、administrator以外のユーザーでログインした時には、ユーザープロファイル画面を開いても、ログインID欄の変更を無効化しました。
無効化しただけでは、グレーアウトされず変更できそうに見えてしまうので、グレイアウトするようにもしています。

```JavaScript:disableUserIdChange.js
$(function(){
  var UserId = $("#UserId").val();
  switch (UserId) {
    case "1":
      break;
    default:
      switch (true) {
        case /users\/login/.test(location.href):
          break;
        case /users\/.*/.test(location.href):
          $("#Users_LoginId").prop('disabled', true);
          $("#Users_LoginId").removeClass("control-textbox");
          $("#Users_LoginId").addClass("control-text");
          break;
      }
      break;
  }
  // console.log(location.href);
});
```
Administratorでログインすると今まで通りに、変更できますが

![byAdmin.jpg](https://qiita-image-store.s3.amazonaws.com/0/256425/3f83a84f-20a9-98e4-f8f5-e33800d40210.jpeg)


一般ユーザーでログインするとグレーアウトされて変更もできなくなります。

![byUser1.png](https://qiita-image-store.s3.amazonaws.com/0/256425/626cbc2a-beeb-e3cf-1b4d-6ce214a3d92f.png)

## 許可するユーザーを増やしたい時は…
```JavaScript
   switch (UserId) {
    case "1":
    case "2":
    ︙
      break;
```
というように、ひたすらユーザーIDを並べていきます。
APIでユーザー情報や所属グループを取得できたりすると良いんですけどね～

## うまくいかない時は…
```JavaScript
// console.log(location.href);
```

　　　　↓↓↓

```JavaScript
 console.log(location.href);
```

ここのコメントを外してIISを再起動、F12キーを押してコンソールログを表示した状態で、トップページを再読込みするとURLが確認できます。

![consoleLog.jpg](https://qiita-image-store.s3.amazonaws.com/0/256425/97679147-4366-4637-3e67-d8b91203cf47.jpeg)

if文のlocation.hrefでチェックしているURLと違っていないか確認してみてください。

## まとめ
初期状態で使いづらいなと感じても、拡張スクリプトや拡張SQL、拡張スタイルシートを使用することで、カスタマイズが可能です。どんどんカスタマイズして便利なツールに育てていけるのも、Pleasanterの魅力のひとつだと思います。
PHPStrom ショートカット、関連URLまとめ

## 環境構築で使用した資料

- [PhpStorm 日本語化](https://www.willbrains.jp/page/4)
- [PHPStrom ライセンスの購入](https://www.willbrains.jp/product/2)
- [PHPStrom 日本語化](https://www.willbrains.jp/page/4)
- [PHPStrom 背景色やスタイルの変更](http://blog.a4works.co.jp/archives/576)

## PHPStrom ショートカット

- クラス検索(Command + O)
- 設定/環境設定ダイアログ（⌘,）
- 自動整形(Option + command + L)
- 全ファイルから文字検索(command + shift + F)
- 上行をコピペする(Command + D）
- 差分を表示する(バージョン管理 > 開きたいファイル > Command + D）

## Debug

- [Max OS X ローカルにXdebugインストール](https://weblike-curtaincall.ssl-lolipop.jp/blog/?p=506)
- [中断されたプログラムの調査](https://pleiades.io/help/phpstorm/examining-suspended-program.html)
vimiumの微妙に嫌な所を改善する。

#Vimiumって凄い。
vimの操作に微妙に慣れてきたので、vimっぽく動かせるchromeのアドオンを探していたのですが
Vimiumっていうすんごいアドオンに出会ってしまいました。
fキーで選択出来るわ、検索用のモーダル出せるわ、何やこいつ状態です。
しかし、微妙に使いづらい所があったんで、そこら辺の修正方法を書いておこうと思います。

## googleの検索結果もコマンドで次ページへ移動出来るようにする
初期状態では、gooleの検索結果を[[や]]で改ページ出来ません。これは検索するうえで不便だと思います。

![タイトルなし.png](https://qiita-image-store.s3.amazonaws.com/0/253308/a0cc36e7-b983-22db-7eb4-ce283c9a51cb.png)

設定のPrevious pattrnsとNext patternsに"前へ"と"次へ"を追加します。
これで改ページを行えるようになります。

## 新規タブを検索画面にする。
僕のchromeの設定のせいかもしれませんが、初期状態の新規タブだとアドレスバーにフォーカスした状態になってしまいます。そのうえ、[javascriptでフォーカスを抜ける技](https://github.com/philc/vimium/issues/840)も使えませんでした。これは新規タブの画面を通常の検索画面にすることで改善出来ました。

![タイトル2し.png](https://qiita-image-store.s3.amazonaws.com/0/253308/0b7a3c34-2fa9-7434-463a-b30610ebeaf4.png)

設定のNew tab URLを検索画面にしてください。

## 検索すると勝手にテキストボックスにフォーカスされている
oを押してカスタムエンジンを使うと、勝手にテキストボックスにフォーカスされていて一々Escで抜けるのが面倒でした。

![タイトルなし3.png](https://qiita-image-store.s3.amazonaws.com/0/253308/7407cacc-3623-b3ab-a361-74354238aa0d.png)

これも設定のDon't let pages steal the focus on load にチェックボックスを入れるだけで改善出来ます。
SSH認証キーをGitLabに登録・設定手順のメモ

SSH認証キーをGitLabに登録しました。クローンするときは、HTTP経由でもできますが、今後の運用が楽なので（裏側で承認してくれるため）SSH認証にしました。

ですが、この方法は最初ちょっと手間なので調べながらやった記録をします。

# 秘密鍵と公開鍵について

SSH認証に必要なのは、秘密鍵と公開鍵です。。２つあって初めてSSH認証できます。発行したら、GithubやGitlabに公開鍵を渡します。ざっとこんな手順です。

# SSH Keysがあるのかの確認

買ったばっかりのPCでない限り、おそらくSSh KeyがPCにあると思うので確認して見ましょう。

```bash
ls -al ~/.ssh
```

このコマンド確認できます。

# 秘密鍵と公開鍵の生成

ホームディレクトリ直下に`.ssh`ディレクトリがなければ作成して、そこに公開鍵と秘密鍵を作成する。

作成コマンドは`ssh-keygen`です。

```bash
Enter file in which to save the key (/Users/HOME/.ssh/id_rsa):
```

保存先を聞かれていますが、カレントディレクトリでOKであれば、そのまま`Enter`を入力。

```bash
Enter passphrase (empty for no passphrase):
```

今回は、パスワードなしで行くので、そのまま `Enter`を押す。

```bash
Enter same passphrase again:
```

同じく、今回は、パスワードなしで行くので、そのまま `Enter`を押す。

そうすると、`id_rsa`と、`id_rsa.pub`が作成されて入ればOKです。

あとは、GitlabでSSHを登録する先があります。UIが変わってるかもしれませんが、僕の場合は、アカウントのアイコンをクリック > setting > SSH keys

ここに、公開鍵をとうろくすれば、`Clone`できるようになります。以上です！

# 参考
- https://wa3.i-3-i.info/word1829.html
- https://qiita.com/suthio/items/2760e4cff0e185fe2db9
- https://qiita.com/redamoon/items/07e445d1fce360cb5fa3
- https://qiita.com/CUTBOSS/items/462a2ed28d264aeff7d5
- https://qiita.com/pompom0c0/items/4b4bd09ab820a1d6fc11
Slack—絵文字リアクションを連続して選ぶ裏技 Shift+Enter ( または Shift+クリック )

Shift+Enter (またはShift+クリック)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/86acaef8-25ab-0779-0407-ad034fef3e82.png)

Shift+Enter (またはShift+クリック)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/35f206d3-fc2d-c1ac-ed4a-7a495b5e07d6.png)

結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/5c0518e7-273d-1b36-9dd3-27324d5bf8e5.png)

## 環境

- Mac App








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
今更ながら、CloudFormation で GuardDuty を使えるようにしてみた。

## はじめに
勝手に始めました。今更ながら CloudFormatin シリーズ。今日は、GuardDuty 編です。
最終的には複数アカウントの紐づけまでやる予定なんで、マスターアカウント想定で作ります。

## つくってみた
### つくるもの
- GuardDuty の有効化
- IAM ユーザ(リードオンリーのイメージで)

### テンプレートの例
安定の yaml で。

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: "GuardDuty Test"
Parameters:
  Username:
    Default: gd-user
    Type: String
Resources:
  GDIAMUserGroup:
    Type: 'AWS::IAM::Group'
    Properties:
      GroupName: GuardDutyReadOnlyGroup
  GDGroupPolicy:
    Type: 'AWS::IAM::Policy'
    Properties:
      Groups:
          - !Ref GDIAMUserGroup
      PolicyName: 'GuardDutyReadOnly'
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Action:
              - "guardduty:ListMembers"
              - "guardduty:GetMembers"
              - "guardduty:ListInvitations"
              - "guardduty:ListDetectors"
              - "guardduty:GetDetector"
              - "guardduty:ListFindings"
              - "guardduty:GetFindings"
              - "guardduty:ListIPSets"
              - "guardduty:GetIPSet"
              - "guardduty:ListThreatIntelSets"
              - "guardduty:GetThreatIntelSet"
              - "guardduty:GetMasterAccount"
              - "guardduty:GetInvitationsCount"
              - "guardduty:GetFindingsStatistics"
            Resource: "*"
  GDIAMUser:
    Type: 'AWS::IAM::User'
    Properties:
      Groups:
        - !Ref GDIAMUserGroup
      UserName: !Ref Username
  GDIAMAccess:
    Type: 'AWS::IAM::AccessKey'
    Properties:
      Status: Active
      UserName: !Ref GDIAMUser
  GDSettings:
    Type: 'AWS::GuardDuty::Detector'
    Properties:
      Enable: true
```

### 困ったこと
特になし？

## おまけ
Organization 登録がされたみたい。今後にこうご期待ください。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
「ビットコインとブロックチェーン」まとめ

# はじめに

* [ビットコインとブロックチェーン](http://amzn.asia/fSMc0E3) を読んだので自分の理解のためにざっくりまとめる。

# ビットコインとは

* ブロックチェーン上で管理される仮想通貨

# ブロックチェーンとは

* ビットコインの取引が記載された分散管理台帳

# ビットコインの利用の流れ

1. `ビットコイン利用者` が「私から誰々に何ビットコイン送金する」という取引（`トランザクション`）を作成してビットコインのネットワークに申請する
1. トランザクションはネットワーク上に伝播して各ノードに共有される
1. `ビットコインマイナー` が複数のトランザクションをまとめて `ブロック` を作成し、既存の管理台帳（`ブロックチェーン`）へ新たな取引を追記する
1. 新たな取引が追記された管理台帳がネットワーク上に伝播されることで取引が成立となる

# トランザクションとは

* ビットコインの取引データ
* ビットコインの管理台帳上にはだれが何ビットコイン持っているという直接的なデータはなく、だれがいくらもらったという過去のすべてのトランザクションを累計して各ユーザーの所持ビットコインを算出するしくみになっている。
* なので新たなトランザクションを作成する際には「誰から誰にいくら送る」という形ではなく、過去のトランザクションを参照して「このトランザクションでもらったビットコインを別の誰々に送金する」という形をとる
* 各トランザクションには鍵がかけられており所有者にしか利用することができない。この鍵がウォレットである。
* 新たなトランザクションを作成する際、元になるトランザクションと新たなトランザクションのコイン量の差額がトランザクション承認の手数料となり、マイニングが成功したユーザーの所持コインとなる。手数料が高いトランザクションほど優先して処理されやすい。

# トランザクション承認の詳細

* 発行されたトランザクションはまとめられてブロックとなる
* ブロックチェーンはブロックの連結リストであり、古いトランザクションを含むブロックを親としてより新しいトランザクションが子ブロックとなる管理台帳である
* 新しいブロックは既存のブロックチェーンの一番新しいブロックを親とする
* ブロックはデータ列でありハッシュ関数にかけることで値が得られる
* ブロックには任意の値を入れられるフィールド（`nonce`）があり、この nonce フィールドを調整して `ブロックをハッシュ関数にかけた結果の値` が `目標とする値` よりも小さくなった時に新しいブロックがブロックチェーンに追記される資格を得る
* この都合のいい nonce の値を探すことがマイニングと呼ばれる
* 前出の `目標とする値` は過去の取引履歴から算出され、その時々のマイニング参加者の処理能力で 10 分程度の計算が必要となる値に随時更新される

# マイニングとは

* ブロックチェーンに新たなブロックを追記すること
* マイニングに成功するとトランザクション手数料と新規発行コインがもらえる
* 新規発行コイン量はブロックチェーンのブロック数に対応して決まっており、ブロック数が増えるごとに発行量が減っていき最終的にはゼロになる。

# 安全性について

* 自分のトランザクションが他人に勝手に使われることはないのか？
  * トランザクションを使用できるのは対応するウォレットを持っている人だけ
  * ウォレットが盗まれればトランザクションも勝手に使われてしまう
    * ウォレットの鍵から子供鍵を生成して利用することで紛失や盗難のリスクを減らすことができる
    * 鍵はただの文字列なので印刷して金庫にしまっておくなどすることができる

* 管理台帳が改ざんされることはないのか？
  * トランザクションを改ざんするとブロックのハッシュ値が変わるので nonce の計算をし直す必要が出てくる。古いブロックであればあるほど影響範囲が大きくなり、現実的な時間で計算しなおすということが難しくなるので、これをもって安全性の根拠とする
  * 理論的にはネットワークの参加者の多くが攻撃者に協力することで攻撃を行うことは可能だが、ネットワーク全体の処理力が指数関数的に成長し続けているので現実的ではないし、攻撃に対しいてはすぐにビットコインコミュニティによって対応策がとられることでしょうということ。
プログラミング学習　講義内容　8/16

・これまでの復習
三人の人から発表（今までの学習内容）
１．山本君：LESSについて
CSSの無駄をそぎ落としたもの
特徴：階層化できる、演算できる、ミックスインできる

階層化

これ
header{
font-size:20px;
color:red;
}
header a{
font-size:20px;
color:blue;
}
を
こう
header{
font-size:20px;
color:red;
}
a{
color:blue;
}
できる。


ミックスイン
color→変数
font-size 15px
padding 10px
margin 5px
としたい場合、
.mix-in(@color){
color:@color;
font-size:15px;
padding:10px;
margin:5px;
}

とすることで、例えば
h1{font-size:20px;
.mix-in(red)
}
が
color→red
font-size 20px
padding 10px
margin 5px
になる。


補足
lessc ~~(LESSファイルの名前).less ~~(CSSファイルの名前).css
というコマンドを打つことでLESSファイルを召喚できる



２．倉田くん：名前空間namespace
使用目的：クラスの名前が呼び出すときに被っていても使えるようにするため
→requireで読み込んだりすると被っていたらエラーが出る(namespace無しの場合)

使い方
namespace 名前空間名;
で指定できる。一つのファイルに複数の空間名を付けることお可能
※namespaceの前には命令文とHTMLを記述しない


名前空間も被る場合
サブ名前空間をつくる
namespace 名前空間/サブ名前空間名/サブ/サブ/...

名前空間が長すぎるときにはuseを使う
use oo/xx/ii as AA;
でAAがoo/xx/iiというnamespaceというものにすることができる。
<?php
require_once'tokyo.php';
use asia/japan/kanto/tokyo as tokyo;
>
これで
asia/japan/kanto/tokyo を tokyoという形に省略することができた。（どこまでを省略するかは自由！例:kantoまでをasで違うものに置き換えてtokyoは残す、など）

3．西村君：オブジェクト指向
メリット
あらかじめ変更が予想される個所をクラスとして個別にまとめておくことで柔軟に変更に対応できる。
必要な知識
クラス：主に設計図。
インスタンス
例：車を作るときの設計図。スピード、色とかの要素は関数。
逆にその設計図の中でスピード、色を決めたら車が出来上がるというようなものにする式がインスタンス

カプセル化：外部から見て簡単に見えるものを作る、不必要に複雑な部分は外部から見て隠す
そのクラスの中での変更をそのクラス内だけにできる

ポリモーフィズム：異なる動作を同じ命令で実現すること
例：走れ！とコマンドすると自動車では「ブーン！」自転車では「シャー！」と表示される、といったイメージ
クラスによって、そのコマンドによって出てくる


interface~~~{}
としておくと、その中で決めておいたもの決めずに実行したときにエラーを吐くようにできる
テンプレート（interfaceの中）に従ってもらえるようにする
他にもabstractがある

クラスの中で使われる関数：メソッド
クラスの中で使われる変数：プロパティ
Vagrantのコマンドメモ


# Vagrantとは

簡単に言うと、VM環境の構築を楽にやってくれるツールです。

# 環境
OS:Windows10
Vagrant:2.0.4
VirtualBox:5.1.34

# VirtualBoxインストール

まずはVirtualBoxをインストールします。
https://www.virtualbox.org/wiki/Downloads
からダウンロード。最新版は、VirtualBox-5.1.34-121010-Win.exe

# Vagrantをインストール

次にVagrantをインストール
https://www.vagrantup.com/downloads.html
からダウンロード。最新版は、vagrant_2.0.4_x86_64.msi

# OSを作ってみる

とりあえず、OSを作って起動する

```bash
$ vagrant init bento/ubuntu-18.04
$ vagrant run
```

でSSHで接続

```bash
$ vagrant ssh
```
とすると、作成したOSに接続できます。
簡単ですね。

以降は、その他のコマンドを忘れないためのメモです。

# Boxの管理コマンド
Boxとは、仮想マシンのテンプレートのようなもので、OSのディスクイメージファイル等が入ったファイルの集まりです。

## Box を追加する

```bash
$ vagrant box add <name> <url>
```
name:box名（なんでもいい）
url:boxファイルのURL

## Box一覧を確認する

```bash
$ vagrant box list
```

## Boxを削除する

```bash
$ vagrant box remove <name>
```
name:box名

# 初期化

```bash
$ vagrant init <name>
```
name:box名

# 仮想マシン操作コマンド
## 起動する

```bash
$ vagrant up
```

## ssh接続する

```bash
$ vagrant ssh
```

## 停止する

```bash
$ vagrant halt
==> default: Attempting graceful shutdown of VM...
```

## 設定ファイルを再読み込みする

```bash
$ vagrant reload
```

## 削除する

```bash
$ vagrant destroy
    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Destroying VM and associated drives...
```
Railsのよしなに力が高すぎた話

`Ruby 2.5`
`Rails5.1.x`

## 次のようなソースがあるとします。

なにかを編集する画面です。モデルに`@user`とあるのできっとユーザーの情報でしょう。
なんと`気分をCHANGE!`ボタンがついている編集画面です。
楽しく作業ができそうですね。

```rhtml

<div id="content">
  <%= form_with(model: @user) do |f| %>
    <div>
      <h1>なにかの編集画面</h1>
      <div>
        <%= f.submit "OK" %>
        <%= button_tag "気分をCHANGE!", type: "button", onclick: "change_color()" %>
      </div>
    </div>
  </div>
  <p><span class="hissu-dayo">*</span>は必須入力項目です。</p>
  <%= render :partial => "form", :locals => {:f => f } %>
  <%= button_tag "すべてをRESET...", type: "button", onclick: "ex_death()" %>
  <% end %>
</div>
          
<script>
  function change_color(){
    $("form input, form button").css('background-color',"skyblue");
  }

  function ex_death(){
    (すべてのそんざい すべての次元を消し そして わたしも消える 処理);
  }
</script>
```

## ここで問題です。

`気分をCHANGE!`ボタンを押すとさわやかな空色に背景が変わるのは次のうちどれでしょう？

1, 「OK」ボタン
2, 「OK」ボタンと「気分をCHANGE!」ボタン
3, 「気分をCHANGE!」ボタンと「すべてをRESET...」ボタン
4,  ALL-IN！

## 正解は。

2の「OK」ボタンと「気分をCHANGE!」ボタンでした。
聡明な読者の方には簡単すぎたかもしれませんね。
正解者に拍手！

…で終了というわけにもいかないので。

## 解説。
このソースでいうと、10行目の`div`の閉じタグの前に`form`の閉じタグが挿入されます。
そう。お気づきになりましたでしょうか。なんと`div`の閉じタグが一個多いのです。

```rhtml

<div id="content">
  <%= form_with(model: @user) do |f| %>
    <div>
      <h1>なにかの編集画面</h1>
      <div>
        <%= f.submit "OK" %>
        <%= button_tag "気分をCHANGE!", type: "button", onclick: "change_color()" %>
      </div>
    </div>
  </div> <!-- この閉じタグがいらない！ -->
  <p><span class="hissu-dayo">*</span>は必須入力項目です。</p>
  <%= render :partial => "form", :locals => {:f => f } %>
  <%= button_tag "すべてをRESET...", type: "button", onclick: "ex_death()" %>
  <% end %>
</div>
```

そして、formの閉じタグは`<% end %>`の記述箇所14行目ではなく、親の`div`が閉じられる前に生成されることになります。
ので、みっつめの`button`タグは`form`の下ではなくなり、セレクタ指定から外れることになるのでした。

この程度のソースなら問題解決まで早いですが、
実際のソースだと外部js呼び出していたり色んなfunction経由したり、そもそも原因がjsにあるのかのきりわけにも時間かかる。
つまり、**マジで問題箇所が見つけられない。**
半日かかりました。

## 結論
Railsはよしなに力が高い。
インデントはちゃんとしようね。してください。
（レガシーなコードを保守している場合もまわりを巻き込んで手を入れていきましょう！）

### おまけ
現在携わっているプロジェクトでRailsのバージョンアップ中なのですが、Rails3.xでは起きていなかったので、
Railsもおにいさん（おねえさん？）になるに従ってよしなに力がどんどんあがっているということなんですね。
create-react-appでChrome拡張機能開発


## create-react-app をインストール
`npm install -g create-react-app`

## アプリケーション作成
`create-react-app [アプリ名]`

## public/manifest.json 編集
以下のようにmanifest.jsonを書き換える。最低限以下のようにすれば動きます。
(アイコンはお好きに)

manifest.jsonの仕様については、[公式ドキュメント](https://developer.chrome.com/extensions/manifest)を参照してください。


### Before
```
{
  "short_name": "React App",
  "name": "Create React App Sample",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
```

### After

```
{
  "manifest_version": 2,
  "version": "1.0",
  "name": "My Chrome Extension Sample",
  "icons": {
    "16": "icon16.png",
    "48": "icon48.png",
    "128": "icon128.png"
  },
  "description": "ReactでChrome拡張機能を作ってみる",
  "browser_action": {
    "default_icon": {
      "16": "icon16.png",
      "24": "icon24.png",
      "32": "icon32.png"
    },
    "default_title": "react extension",
    "default_popup": "index.html"
  }
}
```

## yarn build
以下のコマンドを実行。`build/` 以下にファイルが生成される

`$ yarn build`

## ビルドしたファイルをchromeに読み込ませる

1. chrome://extensions/ にアクセス
2. デベロッパーモードをON
3. パッケージ化されていない拡張機能を読み込む
4. buildディレクトリを指定

すると、URLバーの隣にアイコンが表示され、React Create App の画面が表示されます。

<img width="199" alt="react-chrome-extension-sample.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/104274/16fb1718-6fbb-6c62-9f21-9d04bfc9bc24.jpeg">

## もくもく開発
### Tips

#### 'chrome' is not defined  no-undef
create-react-app を使った場合、ビルド時にeslintのチェックが走り
`'chrome' is not defined  no-undef` と怒られてビルドできません。

これだとChrome APIsが使えないので、`/*global chrome*/` と記述する。

#### browserAction の`onClicked`は `componentDidMount` or `componentWillMount` で代用可能

browserAction の`onClicked` とは、アイコンをクリックしたときに呼ばれるイベントです。

クリック時にReactでなにかしたいときは、`componentDidMount` or `componentWillMount` を使えばOK

## 公開

公式の[Publish in the Chrome Web Store](https://developer.chrome.com/webstore/publish)を参考に進めればOK。

1. [Chrome Developer Dashboard](https://chrome.google.com/webstore/developer/dashboard) に行く
2. `build` をzip化
3. ストアに表示するスクリーンショットやプロモーション用の画像をアップ
4. その他必要項目を入力
5. $5払う
6. 公開
【初心者】routes.rbをもうちょっと深く理解する

Rails TutorialやProgateを一通り終えた人が、
実際にリリースされてるプロダクトを作るときによく利用されるTipsをまとめていきます。

まずはRoutesに関してです。

# Routes
##概要
これまでは、
`get 'users/index' => 'users#index'`
のようにHTTPメソッドを用いて定義していましたが、RESTを利用した方がもっと効率的です。
今回はRESTにまつわる実戦で使えるTipsを見ていきます。

なお、手で動かしながら結果を見る方法として、
サーバーを立ち上げて `http://localhost:3000/rails/info/routes` でブラウザから見るのがいいです。

[rorensu2236](https://qiita.com/rorensu2236/items/e06704f39538452c8d9b)さんの記事をすごい参考にしてます。
ありがとうございます。


## HTTPメソッドの別の書き方
Progateで学んで来たような書き方の他にとりあえず三種類くらい見つけました。

1. `get 'users/index', to: 'users#index'`
2. `get 'users/index', action: :index, controller: 'users'`
3. `get 'users/index'`

3は省略しすぎなので、個人的には1が好きです。

## PATCH, PUT, DELETE
基本全てget, postだけで実現できるようですが、patch, put, deleteなども存在します。

`post 'posts/:id/destroy' => 'posts#destroy'`
みたいに記載してましたが、
`delete 'posts/:id', to: 'posts#destroy'`

のようにPATHを減らして見やすくすることができます。

## REST
これが今回最も重要な概念。
index, show, new, create, edit, update, destroyを個別に宣言しないで一行で実現できます。
HTTPリクエストはGET, POST, PATCH, PUT, DELETEがメインなのでそれをベースに作ってしまう。

`resources :users`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/27c0a618-4df1-0a00-7168-fa606e48b577.png)

`resource :users`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/14e3dc1e-9f15-d7f4-64b8-8a95987855a0.png)

基本は`resources`を使うことが多いはず。
`resource`は`:id`が含まれないので、全削除、とか検索とか全ユーザーに共通した処理などのパスを記載するときに利用する。

## namespace
namespaceは`resources`と合わせ技で利用するとすごい便利だしコードがすごい見やすくなる。

```ruby:routes.rb
#管理者
namespace :admin do
  resources :mypage
end
#クライアント
namespace :client do
  resources :mypage
end
```

namespaceに更にnamespaceをネストして使ったりなど使い方は割と多い。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/a906e33c-b255-52cf-c5d9-76952ab12d91.png)

```ruby:routes.rb
namespace :admin do
  resources :mypage, {only: [:index, :show]}
end
```

こちらは`only:`を利用してアクションを制限することができる。
`before_action`とかと同じ使い方なので細かいことは省略します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/58eb8d76-4dd7-ba85-2a28-0a1ea5dc9a72.png)



## collection / member
resources以外で定義したいルーティングはこちらを使うと便利。

```
resources :clients do
  #コントローラーの新しいメソッド（idが不要な場合はcollection）
  collection do
    #全データ削除や検索には個別のIDは不要なのでcollection
    post:reset_all
    post:search
  end

  #コントローラーの新しいメソッド（idが必要な場合はmember）
  member do
    # そのクライアントのデータを初期化する作業や、初期データなどを入れる場合はidを利用するのでmember
    get :reset_data
    get :set_base_data
  end
end
```

コメントアウトの通りでmemberとcollectionは使い分ける。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180679/addefe92-8925-a322-6bb7-d8851f09f7d3.png)


# まとめ
ProgateやRails Tutorialの情報に加え、ルーティングに関してはここら辺が理解できれば問題ないかと思います。
あとは必要に応じて肉付けしていけば問題なし。
[.NET] 2018年8月現在の.NETにおける日本標準時

# はじめに

日本にサマータイムが導入されるかもしれないそうなので、.NETにおける日本標準時の仕様をチェックした。
以下は、東京標準時に設定されているWindows 10のPCでC#インタラクティブを実行した結果になる。

# 日本標準時の仕様

現在のタイムゾーン情報を取得するには以下のようにする。

```
TimeZoneInfo.Local
```

各プロパティは以下のようになる。

```
> TimeZoneInfo.Local.Id
"Tokyo Standard Time"
> TimeZoneInfo.Local.StandardName
"東京 (標準時)"
> TimeZoneInfo.Local.DisplayName
"(UTC+09:00) 大阪、札幌、東京"
```
"Japan Standard Time"ではなくて、"Tokyo Standard Time"である。
日本がひとつのタイムゾーンしかもたないという前提を極力排した名前ということだろう。桃岩時間のサポートが考慮されていると考えると胸が高なる。

```
> TimeZoneInfo.Local.SupportsDaylightSavingTime
false
> TimeZoneInfo.Local.GetAdjustmentRules()
TimeZoneInfo.AdjustmentRule[0] { }
```

タイムゾーン調整ルールは存在しない。
この調整ルールはサマータイムの規則のことなので、日本はサマータイムが導入されていないということになる。
いや、それぞれのルールは適用される開始日と終了日を持つので、より正しくは「.NETの世界」ではサマータイムが導入されたことがない、その予定もないということになる。
これは、日本では1948年から1951年にかけてサマータイムが導入されていたという事実に反する。

そのため、

```
> var date = new DateTimeOffset(1948, 5, 2, 9, 0, 0, TimeSpan.FromHours(9));
> TimeZoneInfo.ConvertTime(date, TimeZoneInfo.Local)
[1948/05/02 9:00:00 +09:00]
```

となる。
1948年5月2日はサマータイム初日であるので、歴史的に正しい処理系であれば
`[1948/05/02 10:00:00 +10:00]`
となるはずであるが、.NETの仕様ではこのようになっている。直感的でわかりやすいと言ってもいいし、歴史的に正しくないという言い方もできる。

歴史的に正しい結果を返す環境として、PHPがある。
http://d.hatena.ne.jp/hnw/20101223
PHPが元にしているtz databaseを使用する処理系では同じ結果になるのだろう。

なお、夏時間の表示名だけは用意されている。

```
> TimeZoneInfo.Local.DaylightName
"東京 (夏時間)"
```

# サマータイム導入タイムゾーンではどうなっているか

では、サマータイムが導入されるとどういうことになるのだろうか。
例として、太平洋標準時でおこなった結果が以下のとおりだ。

```
> var pst = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

> pst.Id
"Pacific Standard Time"
> pst.StandardName
"太平洋標準時"
> pst.DisplayName
"(UTC-08:00) 太平洋標準時 (米国およびカナダ)"
> pst.DaylightName
"太平洋夏時間"

> var date1 = new DateTimeOffset(2018, 1, 1, 0, 0, 0, TimeSpan.FromHours(-8));
> TimeZoneInfo.ConvertTime(date1, pst)
[2018/01/01 0:00:00 -08:00]

> var date2 = new DateTimeOffset(2018, 6, 1, 0, 0, 0, TimeSpan.FromHours(-8));
> TimeZoneInfo.ConvertTime(date2, pst)
[2018/06/01 1:00:00 -07:00]
```

00:00:00という同じ時刻を指定しても、1月と6月とでローカルの時刻やオフセットの値が変わるのがわかる。

```
> pst.SupportsDaylightSavingTime
true
> pst.GetAdjustmentRules()
TimeZoneInfo.AdjustmentRule[2] { TimeZoneInfo.AdjustmentRule { DateEnd=[2006/12/31 0:00:00], DateStart=[0001/01/01 0:00:00], DaylightDelta=[01:00:00], DaylightTransitionEnd=[System.TimeZoneInfo+TransitionTime], DaylightTransitionStart=[System.TimeZoneInfo+TransitionTime] }, TimeZoneInfo.AdjustmentRule { DateEnd=[9999/12/31 0:00:00], DateStart=[2007/01/01 0:00:00], DaylightDelta=[01:00:00], DaylightTransitionEnd=[System.TimeZoneInfo+TransitionTime], DaylightTransitionStart=[System.TimeZoneInfo+TransitionTime] } }
```

もちろん、タイムゾーンに夏時間規則があると返す。
`GetAdjustmentRule()`が返す配列の要素がふたつあるのは、サマータイムの扱いが2007年を区切りに変化しているからだ。
https://ja.wikipedia.org/wiki/%E5%A4%AA%E5%B9%B3%E6%B4%8B%E5%A4%8F%E6%99%82%E9%96%93

> 2006年までは、4月の第1日曜日午前2時から10月の最終日曜日午前2時までの期間の適用であったが、2007年以降は、3月の第2日曜日午前2時から11月の第1日曜日午前2時までの期間の適用に変更された。 

2006年末までの調整ルールと2007年頭からの調整ルールとで、合計ふたつということになる。
初めてGASを使って簡単にスプレッドシートを改良したコード公開します！

# はじめに
某web広告代理店で新卒としてエンジニアで働いている者です。最近ビジネスサイドや先輩からだんだんと信頼を掴んできたのか、「*スプレッドシートで予定シートにURLを打ち込めば担当者シートから担当者を取得して予定シートに日付と担当者が自動入力されるようにしてほしい*」と依頼をいただきました。

# GASとは？
Google Apps Scriptの略で、JavaScriptベースで記述できるプログラミング言語です。Googleクラウド上で動くため、JSの書き方さえ分かれば、環境構築無しにエンジニアでなくても記述することができます。
このGASを使えば、スプレッドシートやドキュメント、GmailをはじめとするGoogleのアプリケーションの処理を自動化したり、連携することができます。

# スプレッドシート構成
###担当者シート

![担当者シート](https://cdn-ak.f.st-hatena.com/images/fotolife/t/teeeeeeemo/20180816/20180816113351.png)

IDとURLとそのサイトの担当者が記載されています。
URLはドメイン単位で割り振られています。

###予定シート
![予定シート](https://cdn-ak.f.st-hatena.com/images/fotolife/t/teeeeeeemo/20180816/20180816113257.png)

日付と案件名、URLと担当者が記載されています。
URLはドメイン以降も記述されており、ページごとにこのシートに記入します。
E列はURLをドメインまでで取得するためにarrayfomulaとsplitを使って/で分割しています。

# GASの処理
### GASを使う流れ
GASはスプレッドシートの`ツール`→`スクリプトエディタ`から記述することができます。

### コード

```javascript

function urlFix() {
  var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet(); //スプレッドシート取得
  var objSheet = objSpreadsheet.getSheetByName('予定'); //シート名を元にシート取得
  var objCell = objSheet.getActiveCell(); //現在カーソルのあるセルを取得
  var row = objCell.getRow(); //セルの行数を取得
  var http = objSheet.getRange(row, 5).getValue(); //httpに当たる部分の取得
  var url = objSheet.getRange(row, 6).getValue(); //ドメインの部分を取得
  url = http + "//" + url + "/"; //担当者シートのURLと同じ形に整形
  var person = getPerson(url); //そのURLを投げて担当者を返してもらう
  if (objCell.getColumn() == 3) {
    objSheet.getRange(row, 4).setValue(person); //担当者をセット
    var today = new Date();
    var y = today.getFullYear();
    var m = today.getMonth() + 1;
    var d = today.getDate();
    objSheet.getRange(row,1).setValue(y + '/' + m + '/' + d); //日付をセット
  }
}

function getPerson(url) {
  var objSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = objSpreadsheet.getSheetByName('担当者');
  var personValues = sheet.getRange('C:C').getValues(); //担当者を全て配列で取得
  var urlArrays = sheet.getRange(1, 2, sheet.getLastRow()).getValues(); //URLを全て配列で取得
  urlArrays = Array.prototype.concat.apply([], urlArrays); //二次元配列を一次元に変換
  var personArrays = Array.prototype.concat.apply([], personValues); 
  var row = urlArrays.indexOf(url); //渡ってきたURLと同様のものが何行目にあるかを取得
  return personArrays[row];　//同様の行にある担当者取得

}

```

* **urlFix**　urlを取得しgetPersonに渡す処理と返ってきた担当者、その日をスプレッドシートに挿入する処理
* **getPerson** 渡ってきたURLを元に担当者を取得し返す処理
* トリガーの設定で、スプレッドシートが編集時に`urlFix`が呼び出されるようにする。

# できた処理

かなり荒いです
![](http://160.16.231.167:8080/img/qiita.gif)

URLを入力した行に自動で日付と担当者が入ります。


# 難しかった点・感想
* はじめはどこがアクティブなセルだとか、トリガーの編集時などのタイミングがわかりにくかった。
* JSをしっかりと書いたことがなかったため、JSの勉強もしつつで進めたことにより理解に戸惑う点が多かった。
* JSを描くという経験、Google Apps Scriptの利用が初めてだったため、何か間違っている、こここうして方がもっといいよね等ございましたらぜひご指摘ください！

#　参考
[Google Apps Script完全入門](https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-GoogleAppsScript%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-GoogleApps-G-Suite%E3%81%AE%E6%9C%80%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%AC%E3%82%A4%E3%83%89/dp/4798053767)
＊JSの概念いついて半分くらいの量が割かれています。かなり初心者向けの本です。
Nginxのリバースプロキシでoriginから404や503が返却された時にRetryさせたいときの設定

とりあえず以下の設定をしておけばいいらしい。


```
upstream example.com {
  server backend1-example.com;
  server backend1-example.com;
  server backend1-example.com;
}
```
upstreamはNginxでLBを実現させるためのものだが、その仕様の一つとしてtimeoutしたときに次のサーバーに対してretryするという挙動をする。なので通常の使い方だとは異なるサーバーを指定するわけだが、originサーバーは1つでリトライ処理だけを取り込みたい場合は上記の設定のように同一サーバーを設定しておけばリトライの挙動が実現できる。

レスポンスが404や503などタイムアウト以外のケースでリトライさせたい場合はproxy_next_upstreamを指定する

詳しいことは大体この記事に書いてある。
https://blog.1q77.com/2017/06/retry-function-of-reverseproxy/


ただし上記の記事ではステータスコード404や403では動かないとあるので補足しておくと、error_pageを無効にしないとupstreamの設定が上書きされてしまうとかなんとか。
https://forum.nginx.org/read.php?2,268529,268544#msg-268544
Athenaのパーティションを一括作成して一括削除

```shell
#!/bin/sh

# ex.
# $ ./xx.sh create 2018-01-01 2018-12-31
# $ ./xx.sh delete 2018-01-01 2018-12-31

METHOD=$1
STARTDATE=$2
ENDDATE=$3
CURRENTDATE=$STARTDATE
REGION=us-east-1
INPUTS3BUCKET=s3://xxx
OUTPUTS3BUCKET=s3://xxx
DBTABLE=データベース名.テーブル名

while [ 1 ] ; do

  CURRENTYEAR=`date -j -f "%Y-%m-%d" "$CURRENTDATE" "+%Y"`
  CURRENTMONTH=`date -j -f "%Y-%m-%d" "$CURRENTDATE" "+%m"`
  CURRENTDAY=`date -j -f "%Y-%m-%d" "$CURRENTDATE" "+%d"`

  if [ $METHOD = "create" ] ; then
    COMMAND="ALTER TABLE $DBTABLE ADD PARTITION (year='$CURRENTYEAR',month='$CURRENTMONTH',day='$CURRENTDAY') location '$INPUTS3BUCKET/$CURRENTYEAR/$CURRENTMONTH/$CURRENTDAY/'"
  elif [ $METHOD = "delete" ] ; then
    COMMAND="ALTER TABLE $DBTABLE DROP PARTITION (year='$CURRENTYEAR',month='$CURRENTMONTH',day='$CURRENTDAY');"
  else
    echo please input create or delete.
    exit 0
  fi

  aws --region $REGION athena start-query-execution --query-string "$COMMAND" --result-configuration OutputLocation=$OUTPUTS3BUCKET

  if [ $CURRENTDATE = $ENDDATE ] ; then
    break
  fi

  CURRENTDATE=`date -v+1d -j -f "%Y-%m-%d" "$CURRENTDATE" "+%Y-%m-%d"`
done

```


参考にさせてもらいました。
https://qiita.com/ssossan/items/6a4320b9e40af9a132c3
【エラー解決】Angularでerror TS1005: ',' expected.のエラーの解決

#概要

最近は、JSのフレームワークを使ったりしてます。
今回はAngularについて、`error TS1005: ',' expected.` のエラーで解決したので、その方法について書きます。

以下の画像のように、ターミナルでサーバーを起動しようと

<img width="577" alt="スクリーンショット_2018-08-16_13_17_27.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/ae758b7b-e9f3-100e-5790-2833c131b50e.png">

```irb
$ npm start
```

入力すると、

```irb
ERROR in src/app/common/header/header.component.ts(6,3): error TS1005: ',' expected.
```

エラーが出てしまう。

これは、エラー内容にある通り、テキストエディタの中のファイル構造を示している。

上記のエラーで例えると、ファイル
`src`の中の
=>`app`の中の
=>`common`の中の
=>`header`の中の
=>`header.component.ts`
の中に3~6行目あたりの`,`（カンマ）のエラーを表している。

下の画像の5行目の最後にカンマの記載漏れがあるので、最後にカンマを追加するとエラーが消えた。

<img width="436" alt="header_component_ts_—___bwm-project_bwm-ng.png" src="https://qiita-image-store.s3.amazonaws.com/0/97880/18b1d438-44e7-e1c7-f3fe-7fc6ab13f0bc.png">
SAS Viyaで簡易的なデータ集計を行う

SAS Viyaですでに取り込んだ、既存のテーブルを開く場合は次のように実行します。

```python
table = sess.CASTable('table_name')
```

SAS Viyaに取り込んだデータを見るには、下記のように行います。

```python
table.head()
```

テーブルでデータが表示されます。

b_tgt | cat_input1 | cat_input2 | cnt_tgt | demog_age | demog_ho | demog_pr | int_tgt | r_demog_homeval | r_demog_inc | ... | rfm6 | rfm7 | rfm8 | rfm9 | rfm10 | rfm11 | rfm12 | demog_genf | demog_genm | account
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1.0 | X | A | NaN | NaN | 0.0 | 24.0 | 7000.0 | 57600.0 | 52106.0 | ... | 22.0 | 4.0 | 6.0 | 5.0 | 20.0 | 9.0 | 92.0 | 0.0 | 1.0 | 100000001
1 | 1.0 | X | A | 2.0 | NaN | 0.0 | 24.0 | 7000.0 | 57587.0 | 52106.0 | ... | 22.0 | 4.0 | 6.0 | 5.0 | 20.0 | 9.0 | 92.0 | 0.0 | 1.0 | 100000002
2 | 1.0 | X | A | 2.0 | NaN | 0.0 | 0.0 | 15000.0 | 44167.0 | 42422.0 | ... | 16.0 | 3.0 | 8.0 | 16.0 | 27.0 | 11.0 | 91.0 | 0.0 | 1.0 | 100000003
3 | 0.0 | X | A | 0.0 | 68.0 | 0.0 | 32.0 | NaN | 90587.0 | 59785.0 | ... | 21.0 | 2.0 | 7.0 | 15.0 | 19.0 | 9.0 | 123.0 | 1.0 | 0.0 | 100000004
4 | 0.0 | X | A | 0.0 | NaN | 0.0 | 0.0 | NaN | 100313.0 | NaN | ... | 38.0 | 5.0 | 19.0 | 24.0 | 13.0 | 6.0 | 128.0 | 1.0 | 0.0 | 100000005
デフォルトで10件のデータが返ってきます。件数を増やす場合は数字を指定します。

```python
table.head(2)
```

表示するカラムを絞る場合は columns パラメータを指定します。

```python
table.head(columns=["b_tgt", "demog_age"])
```

b_tgt | demog_age
|---|---|---|
0 | 1.0 | NaN
1 | 1.0 | NaN
2 | 1.0 | NaN
3 | 0.0 | 68.0
4 | 0.0 | NaN

値の集計を行うのは sum を使います。全カラムが対象になります。

```py
table.sum()
```

数字以外のカラムを省く場合は numeric_only=True とします。

```py
table.sum(numeric_only=True)
b_tgt              2.115090e+05
cnt_tgt            3.304730e+05
demog_age          4.657248e+07
demog_ho           5.832970e+05
```

最大値を知りたい場合は max を使います。同じように最小値は min で取れます。

```py
table.max(numeric_only=True)

b_tgt                   1.00
cnt_tgt                 6.00
demog_age              89.00
demog_ho                1.00
```

----

すべてのコードは [sassoftware/python-swat](https://github.com/sassoftware/python-swat/) で、APIは [API Reference — SWAT 1.4.0 documentation](https://sassoftware.github.io/python-swat/api.html) で確認できます。
TypeScriptのコンパイル時に『error TS2304: Cannot find name 'Map'.』が出た時の対応


# TypeScriptコンパイル時にエラー

TypeScriptのコンパイル時、モジュールにbluebird(request-promiseなどの依存パッケージとしても使われている)を使っている場合、Mapが見つからないエラーとして、

```bash
$ tsc -p ./ts --outDir ./js

node_modules/@types/bluebird/index.d.ts:477:33 - error TS2304: Cannot find name 'Map'.

477   props<K, V>(this: PromiseLike<Map<K, Resolvable<V>>>): Bluebird<Map<K, V>>;
```
のようなエラーが出ることがあります。

# 対処法

tsconfig.jsonの"lib"の項目に、es6を追加してください。

```追加前
{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",      /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    // "lib": [],         /* Specify library files to be included in the compilation. */
    // "allowJs": true,   /* Allow javascript files to be compiled. */
```

```追加後
    /* Basic Options */
    "target": "es5",      /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
    "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    // "lib": ["es6"],         /* Specify library files to be included in the compilation. */
    // "allowJs": true,   /* Allow javascript files to be compiled. */
```

コンパイル時の参照ライブラリとしてES6がつかわれ、Mapのビルドが通るようになります。

## 参考

- https://stackoverflow.com/questions/39416691/webpack-ts2304-cannot-find-name-map-set-promise
- https://github.com/ajafff/tsutils/issues/13
提供された秘密鍵とPuTTYでSSHアクセスする

# 提供された秘密鍵とPuTTYでSSHアクセスする
## 目標、目的、目次
* SSH秘密鍵をPuTTY形式に変換する
* SSH秘密鍵を使ってPuTTYからログインを行う

## 実施

### SSH秘密鍵をPuTTY形式に変換
PuTTYgenを起動し、SSH秘密鍵をLoadする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/0ac6d2b3-9e6d-41d9-ee61-340cac4fa168.png)

この時、SSH鍵を選択するためにファイル形式を全表示する「All Files(*.*)」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/9ff741d6-c958-d402-24d1-fdcd5504fae9.png)

SSH鍵を選択し、開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/3f24c34f-beaa-38e1-2dda-5de0b5bdac4e.png)

SSH秘密鍵展開パスワードが設定されている場合訊かれるため
設定されているパスワードを入力し、OK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/b81531c9-ce1c-c765-aec6-b1e0e7eb0e84.png)

読み込めたら「読み込めたからPuTTY形式で保存するには～」というダイアログが出ます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/5ad87d56-8002-10e0-838a-7ad0e2eb35e8.png)

そのまま「Save private key」を選択し、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/a82a9143-64f0-a8fb-1ca7-8d2a52d62ba8.png)

適当に保存します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/99506a57-6296-b041-18c0-0858702f6b43.png)

この時PuTTY鍵展開PassはKey passphraseに入っておりSSH展開Passと同じ物が入っています。

### PuTTYによるSSH接続

PuTTYを起動します。

任意のサーバーIP：ポートを入力し
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/66fa1747-c11f-c8b0-e5c0-a5bec5638774.png)

CategoryからConnection→SSH→Authを選択し、
Browseを開き先ほど作ったppkファイルを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/f7bd262a-890f-2156-b6bb-53b7c11c198e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/bc49f373-d637-9b5e-d49f-b161bd71336d.png)

Openで接続します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/71ba2a6e-8020-ecbd-949d-2494efe2c7c1.png)

login as:アカウント名
Passphrase for key "～～":PuTTY形式展開Pass
を入力し、ログインできます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/150940/a0a5a0b7-14bf-97fd-4772-b2be56ecee46.png)
Vim—H J K L のキーストロークを絵で覚える ( 左下上右に移動 )


VIMを開いてHJKLキーを触りながら矢印をイメージすると、ちょっと感覚がつかめた気がした。

![image](https://user-images.githubusercontent.com/13635059/44184778-8c1b0400-a14b-11e8-8e8a-813694fb37f2.png)

(普段は方向キー派の自分)

## TRY

ホワイトボードやノートに書いて脳に刷り込んでみるのはいかがだろう。

![image](https://user-images.githubusercontent.com/13635059/44187981-c7233480-a157-11e8-97b1-4b0b39004f51.png)


## あわせて読みたい？

- [Vim — ggとG のキーストロークを絵で覚える ( G は重力のG ) - Qiita](https://qiita.com/YumaInaura/items/19491c052b8fdc62e199)

## Links

- [Remember VIM "H J K L" key binds ( key strokes ) with arrows image](https://gist.github.com/YumaInaura/10bf27e6d461e9d82081b980331c6a3f)
- [Medium—imported](https://medium.com/supersonic-generation/remember-vim-hjkl-key-strokes-with-arrows-image-2a3006a9aafb)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
FileMaker// iPadでキーボードの表示を抑制する

###お盆なのに仕事してます。貧乏暇なし
---
##FileMakerのiPad利用でちょっと気になったこと

FileMakerはiPad/iPhoneデバイスでの利用にも適していますが、日付や時刻フィールドを選択したときに日付・時刻設定用のポップアップと同時にタッチキーボードが起動してしまいます

さて、これをどうしようかと思って試行錯誤した結果、こんな感じになりました
![image.png](https://qiita-image-store.s3.amazonaws.com/0/181254/e13edf1f-1965-7ab5-ba98-a49127fc9fce.png)
OnObjectEnter でフィールドに入った時点でキーボードの起動をオフにする
OnObjectEnterにはスクリプト引数で1を入れています
スクリプトは以下。
1.デバイスで判定してます。3以上＝モバイルと判断してIfを実行
2.スクリプト引数が1ならタッチキーボードの有効化を[オフ]
![fm0816.png](https://qiita-image-store.s3.amazonaws.com/0/181254/f04584d6-e6c5-8f21-25b7-6872ee18bb0f.png)
同じスクリプトをOnObjectExitにも設定していますが、こちらにはスクリプト引数を持っていないため、タッチキーボードの有効化が[オン]になるという仕組み
よくあるパターンだと思うので、もう少しスムーズかつ美しく記述できないかな

###逆に日付や時刻フィールドに入ったときに、ポップアップの設定ウインドウが出ないようにすることはできるんだろうか？
---
###リファレンス
・[タッチキーボードの有効化](https://fmhelp.filemaker.com/help/17/fmp/ja/index.html#page/FMP_Help/enable-touch-keyboard.html)
・[OnObjectEnter](https://fmhelp.filemaker.com/help/17/fmp/ja/index.html#page/FMP_Help%2Fonobjectenter.html)
・[OnObjectExit](https://fmhelp.filemaker.com/help/17/fmp/ja/index.html#page/FMP_Help%2Fonobjectexit.html)
OculusGoのAvatarで口を動かす

# OculusGoのAvatarで口を動かす
もしかしたらハマる人少ないかもしれないけど、盛大にハマったのでやり方をまとめます。

## 1. ドキュメント情報を確認
https://developer.oculus.com/documentation/avatarsdk/latest/concepts/avatars-gsg-unity-mobile/#avatars-sdk-unity-mouth_movement
Oculusの公式で、口を動かすやり方は上記に書いてあります。

なお、LipSyncというサンプルがOculusIntegrationの中にあり、そっちでは音素に合わせて口の形を変えてますが、現状のOculusのAvatarではその機能に対応していない様子。
口の大きさを音圧で変える方法のみ対応しています。

・・・が、ここに書いてあるように、 **`OvrAvatar.VoiceAmplitude`を 0-1の範囲で設定しても、それだけでは口は動きません。**

公式にはここくらいしか書いてないのに・・・！

## 2. サンプルソースをあさる
`OvrAvatar.VoiceAmplitude`を参照してるサンプルコードを探してみたところ、 `Assets/Oculus/Avatar/Samples/SocialStarter/Assets/Scripts/SocialPlatformManager.cs`にて参照されていることを確認。（階層が深い・・・見つけづらい・・・）

このクラスの、Update()関数内ではドキュメント以上のことをやっているようには見えないためここで詰まる。

ぐぐぐ・・・

## 3. OvrAvatarのソースを見る
そもそも`OvrAvatar.VoiceAmplitude`は内部でどのように動作してるのか確認してみました。

`OvrAvatar.UpdateVoiceBehavior()`にて、`VoiceAmplitude`を係数として口の大きさを決めてるっぽいソースコードを発見。
この関数の一番上がこうなってました。

```
    private void UpdateVoiceBehavior()
    {
        if (!EnableMouthVertexAnimation)
        {
            return;
        }
```

・・・これだ！

## 4. 解決
結論から言えば、 **`OvrAvatar.EnableMouthVertexAnimation`が `true` になってないとAvatarの口は動きません。**
改めて `SocialPlatformManager.cs`を確認し直したところ、確かにremoteAvatarとlocalAvatar両方で`EnableMouthVertexAnimation = true`の処理を入れてました。

公式情報がちょっと足りなかったのですね。Oculusはだいぶ情報も出てきていますが、まだまだ情報が足りないところも多いです。
口は動かせてもAvatarのLipSyncはまだ対応してないとか、初めはわからなかったですし・・・（ドキュメント読み込み不足）
・・・っていうかLipSync対応してないですよね？ もうちょっと資料探したらやり方見つかるとかないですよね？


まあとにかく、同じところでハマる人が居たら、一助になれば幸いです〜
FirebaseからPush通知

#全体の流れ
1. Firebaseでプロジェクト作成
2. アプリにFCMプラグインの導入
3. アプリソース修正
4. Firebaseからメッセージ送信
5. アプリでメッセージ受信

#Firebaseでの作業
##Firebaseでプロジェクト作成
###「新規プロジェクト作成」からプロジェクト作成
![スクリーンショット 2017-05-02 17.04.41.png](https://qiita-image-store.s3.amazonaws.com/0/175762/f3f286a5-0535-6ae9-adbe-db353749dc50.png)

###プロジェクト名、国/地域を指定
![スクリーンショット 2017-05-02 17.05.39.png](https://qiita-image-store.s3.amazonaws.com/0/175762/691c3a3c-e78d-b000-5e40-96d11b1c069e.png)

#アプリの登録
###「AndroidアプリにFirebaseを追加」を選択
![スクリーンショット 2017-05-02 17.06.11.png](https://qiita-image-store.s3.amazonaws.com/0/175762/c26c6c23-0526-9df5-6f69-52179b8e5fda.png)

###「Android パッケージ名」を指定
![スクリーンショット 2017-05-02 17.06.29.png](https://qiita-image-store.s3.amazonaws.com/0/175762/2a76ada6-8fac-8846-9661-8e3bf64d27aa.png)

###google-services.jsonを取得
![スクリーンショット 2017-05-02 17.12.52.png](https://qiita-image-store.s3.amazonaws.com/0/175762/f262f989-81b7-9141-a1a7-1e4a824488a7.png)

#アプリ側の作業
##FCMプラグイン導入
基本的にはこちらに書いてある通り
https://github.com/fechanique/cordova-plugin-fcm

```
$ cordova plugin add cordova-plugin-fcm
```

##index.jsの修正

```
receivedEvent: function (id) {
  var parentElement = document.getElementById(id);
  var listeningElement = parentElement.querySelector('.listening');
  var receivedElement = parentElement.querySelector('.received');

  listeningElement.setAttribute('style', 'display:none;');
  receivedElement.setAttribute('style', 'display:block;');

  /* cordova-plugin-fcmの利用 */
  // 登録ID 取得
  FCMPlugin.getToken(function (token) {
    console.log(token);
  });

  // プッシュ通知受信
  FCMPlugin.onNotification(
    function (data) {
      console.log(data);
      if (data.wasTapped) {
        //Notification was received on device tray and tapped by the user.
        alert(JSON.stringify(data));
      } else {
        //Notification was received in foreground. Maybe the user needs to be notified.
        alert(JSON.stringify(data));
      }
    },
    function (data) {
      alert("success");
    },
    function (data) {
      alert("error");
    });
}
```

##google-services.jsonを配置
cordova プロジェクトフォルダ直下（wwwと同階層）に配置する

##登録ID取得
アプリを実行すると、「FCMPlugin.getToken」で登録IDが取得できる

#メッセージ作成、送信
Firebaseからメッセージを送信する
[プロジェクト選択]->[Notification]->[新しいメッセージ]
![スクリーンショット 2017-05-02 17.30.29.png](https://qiita-image-store.s3.amazonaws.com/0/175762/1fc7fd24-b1fb-8156-e455-ff1b98514ac1.png)

単一の端末に送信してみる
![スクリーンショット 2017-05-02 17.37.15.png](https://qiita-image-store.s3.amazonaws.com/0/175762/2d06f891-9f0e-d1cf-d1e6-a70fa2c2f4e3.png)

#端末でメッセージの受信
##アプリ起動時に受信した場合
「カスタムデータ」で指定した値が取得できた
![スクリーンショット 2017-05-02 17.53.25.png](https://qiita-image-store.s3.amazonaws.com/0/175762/f164e82e-0820-0f16-1c45-9efd8ad9407c.png)


##アプリ未起動時に受信した場合
「メッセージ文」「タイトル」で指定した値が表示された
![スクリーンショット 2017-05-02 17.53.56.png](https://qiita-image-store.s3.amazonaws.com/0/175762/85dc73ac-401f-9104-b3d2-d9cdbb7e766b.png)
Bundle exec rails generate rspec:install を実行しても動かなかった時の対処法

 Rails5にrspecを導入しようと、bundle installした後に、下記コマンドを打ち込んだところターミナルが止まってしまった。

```terminal
$ bundle exec rails generate rspec:install
```
ctrl + c で強制終了したところspring関連のところで止まっていたっぽい

```terminal
    16: from bin/rails:3:in `<main>'
	15: from bin/rails:3:in `load'
	14: from /Users/ユーザ名/ワークディレクトリ名/アプリケーション名/rails/bin/spring:15:in `<top (required)>'
	13: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:70:in `require'
	12: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:70:in `require'
	11: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `<top (required)>'
	10: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/binstub.rb:31:in `load'
	 9: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/bin/spring:49:in `<top (required)>'
	 8: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client.rb:30:in `run'
	 7: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
	 6: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/rails.rb:24:in `call'
	 5: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/command.rb:7:in `call'
	 4: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/run.rb:35:in `call'
	 3: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/run.rb:42:in `warm_run'
	 2: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/run.rb:62:in `run'
	 1: from /Users/ユーザ名//.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/spring-2.0.2/lib/spring/client/run.rb:117:in `verify_server_version'
```
とりあえずspringを停止してみたところうまくいった。
springの停止コマンド

```terminal
$ bin/spring stop 
Spring stopped.
```
再度rspecのコマンドを実行

```terminal
$ bundle exec rails generate rspec:install
Running via Spring preloader in process 60241
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

無事ファイルが作られた。
springのstatusを確認したら自動的にspringも起動されていた。

```terminal
$ bin/spring status                                                                                                               606ms  木  8/16 12:15:07 2018
Spring is running:

60196 spring server | rails | started 13 mins ago   
60230 spring app    | rails | started 13 mins ago | development mode  
```
端末でのデバッグ

Webアプリ開発時の実機デバッグ方法のメモ

#Android
・PCと端末を接続
・chrome 起動
・新しいタブを起動し、「chrome://inspect/#devices」にアクセス
・「inspect」をクリック
・DeveloperToolsが起動する

#iOS
・PCと端末を接続
・Safafiを起動
・[開発]->[接続端末名]->[ページ]を選択
・Webインスペクタが起動する