OmniAICreator/Qiita-1.07M huggingface dataset:
DNN_前編 1 (要点)

#Section1：入力層～中間層
入力層の各値（入力値）に重みWを掛けて、バイアスbを足した値が、総和uとして中間層の第1層目の各ノードに渡される。
渡された総和uは、活性化関数fを通して、zが吐き出され（z=f(x)）、この値が、ノードの出力値となり、次の層のノードに入力値として渡される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/64f817d5-2edb-5379-2c98-64ef696c5087.png)


#Section2：活性化関数
中間層の活性化関数は、
ReLU、シグモイド（ロジスティック）関数、ステップ関数などがある。
ステップ関数は、0または1しか表現出来ないため、0～1間の数値を表現出来ず線形分離可能なものしか学習出来ない。
シグモイド関数は、ステップ関数に比べて改善はしたが、ものすごく小さな入力値の場合、出力は限りなく0に近い正値になるため、勾配消失問題を引き起こす事がある。
ReLUは、今最も使われている活性化関数（万能という訳ではない）。

出力層の活性化関数は、
ソフトマックス関数、恒等写像、シグモイド（ロジスティック）関数などがある。


活性化関数によって、各ノードの出力は、弱く伝播したり、強く伝播したりする（強い方が、重要な情報）。


#Section3：出力層
出力層の役割は、出力された値を人間が見て、何らかの情報が得られるものになっている（中間層までの出力値は、人間が見ても、どう評価すればいいのか理解出来ない）。
例えば、分類の場合は、各クラスの確率が出力値になっていたりする。

###3-1 誤差関数
正解値と出力値との誤差を評価する関数。
この誤差を小さくしていく事が学習の目標。
回帰問題の場合は、二乗誤差
分類問題の場合は、交差エントロピーなどが使われる。


###3-2　出力層の活性化関数
Section2でも触れたように、中間層と出力層の活性化関数は異なる。
出力層では、恒等写像、シグモイド関数、ソフトマックス関数などが使われる。

中間層では、閾値の前後で、信号の強弱を調整しているのに対して、
出力層では、信号の大きさ（比率）はそのまま変換する。

分類問題では、出力層の出力は0～1の範囲の値で、全ての分類の出力値を合計すると1になるようにする必要がある（確率なので、合計すると100%にしないといけない）。


|  | 回帰 | 二値分類 | 多クラス分類 |
|:-----------|------------:|:------------:|:------------:|
| **活性化関数**| 恒等写像 | シグモイド関数 | ソフトマックス関数 |
| **誤差関数**| 二乗誤差 | 交差エントロピー | 交差エントロピー |


#Section4：勾配降下法

そもそも深層学習の目的として、学習と通して重みWを調整して、正解との誤差を最小にするネットワークを作成する事になる。
そこで勾配降下法を利用して、重みWを最適化していく事になる。

勾配降下法は、下記の式で定義される：
$w^{(t+1)} = w^{(t)} - \varepsilon \mathrm{\nabla} E$, &nbsp;&nbsp;&nbsp; $\mathrm{\nabla} E= \dfrac{\partial E}{\partial w} = [\dfrac{\partial E}{\partial w_1},...,\dfrac{\partial E}{\partial w_M}]$

つまり勾配の下がる方向に対して、学習率εを掛けた値を更新する事になる。
εが大きすぎると、更新量が大きすぎて、最小値にいつまでもたどり着けずに発散してしまう。
εが小さすぎると、更新値が小さすぎて、最小値にたどり着くまでに時間が時間がかかる。

また学習率が小さすぎる場合は、大域的極小解までたどり着けず、途中の小さなくぼみで学習が収束してしまう事がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435761/913900b5-ffce-49ce-c2a5-69aa0e96da07.png)

#####確率的勾配降下法（SGD）：
勾配を計算して、学習率を掛けて減算するというところは、勾配降下法と同じ。
違いは、勾配降下法では、全サンプルに対して、パラメータの更新を行っていたのに対して、SGDでは、ランダムに抽出したサンプルデータに対して、パラメータの更新を行う。

| 確率的勾配降下法 | 勾配降下法 |
|:-----------|------------:|
| ランダムに抽出したサンプルの誤差 | 全サンプルの平均誤差 |


#####SGDのメリット：
・データが冗長な場合に、計算効率が向上し、学習が早く実行出来る
・望まない局所極小解に収束するリスクを減らせる（但し、必ずしもリスクはゼロではない）
・オンライン学習が出来る
・パラメータの更新が小刻みに行われるので、学習の途中経過を確認する事が出来る


#####ミニバッチ勾配降下法：
勾配を計算して、学習率を掛けて減算するというところは、勾配降下法やSGDと同じ。
イメージとしては、勾配降下法とSGDの中間的な処理。
全サンプルを一度に学習するのではなく、サンプルをいくつかの集合（ミニバッチ）に分けて、その集合ごとに学習をしていく。

| ミニバッチ勾配降下法 | 確率的勾配降下法 |勾配降下法 |
|:-----------|------------:|:------------:|
| ランダムに分割したデータの集合(ミニバッチ)Dtに属するサンプルの平均誤差 | ランダムに抽出したサンプルの誤差 | 全サンプルの平均誤差 |

#####ミニバッチ勾配降下法のメリット：
・確率的勾配降下法のメリットを損なわず、計算機の並列計算資源を有効利用出来る。


#Section5：誤差逆伝播法
誤差逆伝播法（back propagation）とは、算出された誤差を、出力層側から入力層側に向かって、順番に微分して、前の層→前の層への微分の計算を連鎖律を使って伝播させていく方法。
最小限の計算で、各パラメータの微分値を解析的に計算する方法。
発生した誤差に対して、前層での出力が強いノードが大きく更新される事になる。

訓練データは、入力層→出力層に向かって、計算されて行くのに対して（順伝播）、逆方向に計算が進む事で、逆伝播という言葉で呼ばれる。
Laravel コマンド(Command) 進み具合を見るプログレスバーを使って、かっこよくしてみた

##行うこと
コマンド実行時にかっこいいプログレスバーを表示したい。

まず、テスト用にCommand用のファイルを作成する。

```:コマンド
php artisan make command ProgressTestCommand
```

##基本形

あまり、カスタマイズせずにプログレスバーを表示してみます。

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ProgressTestCommand extends Command
{
    protected $signature = 'test-progress';

    protected $description = '進行状況を可視化するTest';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $loopCount = 1000;
        $progressBar = $this->output->createProgressBar($loopCount);

        //開始
        $progressBar->start();

        for($i = 0 ; $i < $loopCount ; $i++) {
            //プログレスバーを進める
            $progressBar->advance();
        }

        //終了
        $progressBar->finish();
    }
}

```

実行してみます。

```:コマンド
root@34112e76c30c:/var/www# php artisan test-progress
 1000/1000 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
```

プログレスバーがでています。

##カスタムしていく

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ProgressTestCommand extends Command
{
    protected $signature = 'test-progress';

    protected $description = '進行状況を可視化するTest';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $loopCount = 100000;
        $progressBar = $this->output->createProgressBar($loopCount);

        // プログレスバーのフォーマット
        $progressBar->setFormat(' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%');

        // 処理前の表示
        $progressBar->setEmptyBarCharacter('|');

        // 処理後の表示
        $progressBar->setBarCharacter('-');

        // 処理中の表示
        $progressBar->setProgressCharacter(">");
        
        //開始
        $progressBar->start();

        for($i = 0 ; $i < $loopCount ; $i++) {
            //プログレスバーを進める
            $progressBar->advance();
        }

        //終了
        $progressBar->finish();
    }
}

```

```
root@34112e76c30c:/var/www# php artisan test-progress
  20471/100000 [----->||||||||||||||||||||||]  20% 6 secs/29 secs 12.0 MiB
```

ちょっとカッコよくなった感

##まとめ
ループ処理なんかを持ったコマンドを複数実行する場合は、可視化することでよりそれっぽく見えるなーと思った。
ただ、プログレスバー用の処理はなるべくどこかにまとめておきたいと思った。

##参考にさせていただいた記事
https://blog.capilano-fw.com/?p=3402
https://programmer-jobs.blogspot.com/2017/02/laravel-5-4-artisan-console-progress-bars.html
Firebase設定 メモ

ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#RailsからFirebase Storageにアップロードする時のFirebaseの設定
ここから鍵ファイルをダウンロードする!
![スクリーンショット 2019-06-18 20.01.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/a9ae002d-a045-974f-9b3f-71b7932968b8.png)

#環境変数の設定
こんな感じで環境変数を設定

```jsx
export GCS_BUCKET= 自分の設定した内容
export GOOGLE_CLOUD_PROJECT=opos-dev
export GOOGLE_CLOUD_KEYFILE_JSON="$(cat 自分の.json)"
```

#shrineの設定

こんな感じでshrineの設定をすればオケ

```jsx
require "shrine"

if Rails.env.test?
  require "shrine/storage/file_system"
  Shrine.storages = {
    cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"),
    store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store")}
else
  require "shrine/storage/google_cloud_storage"
  bucket = ENV["GCS_BUCKET"]
  Shrine.storages = {
    cache: Shrine::Storage::GoogleCloudStorage.new(bucket: bucket, prefix: "images/cache"),
    store: Shrine::Storage::GoogleCloudStorage.new(bucket: bucket, prefix: "images", default_acl: "publicRead")}
end

Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data
Shrine.plugin :restore_cached_data
```
Gitのセットアップをする（強い SSH key を使う、 GPG key を使った署名付きコミットを行う）

今まで RSA で適当に鍵を作ったりしていたが、もう少しセキュリティ面を考え、真面目に SSH key を作ったり、署名付きコミットをしてみようと思った。

# 強い SSH key を作る

RSA の 1024bit はよくないらしく、 2048bit も時間の問題で使えなくなりそうなので、ここは ECDSA や Ed25519 を使うことにしてみる。

各種Keyの作り方は下記が参考になった。

[2017年版 SSH公開鍵認証で使用する秘密鍵ペアの作り方 - Qiita](https://qiita.com/wnoguchi/items/a72a042bb8159c35d056)

圧倒的に意識が高いらしい、 ed25519 にして鍵を作ってみる。

```sh
ssh-keygen -t ed25519
```

なお、[電子署名EdDSA(ed25519)の数的構造 - Qiita](https://qiita.com/angel_p_57/items/a1dc4e9c0b18a23c5242) 等で理論を軽くおってみたが、難しいことはよくわからなかった。

ただ、古いサーバーに入ることに備えて RSA の鍵も作っておく。長さは 4096bit にして少しでも長くしておく。（自分が使う範囲だとこれくらいの長さでも大丈夫だが、もっと古いサーバーだとそうもいかなかったりするのかな？）

```sh
ssh-keygen -t rsa -b 4096
```

# GPG鍵を使った署名付きコミットをする

GitHub で SSH key の他に PGP key が登録できるのだが、これが今までなぜ存在するのか実は知らなかった。

公式の記事を読んで機能を知った。[About commit signature verification - GitHub Help](https://help.github.com/en/articles/about-commit-signature-verification)

導入についてはこの記事が参考になった。

[macOS Mojave で GnuPG の鍵を SSH の鍵として使う - Qiita](https://qiita.com/sira/items/d61caf237fed95090455)

なお、導入にあたっては `gpg` コマンドが動く状態であることが重要っぽい。そのためのパッケージがどうこうみたいな問題はあるようだが、あまり躓くことなく導入できてしまったので何が最小構成なのかわかっていない。（一応、 `gpg` コマンド動く状態で、 Ubuntu で少し試してみたが、同じ手順で導入できている）

ただしバージョンはなるべく新しいほうが良いようだ。こちらの [git(GitHub)でGPGを使った署名をおこなう - Qiita](https://qiita.com/pontago/items/5867b6492e09c34084fe) 記事も参考にしたが、なるべく新しいほうがいいんだなあ… ということを知った。（ただこの記事は RSA で進めていたので、もう少しいい感じのやつないかなーで上の macOS Mojave でやる記事を見つけた）

最後に下記を打ち込んで、

```sh
gpg --list-keys --with-keygrip <あなたのemailアドレス>
```

pubの直後にある部分を `<keyのID>` としてやると、 GPG キーが Export される。

```sh
gpg --armor --export <keyのID>
```

これを GitHub の PGP Key に貼り付ければ登録完了。

登録後はこんな感じに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72473/5d2dfc62-819f-cc0d-444b-e70c1ef7959f.png)


# git commit を常に署名付きにする

```sh
git config --global commit.gpgsign true
```

で global な `.gitconfig` に設定を書き込んであげればOK。

push したら下記のように見えるはず。（しかし個人リポジトリだからといってコミットメッセージがひどい）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72473/0ceaecc9-9a59-d12f-4ffd-b877bf488ca4.png)

緑色の `Verified` がついていればOK。

# まとめ

GPG key の存在とか、設定方法とか改めて提供されている機能を活用してみようと思うといろいろ学ばなければいけないことが多いなと感じた。

でもこれでこれは私のコミットです！！と堂々と言えるようになったのは良かったかな、と思う。バリバリ署名付きコミットをアピールするように進捗を出していきたい。
【備忘録】【javascript】ページの一番下までスクロールしたかどうかを判定する方法

## 対象がwindowの場合

```.javascript
// 参考: https://ja.javascript.info/size-and-scroll-window
// ブラウザ間の差異をカバーする
// ページ全体の高さを取得する
const scrollHeight = Math.max(
  document.body.scrollHeight, document.documentElement.scrollHeight,
  document.body.offsetHeight, document.documentElement.offsetHeight,
  document.body.clientHeight, document.documentElement.clientHeight
);

// 一番下までスクロールした時の数値を取得(window.innerHeight分(画面表示領域分)はスクロールをしないため引く)
const pageMostBottom = scrollHeight - window.innerHeight;

window.addEventListener('scroll', () => {
	const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

	// iosはバウンドするので、無難に `>=` にする
	if (scrollTop >= pageMostBottom) {
		console.log('一番下までスクロールしました');
	}
});
```

## 対象がelementだった場合
参考: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight

要素がスクロールの最後にある場合 `true`
そうでない場合に `false`

```.javascript
// ios系はバウンドするので <= としている
element.addEventListener('scroll', () => {
  element.scrollHeight  -  element.scrollTop <= element.clientHeight
});
```
LaradockをCentOS7に構築する手順

# 作業環境
| OS・ミドルウェア | バージョン                              |
|:------------|:-------------------------------------|
| CentOS      | CentOS Linux release 7.6.1810 (Core) |
| Virtual Box | 6.0.8 r130520 (Qt5.6.3)              |
| Vagrant     | 2.2.4                                |

# Laradockとは
LaravelをDockerで構築できるDockerイメージ。
※Laradock公式サイトは [こちら](https://laradock.io)

LaradockはNginx, Apache, PHP(任意バージョン), PostgreSQL, MySQLを自由に選択して簡単に立ち上げることができる。

# Laradock環境構築
Docker用のディレクトリを作成する
今回は/home/にprojectsというディレクトリを用意する。

```
$ mkdir /home/docker_projects
```

作成したディレクトリにLaraockをクローンする

```
$ cd /home/docker_projects
$ git clone https://github.com/laradock/laradock.git
```

projectsにlaradockというディレクトリが作られる。

```
$ ls -al
total 4
drwxr-xr-x.  3 root root   22 Jun 17 17:19 .
drwxr-xr-x.  4 root root   39 Jun 17 17:19 ..
drwxr-xr-x. 66 root root 4096 Jun 17 17:20 laradock
```

## Laradockの準備
laradock内に.envファイルを作成

```
$ cp ./laradock/env-example ./laradock/.env
```

## Laradockを起動
今回はnginx, mysql, php-fpm, workspaceを立ち上げる。

```
# Dockerイメージのビルド
$ cd /home/docker_projects/laradock
$ docker-compose up -d --build workspace nginx php-fpm mysql
```

※２回目以降は`--build`なしで実行できる。

### Docker状態の確認
```
$ docker-compose ps
```

### コンテナにログインする
※`--user=root`の`root`を変更すれば他のユーザでログインできる。

```
$ docker-compose exec --user=laradock workspace bash
```

# Laravelのインストール
下記のコマンドを実行してLaravelをインストールする
※ProjectNameの部分は任意のプロジェクト名にする
　また末尾に`"5.3.*"`のように記述するとlaravelのバージョンを指定できる

```
$ composer create-project laravel/laravel ProjectName
```

※コンテナ内(/var/www/)で作成したフォルダやファイルは、ホスト内のlaradockフォルダと同階層にもできている。
 場所を変更したい場合は`laradock/.env`の設定を変更する

```
# 必要な場合だけ
APP_CODE_PATH_HOST=任意のパス
```

## Laravelの初期設定
### 日本用の設定

設定ファイルを編集

```
$ vi ProjectName/config/app.php
```

```php
'timezone' => 'Asia/Tokyo',  #日本時間に設定
'local' => 'ja',             #日本語に設定
```

### ファイル権限の変更

```
$ cd ./ProjectName
$ chmod -R 777 storage
$ chmod -R 777 bootstrap/cache
```

## データベースの接続設定
設定ファイルを編集する

```
$ vi ProjectName/.env
```

```php
DB_CONNECTION=(mysql, pgsql, sqlite, sqlsrv)
DB_HOST=データベースに接続する為のIPなど
DB_DATABASE=データベース名
DB_USERNAME=ユーザ名
DB_PASSWORD=パスワード
```

# Laravelのトップページを表示する
まだコンテナの中にいる場合は下記のコマンドで抜ける

```
$ exit
```

### Nginxの設定を変更する

```
$ vi /home/docker_projects/laradock/nginx/sites/default.conf
```

ドキュメントルートの編集

```
# コンテナ内のパスで設定する
root /var/www/ProjectName/public;
```

dockerコンテナを再起動

```
# 停止
$ docker-compose stop

# 起動
$ docker-compose up -d workspace nginx php-fpm mysql
```

ブラウザにアクセスして下記の画面が表示されていれば完了！
<img width="822" alt="スクリーンショット 2019-06-30 19.49.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329349/57e68187-58bf-79dd-06db-9b902b69d16c.png">
Angular のテスト時間長い問題を解決する

# Angular のテスト長い問題を解決する
Angular のプロジェクトに参画して雰囲気で Angular を書き始めましたが、如何せんテストの量が多い。

Angular は `ng test` でテストを実行できますが、基本的に全てのテストを実行するので、アプリケーションが大きくなると一度のテストに時間がかかり、気軽にテストできなくてつらい問題が発生します（小さい単位でテストしたい...）

## (追記) custom-webpack でテスト対象を動的に変更する

こんな感じでテスト対象を環境変数で指定します。こっちの方が後々楽です。手っ取り早く試したいなら後述の「テストのエントリーポイントを追加する」の方が楽です。

```console
$ TEST_TARGET='./app/<module>' ng test
```

### 導入方法

custom-webpack と webpack をインストールします。 custom-webpack は Angular とバージョンを合わせないと動作しないです。

```console
$ npm install -D @angular-builders/custom-webpack
$ npm install -D webpack
```

環境変数を定義する `extra-webpack.config.js` を作成します。

```console
$ cd path/to/<angular-project>
$ touch extra-webpack.config.js
```

```ts
const webpack = require('webpack');

module.exports = (config) => {
  config.plugins.push(new webpack.DefinePlugin({ 'process.env.TEST_TARGET': JSON.stringify(process.env.TEST_TARGET || './') }));
  return config;
};
```

既存の `angular.json` を修正します。

```diff
        "test": {
-         "builder": "@angular-devkit/build-angular:karma",
+         "builder": "@angular-builders/custom-webpack:karma",
          "options": {
+           "customWebpackConfig": {
+             "path": "./extra-webpack.config.js"
+           },
```

`src/test.ts` の `require.context()` のパスに環境変数を指定します。

```diff
- const context = require.context('./', true, /\.spec\.ts$/);
+ const context = require.context(process.env.TEST_TARGET, true, /\.spec\.ts$/);
```

以上で完了です。

## テストのエントリーポイントを追加する
テストのエントリーポイントを追加して小さい単位、例えば Module 単位などでテストします。

`ng test` は（特に何も設定していなければ）テストのエントリーポイントである `src/test.ts` の内容を基にテストの対象を決定します。これを書き換えてもテスト対象を絞ることはできますが、毎度書き直すのは面倒です。

```ts:test.ts
...
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
...
```

`--main` オプションを使えば、実行時にエントリーポイントを指定できるので、必要な単位でエントリーポイントを用意します。

以下、 Module 単位でテストする場合の手順です。

### `test.ts` をコピーする

`src/test.ts` を Module のディレクトリにコピーします。

```console
$ cd path/to/<angular-project>
$ cp src/test.ts src/app/<module>
```

### 実行

`--main` オプションでテストのエントリーポイントを指定して実行します。（私が試した環境の場合 `--tsConfig` を指定しないのと `ts` のコンパイルに失敗したので同時に指定しています）。

```bash
$ cd path/to/<angular-project>
$ ng test --main=src/app/<module> --tsConfig=tsconfig.json
```

## まとめ

`--main` オプションを使えば、小さい単位でテストできて嬉しい。でも PR 投げる前には全部テストしよう。
シェルスクリプト+psqlでカレントスキーマを変更しつつSQLを実行する

#背景
シェルスクリプトで、スキーマを切り替えつつ、該当の全てのスキーマにSQLを実行する必要があったのでメモを残します。

#調査

```
select current_schema();
```
でカレントスキーマの情報が取得でき、(大抵の場合はpublic)

```
set search_path to $schema;
```
で目的のスキーマに変更ができました。

なのでこのコマンドを-cで実行しつつ、-fでSQLファイルを指定する組み合わせを行うとOKです。

```
psql -d ${DBNAME} -U ${USER} -c "set search_path to $schema;" -f ${sqlfile}
```

でカレントスキーマを切り替えて${sqlfile}を実行できます。


#script sample
ざっと書くと

``` 
schemas=`psql -d ${DBNAME} -t -c "select distinct table_schema from information_schema.tables where table_schema like '${schemaname}%' and table_schema not in('public','pg_catalog','information_schema')"`

for schema in $schemas
do
  for sql in `ls`
  do
    if [[ $sql == *".sql" ]]
    then
      #ファイル名は${tablename}.sqlの想定です
      table=`echo $sql | sed -e "s/.sql//"`
      echo "process > ${schema}.${table}"
      psql -U ${USER}-d ${DBNAME} -c "set search_path to $schema" -f $sql
    fi
  done
done
```

もちろんSQLファイルに"public."とかスキーマが書かれていると困るので

```
sed -i -e "s/public.//g" $sql
```
とかでスキーマ定義を無くす必要はあります。

#感想

スキーマ切り替え方法は上記のようにカレントスキーマを変更する方法の他に:SCHEMAなどの特定の文字列を対象のスキーマ名に置き換えつつ実行する手法もありますがどちらが一般的なんでしょうか。
個人的にはpsqlで-cと-fが同時に使えるのは意外でした。
ionicで現在地取得時に出るアラートのテキストを変更

## 背景
ionicを利用して作成したiosアプリにプラグインを利用してgoogleMAPを表示させています。

利用したプラグインは以下の2つです。

+ @ionic-native/google-maps
+ cordova-plugin-googlemaps


アプリではユーザーの現在地情報も利用しています。
情報取得時にはユーザー側にアラートで「現在地を利用して良いか？」という趣旨のテキスト（英語）が表示されていました。
ところが、appleの審査で「日本人読めないだろ！」という指摘を流暢な英語で受けたので直します。


## 解決
config.xml の `platform name="ios"` 内に下記を追加します。
xcodeからも同様に治せるはずです。

```xml:config.xml
<edit-config file="*-Info.plist" mode="merge" target="NSLocationWhenInUseUsageDescription">
    <string>お近くのお店を探す為に現在地を使用させて頂きます</string>
</edit-config>
```
https://github.com/ionic-team/ionic/issues/13535#issuecomment-380977046

というメモでした。
Oculus Questのセットアップやら

#概要
Oculus Questをさわる機会があったのでそのセットアップの手順を記載していきます。HTC VIVE以降手元にVR機器がなかったためVRの開発欲求が高まっています。

#環境
・Oculus Quest
・Windows10
・スマートフォン（Android端末）

#Oculus Quest開封
大人になっても開封の儀というのは楽しみなものですね。どの開発からやっていくかと思いを巡らせながらいざ開封！！

中身の確認

+ Oculus Quest本体
+ 左コントローラー
+ 右コントローラー
+ Type-C充電用ケーブル
+ 眼鏡用スペーサー
+ 説明書
+ ガイド
+ 単三電池２本
 
![IMG_0279_re.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/8e1e9212-1c9e-82a9-61e8-a31f83eebba7.jpeg)


####ケーブルがない！！！(充電ケーブルはノーカン)
これだけでもう感動してしまいました。それに物が少なくコンパクトな梱包で著者のテンションはHighです（笑）。

#セットアップ
Oculus Questのセットアップはスマートフォンで行います。
まずは、Oculusアプリ（iOS/Android）をダウンロードします。
今回は、Android版での設定の仕方を記載します。

###1．アカウント登録/ログイン
セットアップを行うためにはOculusのアカウント登録が必要で、Facebookアカウントでログインするか新規でOculusアカウントを作成するか選択します。

###2．使用するデバイスを選択
使用するデバイスを選択します。今回はOculus Questを選択。
※OculusアプリのバージョンによってはOculus Questが表示されない場合があります。

###3．Oculus Questとスマートフォンをペアリング
ペアリングを行うために、Oculus Questの電源を入れます。
Oculus Questの状態は電源ランプが白の時に起動状態、オレンジの時に充電中を表します。
Oculus Questをのぞき込み右下にある5桁の数字をスマートフォン側のアプリに入力します。

###4．コントローラーとペアリング
付属してある単三電池をコントローラーに入れます。
電池カバーが磁石式になっており、カバーを近づけると自動的に閉まるようになっているため、着脱が容易にできるようになっていました。
電源を入れると自動的にペアリングされます。

その後、Oculus Questが自動的にアップデートが走ります。スマートフォン側では、チュートリアルの動画が流れます。見ないと次以降の使い方で苦戦を強いられることになるためしっかりと見るようにしましょう。

###5．ルームスケールの設定
Oculus Questでコンテンツを体験できる部屋の範囲を設定します。ここで設定した範囲にいるときにだけコンテンツが流れるようになります。それ以外の範囲に出た場合は前方のカメラ映像がグレースケールで表示され、物や壁等にぶつからないような仕様になっています。（これが本当にすごい！！！）

こちらはOculus Questを装着したまま行うことができ、表示されるルームスケールの手順通りに進めれば簡単に設定することができるので割愛します。

著者はいくつかアプリ等を遊んでみましたが、このルームスケールが一番面白いと思っています（笑）

###6．開発者モードに変更
Oculus Questを使って開発しない方はこれ以降は見る必要はありません。
アプリ等を購入して、Oculus Questライフを満喫してください。

Oculus Questを使って開発したいよって方は、開発者モードに変更する必要があります。
開発者モードへの変更はスマートフォンから行います。

1．Oculusアプリを立ち上げ、下方向にあるタブの設定を開きます。
<img width="144" alt="Screenshot_20190619-193208_re.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/5f65d31f-e323-2ea4-eabe-cdde7bebc069.jpeg">
2．ペアリングしたOculus Questの名前があるので、名前をタップし「その他の設定」から「開発者モード」を開く。
<img width="144" alt="Screenshot_20190619-193321_re.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/d98fe15f-7a5a-90eb-05b7-b0e3a8c24418.jpeg"><img width="144" alt="Screenshot_20190619-193327_re.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/a5be72cb-d42f-0cfc-12a1-d7c4ab8b1a9e.jpeg">
3．右方向にあるスイッチをOnにする。（事前に開発者登録が必要です。登録されていない場合は自動でOculus Dashboardが開くので、団体名等を入力してください）

<img width="144" alt="Screenshot_20190619-193332_re.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440432/b84857f8-75cd-e3fc-cf03-5d97a372891c.jpeg">



以上で設定完了です。

比較的難しい作業はなく、インストールやアップデートの時間を省けば、5分から10分程度で設定できました。

次回はUnityでのOculus Quest用のビルド方法について記載していきます。

#参考
+ [0から始めるQuestビルド](https://qiita.com/HhotateA/items/d42f2d2522c1fdd227b9)
+ [Unityで作ったアプリをOculus Questで動かす](https://qiita.com/pira/items/1c935f30d5ba6c020333)
+ [数分で完了 Oculus Questの開封からセットアップまで詳細](https://www.moguravr.com/oculus-quest-setup/)
CentOS7.6にMySQL8.0をyumでインストールする

テスト用に新しい環境を作ってみたのでメモ :writing_hand_tone2:
環境はおなじみConoha VPSです :clap_tone2:

▼OS

```console
cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core) 
```

#CentOS7.6にMySQL8.0をyumでインストールする

##1.MySQL8.0のインストール
(参考)https://dev.mysql.com/doc/mysql-yum-repo-quick-guide/en/

###1-1.公式リポジトリを追加
最新は 「mysql80-community-release-el7-3.noarch.rpm」 のよう。
DL用のURLはサイトたどったら以下の通りでした :information_desk_person:
サクッといきます:ok_hand_tone2:

```console
$ sudo rpm -Uvh https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
```

###1-2.mysqlをインストール

```console
$ sudo yum install --enablerepo=mysql80-community mysql-community-server
```

###1-3.確認する

```console
$ mysqld --version
/usr/sbin/mysqld  Ver 8.0.16 for Linux on x86_64 (MySQL Community Server - GPL)
```
よーし :ok_woman:
あ、mariaDBもちゃんと置換されてるみたいだった:v_tone2:

▼ログ

```console
置換:
  mariadb-libs.x86_64 1:5.5.60-1.el7_5   
```

はい、楽勝でしたね :stuck_out_tongue_winking_eye:

あとはおまけです。
MySQL５．７の時とかと全く一緒 :dancer_tone3:
##２.おまけ
###2-1.自動起動の設定

```console
$ systemctl enable mysqld.service
```

###2-2.起動する
```console
$ systemctl start mysqld.service
```

###2-3.mysqlに入る

パスワードがログに出力されているらしいので、以下のコマンドで確認する。

```console
$ sudo grep 'temporary password' /var/log/mysqld.log
2019-06-19T12:46:39.848469Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: XXXXXXXXXXXX
```
XXXXXXXXXXXXの部分にパスワードが表示される。
このパスワードを使って入る。

```console
$ mysql -uroot -p
Enter password: XXXXXXXXXXXX
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.16

省略...
```

入れた :runner_tone1:

###2-4.SELECTしてみる

```console
$ mysql> select host, user from mysql.user;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
```

あちゃ :sweat_smile:
まずは新しいパスワードを設定する必要があるみたい。
パスワードの強度が低いと変更できないので、とりあえずマニュアル通りのパスを設定。

```console
$ mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!';
Query OK, 0 rows affected (0.00 sec)
```

でけた :ok_hand_tone2:

```console
$ mysql> select host, user from mysql.user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+
4 rows in set (0.00 sec)

```

よーし。
とりあえず使えたワッショイ :lifter:
Leetcode #387: First Unique Character in a String

```swift
func firstUniqChar(_ s: String) -> Int {
    var candidates = [Int]()
    var dict = [Character: Int]()
    let s = Array(s)
    for i in stride(from: 0, to: s.count, by: 1) {
        if let value = dict[s[i]] {
            if let index = candidates.firstIndex(of: value) {
                candidates.remove(at: index)
            }
        } else {
            dict[s[i]] = i
            candidates.append(i)
        }
    }
    return candidates.isEmpty ? -1 : candidates[0]
}
```
AsIs ToBe 思考で問題と課題を明確にする

![asis_tobe.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31223/fa4a6c43-8b8d-7ec8-9be2-ebe513a20d51.png)

**対象読者**

問題解決・課題設定の基本を身につけたい人

# 問題と課題の違い

AsIs ToBe を知る前に「問題」と「課題」が何かを理解する

## 問題は、現状と理想の間にギャップがある状態

例えば、A さんの通勤時間が 2 時間だとする。



* A さんの理想的な通勤時間が「1 時間以内」ならば、現在の通勤時間は **問題だ**
* なぜならば現状と理想の間に、**ギャップがある**からだ

一方で

* A さんの理想的な通勤時間が「3 時間以内」ならば、現在の通勤時間は **問題ではない**
* なぜならば現状と理想の間に、**ギャップがない**からだ



## 課題は、問題解決のために取り組むべきこと

「問題解決のために取り組むべきこと」が課題だ。

A さんの通勤時間に問題があるとして、考えられる課題は主に 5 パターンある

* (1) 会社近くに引越しをする
  * 引越資金を貯める必要がある
  * 引越し日程を決める
  * 総務に引越し日程を連絡する
* (2) 平日は会社近くのカプセルホテルで寝泊まりする
  * 会社近くにカプセルホテルがあるかを調べる
  * 支出オーバーにならないように費用計算をする
* (3) 自宅勤務できるように会社に願い出る
  * 上長に相談をする
  * 承認が下りた場合総務に申請をする
* (4) 自宅近くに支社設立を会社に願い出る
  * 上長・上役を巻き込んで相談する
* (5) 転職する
  * 通勤1時間以内の会社にあたりを見つけ、転職準備を始める
  * 上長に退職の相談をする

補足：

A さんにとって実現能可能かどうかは横に置いている

実現可能性の検討は、課題の洗い出しが終わった後にすべきことだ

# AsIs ToBe

AsIs ToBe を利用すれば、問題と課題を「流れに沿って」明確にできる。

## 全体図

![asis_tobe.001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31223/fa4a6c43-8b8d-7ec8-9be2-ebe513a20d51.png)

### 現状(AsIs) を洗い出す

**先ほどの通勤時間が問題になる場合を例にとろう**

今自分が置かれている状態を、考えられる・思い当たるだけ洗い出す。

* 起床は朝の 6 時 00 分 だ
* 6 時 40 分 の電車に乗らないと遅刻する
* 起床から出勤準備まで余裕がない
* 6 時 00 分より前に起きると体調に異常をきたす

## 理想(ToBe) の姿を描き出す

何の制約も受けない、理想のみを思い描く。

* 通勤時間は 1 時間以内である
* 毎日の起床は 7時半過ぎである
* 心身ともに余裕を持って出勤できる

## 問題が何なのかを言葉にする

現状と理想のギャップを言葉にする。言葉で表現できない問題は問題ではない。

* 長時間電車に揺られて職場に行くことが苦痛である
* 睡眠時間を十分確保できない
* 朝、精神的に余裕がないのは苦痛である

## 課題を洗い出す

「問題解決(ギャップを無くすこと)の為に取り組むべきこと」 が 課題だ。

* 主課題: 引越しをすること
  * 課題1: 引越資金を貯める
  * 課題2: 資金が貯まり次第、引越しの日程を決める
  * 課題3: 引越し日程決まり次第、総務に連絡をする

「課題2: 引越しの資金を貯める」の課題はさらに細分化できないだろうか。

「現状余力がある資金は X 円で、引越し資金 は相場からして Y 円必要。Z 円足りない」

という別の問題が見えてくるだろう。どういった課題を設定できるだろうか。

課題を細分化できたら、課題2の子課題として設定しよう。

# 留意点

## それは本当に課題か

### 現状を課題にしない

よく課題管理表で目にする「何々ができない」と記された「課題のようなもの」がある。

これは単なる「現状(AsIs)」だ。

そこには何の理想の姿も、問題も、課題もない。

## それは本当に問題か

### 現状と理想の間にギャップがなければ問題ではない

冒頭の通勤時間の例でも示した通り、理想と現実の間にギャップが存在していなければそれは問題ではない。

なので「自分は問題だと思った」が「他人は問題だと思わなかった」が起きるのは

他人が「現状 = 理想」としているからだ。

### 現状と問題を混同しない

「市場リリース版にバグを混入させない」が理想の姿だとする。

「バグを見つけた」は単なる現状。それは何が問題なのかが分からない。

ここでは、**現状が理想にどれだけ達していないか** をはっきりさせ、現状を問題に昇華させれば良い。

例えば、理想を「市場リリース版でバグが起きていないこと」としよう。

* 「バグを見つけた。これは市場リリース版で再現する」は問題だ
    * 理想に達していないから
* 「バグを見つけた。これは開発版でのみ再現する」は問題ではない
    * 理想に達している(市場リリース版にはバグが混入していない)からである

### 理想がなければ問題は出てこない

理想なきところに問題は現れない

まず自分が何を理想に描くことだ。キーワードは

* どうしたいか
* どうなりたいか
初心者がconohaでVPSを借りてnginxでphpページを公開するまで-初期セキュリティ編-

## セキュリティ対策を行う

###1:root以外のユーザーを追加する
rootユーザーのパスワードはkonohaサーバーのパスワードと同じなので
サーバー攻撃されてkonohaアカウントがバレるし
konoha側が攻撃されてサーバーのrootがバレるし
いろいろ不味いので新たにユーザーを作成する。

```bash
#ユーザーの作成とパスワード設定
adduser　ユーザー名

#sudoグループへ加入する
gpasswd -a ユーザー名 sudo

#ログインできるか確認する
su ユーザー名

#sudoできるか確認する
sudo echo "test"

#sshにログインできるか確認する
ssh -l ユーザー名 接続先
```
ここまで完了できたらユーザーはちゃんと追加できている。
もし追加ユーザーがsshに接続できない場合はkonohaの管理画面でsshkeyを設定している可能性が高い。
そのときはsshkeyを削除してサーバーを再構築リセットして最初から手順踏む。

###2:rootでのssh接続を遮断する
追加したユーザーで今後の作業を行うので
パンドラの箱であるrootは封印する。

```bash
#rootでログイン出来ないように設定ファイルを書き換える
sudo vi /etc/ssh/sshd_config
→PermitRootLoginをyesからnoに書き換える

#設定ファイルを反映させる
service sshd restart

#sshにrootでのログインを試みる(失敗するのが正しい)
ssh -l root 接続先
```
これでrootは無事封印された。

###3:sshkeyの設定をする。
さらにセキュリティを高めるために公開鍵認証でのssh接続ができるようにする。

```bash
#ホームディレクトリに移動して「.ssh」というフォルダを作って権限を設定する。
cd ~/
mkdir .ssh
chmod 700 .ssh

#「.ssh」に移動してsshkeyの生成して権限を設定する。
cd .ssh
ssh-keygen -t rsa -b 4096 -f 鍵ファイル名
chmod 600 鍵ファイル名

#catで表示させた鍵ファイルの中身をローカルにコピペする
cat 鍵ファイル名

#公開鍵の登録
ssh-copy-id -i 鍵ファイル名 ユーザー名@接続先

#以上完了したら秘密鍵でのログインを試す。
#うまく行ったなら秘密鍵と公開鍵(.pub)を削除する。
#秘密鍵は必ずバックアップに保存すること！
rm 鍵ファイル名
rm 鍵ファイル名.pub
```
今回は自分以外にサーバーを触る人がいないので、configファイルは作成しなかった。

###4:パスワード認証によるログインを遮断する
秘密鍵でログインできることを確認したら、パスワード認証でのログインは遮断したほうが良い。

```bash
#パスワード認証でログイン出来ないように設定ファイルを書き換える
sudo vi /etc/ssh/sshd_config
→PasswordAuthenticationをyesからnoに書き換える

#設定ファイルを反映させる
service sshd restart

#sshにパスワード認証でのログインを試みる(失敗するのが正しい)
ssh -l ユーザー名 接続先
```

###5:sshポートを変更する
sshのデフォルトポートは22番であるのは常識なので、だいたい22番を狙ってくる。
なのでポート番号を変更することで攻撃されにくくする。

```bash
#設定ファイルを書き換えてポート番号を変更する
sudo vi /etc/ssh/sshd_config
→「#Port 22」を「Port 番号」に書き換える

#設定ファイルを反映させる
service sshd restart
```

これでsshに接続するときは変更した番号でしか接続できなくなる。
…番号を忘れてはいけないよ？

###6:ファイアウォールの設定
設定することでアクセスを制限できて攻撃方法を狭めることができる。

```bash
#ファイアウォールを有効に
sudo ufw enable

#標準はアクセスを全て制限に
sudo ufw default deny

#例外でアクセスを許可する
sudo ufw allow https/tcp
sudo ufw allow http/tcp
sudo ufw allow ftp
sudo ufw allow sshポート番号

#設定を反映させる
sudo ufw reload
```

###7:パッケージの更新
古いverはセキュリティホールがある場合があるので更新する。

```bash
#パッケージ一覧の更新
sudo apt-get update

#インストール済みパッケージの更新
sudo apt-get upgrade
```

#ここまでやれば大丈夫
…なハズ。
初心者が初めてvps借りてやった手順をまとめてみました。
これやったほうが良いよってのがあったら教えて欲しいです！
tsserverをデバッグする

[TypeScriptリポジトリのwiki](https://github.com/microsoft/TypeScript/wiki/Debugging-Language-Service-in-VS-Code) にVSCodeを利用したデバッグ方法が記載されていたのですが、tsserver自体のデバッグだけだったらもっと簡単に出来るのでメモ

## tl;dr

単にnodeのデバッグを普通にVSCodeなりchromeのinspectorなりでやるだけです


## 手順

- TypeScriptのリポジトリを取得
- ビルドを実施
- tsserver.jsをnodeから `--inspect` フラグ付きで実行
- tsserverのプロセスにデバッガからアタッチする
- tsserverのプロセスに任意のコマンドを投げつけて適当にデバッグする


### TypeScriptのリポジトリを取得

普通にcloneしましょう
https://github.com/microsoft/TypeScript.git

### ビルドを実施

普通にビルドしましょう。至って普通です

```console
npm install
npm run build
```

ビルド結果は `built/local` に吐き出されます

### tsserver.jsをnodeから `--inspect` フラグ付きで実行

tsserver.jsをnodeで実行します。
`--inspect`フラグを付けることでデバッガからアタッチ可能になります


```console
node --inspect ./built/local/tsserver.js
```

すると↓のような出力が出ます

```
node --inspect ./built/local/tsserver.js

Debugger listening on ws://127.0.0.1:9229/c93e7eb4-5101-4937-bdc8-4a79d9d381f7
For help, see: https://nodejs.org/en/docs/inspector
Content-Length: 75

{"seq":0,"type":"event","event":"typingsInstallerPid","body":{"pid":4278}}
Debugger listening on ws://127.0.0.1:9230/ae4929aa-bae7-4c28-8e6f-144c1cbef644
For help, see: https://nodejs.org/en/docs/inspector
```

portはデフォルトが `9229` ですが、どうもtsserverはプロセスが2つ立ち上がるのでデバッグしたい箇所によってはどちらのポートにアタッチするかちゃんと選ぶ必要がありそうです（自分は最初に出力されたほうで間に合ったので特に調べてません。。）


### tsserverのプロセスにデバッガからアタッチする

任意のデバッガでtsserverのプロセスにアタッチしましょう。これでデバッグが出来るようになります

#### VSCodeの例


以下のように `launch.json` を作成して、デバッグコンソールからデバッグを開始すればOKです
アタッチに成功するとtsserverのプロセスで `Debugger attached.`と出力されます

```json:launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Attach to TS Server",
      "type": "node",
      "request": "launch",
      "protocol": "inspector",
      "port": 9229,
      "sourceMaps": true,
      "outFiles": ["/path/to/TypeScript/built/local"],
    },
  ]
}
```

- `port`についてはここでは `9229`にしてありますが、先述の通りデバッグ箇所によって適切に変更する必要があるかもです
- ソースマップの解決のために `outFiles` を適切に設定して上げる必要があります

詳しくはVSCodeのドキュメントの[node.jsのデバッグ方法のページ](https://code.visualstudio.com/docs/nodejs/nodejs-debugging)を見てください


#### chromeの例

- `chrome://inspect`を開き、 `configure`ボタンからデバッグしたいURLを入力します
  - `127.0.0.1:9229` など
- Remote Targetの項目にデバッグ対象のプロセスが現れるので `inspect` を押します
- インスペクタの `Sources`を開き、左ペインの `+Add folder to workspace` をクリックし、TypeScriptのリポジトリを選択します
- いい感じにソースマップを解決してくれるので、適当にtsファイルをデバッグします

＊chromeの方は使ってないのでちゃんと調べてないです（エディタでデバッグするほうが定義ジャンプとかする関係で楽なので。。）


### tsserverのプロセスに任意のコマンドを投げつけて適当にデバッグする

tsserverは標準入力でコマンドを受け付けるようになっているので、↓のようにデバッグしたいコマンドを貼り付けて実行してやれば処理が開始されます
サーバーのデバッグのためにHTTPリクエスト投げつけるぐらいのノリですね

```json
{"command":"open","arguments":{"file":"/path/to/sample.ts"}}
```

実際のコマンドをどうやって探すかという話については、VSCodeのコマンドパレットから `Open TS Server log`と叩いてやってエディタが得ているログを見れば、↑のようなjsonがそのまま転がっているのでそれを利用すればOKです

## おわり

以上、tsserverをデバッグする方法でした
テスト6

```vb

Sub コピー貼付()

Dim Efile  As String
Dim FSO As Object, f As Variant
Set AppObj = CreateObject("Excel.Application")  '実行時バインディング

Set FSO = CreateObject("Scripting.FileSystemObject")
DoCmd.SetWarnings False

For Each f In FSO.GetFolder(Application.CurrentProject.Path).Files

    If FSO.GetExtensionName(f.Path) = "xlsx" Then
    
        Efile = Application.CurrentProject.Path & "\" & f.Name
  
        Set WBObj = AppObj.WorkBooks.Open(Efile)  'ワークブックを開く
        
        Set WsObj = WBObj.activesheet

        AppObj.Visible = True   'Excelを表示
        
        WsObj.usedrange.select

        WsObj.range("A1").Activate
        
        AppObj.selection.copy

        DoCmd.OpenTable "テーブル1"
        
        DoCmd.RunCommand acCmdSelectRecord
        DoCmd.RunCommand acCmdPaste
    
        AppObj.Visible = False 'Excelを閉じる
        
    End If

Next

DoCmd.SetWarnings True

End Sub

```
#ruby #rails の #rspec でランダムに落ちるテストを再現したい

- it をめちゃくちゃ増やす。以上。

例:

```
describe do
       subject { some_method } 

        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
        it { is_expected.to be false }
end

```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2206








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
CSSを始める前に

こんにちは。職業です。

タイトルの通り
#今回からCSSについてになります！

それでは、
CSSを始めるうえで必要な知識について、ご紹介しようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/000b36a8-567a-a968-12d2-be261102422b.png)


HTMLとcssはリンクする必要があるため、
ファイルは新しく作成しましょう。

既存ファイルのheadの中にlinkを書きます
hrefの中に新規ファイル名を記入します。

![スクリーンショット (35).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427747/9c581be1-6786-adb2-88ec-a0cd87015702.png)


こちらで下準備は完了になります。

是非参考にしてみてください。
[Node.js] requireなんてわかってる！ようでよくわかってなかったからいろいろ試した

# はじめに
1. Node.jsの`require`の挙動がおかしい！
2. そういえば`require`の細かいところよくしらない
3. いろいろ試してみよう
4. 試したことを書いておこう

# 要約

<font color="red">
**これおかしいんちゃうんけ！どないなっとんねん！！**
↓(色々試す)
**わいがおかしいだけやんけ！！どうかしてたわ！！**
</font>

調べてみたら**「あたりまえやんけ」**ってなることも
調べるまでは**「あたりまえじゃない」**ってことですね。

とりあえずほんの少し`require`に詳しくなれるかもしれない記事です。

# ファイルに直で書かれた処理はrequireされたときに一度だけ評価される

```index.js
const hoge1 = require("./hoge");
const hoge2 = require("./hoge");
```

```hoge.js
console.log("Hoge");
```

```index.jsの実行結果
Hoge
```

`require`を２回しているけど、`Hoge`は１回しか表示されない。

`require`するたびに評価されたらどうしようと思ったけど
評価されなかった、よかった。

# `exports.xxx`したプロパティは共有されるのか

```index.js
const hoge1 = require("./hoge");
const hoge2 = require("./hoge");

console.log(hoge1.a);
console.log(hoge2.a);
```

```hoge.js
exports.a = 0;
```

```index.jsの実行結果
0
0
```

`index.js`に以下の１行を入れたらどうなるか

```diff:index.js
const hoge1 = require("./hoge");
const hoge2 = require("./hoge");

+ hoge1.a = 10;
console.log(hoge1.a);
console.log(hoge2.a);
```

```index.jsの実行結果
10
10
```

`hoge1.a`を変えたら`hoge2.a`も変わった。
`require`は同じ参照先を返してくるらしい。

# `require`したファイルの中の処理が評価されるタイミングは？

```index.js
const hoge = require('./hoge');
console.log(hoge.a);
const foo = require('./foo');
```

```hoge.js
console.log("Hoge");
exports.a = 0;
```

```foo.js
console.log("Foo");
```

```index.jsの実行結果
Hoge
0
Foo
```

`require`したタイミングで評価される。
ここらへんはインタプリタですなぁ。

## `foo`の中で`hoge`の中身いじったら？

```diff:index.js
const hoge = require('./hoge');
console.log(hoge.a);
const foo = require('./foo');
+ console.log(hoge.a);
```

```diff:foo.js
console.log("Foo");

+ const hoge = require('./hoge');
+ hoge.a = "Fooの中で書き換えてやったぜ";
```

```diff:index.jsの実行結果
Hoge
0
Foo
+ Fooの中で書き換えてやったぜ
```

`require`は同じ参照を返すわけだから
`foo.js`の中で`hoge.a`を書き換えたら`index.js`の`hoge.a`にも影響する。
当然である。

# なんかシングルトンに見えてきた

実際の動きから見えてくる事実や推測

- 初めて`require`された時に一度だけ中の処理が評価される
- ２回目以降の`require`では、１回目の時に評価されたモノ(インスタンス)の参照が戻ってくる。

すごくあれっぽいな
これって要するに**シングルトン**じゃないですか？

`require`が**シングルトンをつくる関数**に見えてきました。

これが

```index.js
const hoge1 = require("./hoge");
const hoge2 = require("./hoge");
```

こう見えてきた感じ(要するにhogeのinstanceがくるんやろって見えてる目)

```index.js
const hoge1 = hoge.instance;
const hoge2 = hoge.instance;
```

# まとめ

結局何が知りたかったのか

```js
const a = require('hoge');
const b = require('hoge');
```

果たして`a`と`b`は同じものになるのか？
いや、同じじゃないと困るでしょって話だし結果同じもの入ってました。

どうにか違うものが返せないかと試行錯誤してみたけど無理だった。
(できた！って人いたら教えて欲しい)

# あとがき

わいA「Node.jsは`commonJS`や`es module`や`typescript`やら
外部ファイルを読み込みたいだけなのに、書き方がたくさんあって混乱するんや」

わいB「比較的どんな言語でも"C/C++"ならどうか？
と置き換えて考えればある程度いけるんやけどな」

わいA「Node.jsの`require`は`C/C++`でいうところの何になるんや」

わいB「バシッっと置き換わるものがなくてもやもやするよな」

わいB「`exports`は外部リンケージ(extern)
グローバルに`let`とかで定義した変数は内部リンケージ(static)
と考えてよさそうやん？」

わいA「禿同」

わいA「問題は`require`や」

わいB「Cの`include`じゃね？」

わいA「そう思わせておいての、そうじゃないやつやん？」

わいB「せやなぁ、そもそも`include`ってマクロやしな」

わいA「外部ファイルを取り込む的なニュアンスは同じやけど
根本的にNode.jsの`require`とは別物にしか見えないやで」

わいB「禿同、というわけで今回いろいろ試したわけやし、一応答えを見つけたやん」

わいB「`require`はシングルトンをつくる関数やって」

わいA「ただの関数だったか」

わいB「ただの関数やったんや」

わいA「引数与えて、戻り値もあって」

わいA「確かに関数やな」

わいB「せや、関数や」

わいA「なんだぁ、関数だったか」

めでたしめでたし。
ChromeBookでVisual Studio Codeを設置

## 概要
クロームブック(ASUS C223NA)にWEB開発のためのVisualStudio Codeを設置できましたので、忘れないうちにその記録を残します。
※　クロームブックのモデルが異なる場合設置内容が異なることがあります。
※　下のサイトを参考しながら作業しました。不要な設定があるかもしれません。


### 参考
https://www.taneyats.com/entry/vscode-on-c101pa

## 設置順序
1. Linux設置
1. IME設置
1. VisualStudio Code設置

## Linux設置
Linux設置のためクロームブックを開発モードに変えなくてもできるようになりました。
オプション画面のLinux（ベータ版）をクリックすると設置されます。

設置完了後下のコマンドでアップデートします。（不要かもしれません。）

```bash
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade
```

## IME設置
IME　fcitx及びフォントNoto Sans CJK JRを設置します。
設置途中、Y/nで入力を要求された場合、Yあるいはそのままエンターキーを入力してください。

### fcitx 設置

```bash
$ sudo apt-get install fcitx
$ sudo apt-get install -y fcitx-mozc
$ sudo apt-get install fcitx-lib*
```
設置後im-configを実行しfcitxを選択し、OKをクリックしてください。

```bash
$ im-config
```
fcitx-configtoolを実行して日本語IMEを追加します。
そのまま実行する場合画面に何も表示されないためfcitx-autostartを先に実行してください。

```bash
$ fcitx-autostart
$ fcitx-configtool
```

+ボタンをおして、Only show current languageを解除後、mozcを検索しOkをクリックすると日本語IMEが追加されます。

(参考) IME　Toggleが規定値で`ctrl`+`spacebar`ですが、VisualStudio CodeのIntellisenseショットカットキーとかぶるためGlobal ConfigでTriggerを
`Shift` + `Ctrl` + `SpaceBar`に変更しました。

### フォント設置
日中韓のフォントが全部必要だったためNoto Sansを選択しました。

```bash
$ sudo apt-get install fonts-noto
```

## VisualStudio Code設置
下のURLでクロームブックのCPUとあうものをダウンロードします。
(ASUS C223NAの場合IntelのCPUであるため`code-oss_1.32.0-1550644812_amd64.deb`をダウンロード)
https://github.com/headmelted/codebuilds/releases

ダウンロード後、ファイルエクスプローラーでダウンロードフォルダを開き、debファイルを右クリック（タッチパッド２点タッチ）し、Linux設置を選択すると設置が始まります。

## 終わり
これで200ドルの開発向けクロームブックの出来上がりです。（笑）
クロームブックの購入時から開発マシンで使用する計画でしたが、Linuxの知識不足と、情報不足でうまく行かなかったが、やっと設定完了できました。
低価クロームブックのため快適とは言えないけれど、簡単な開発には問題なさそうです。
Windows10にてAtomでdjangoの環境を作る

#背景
会社のPCが入れ替わりになったので。これ書くの3回目。

##この文書には前編があります
なのでこちらを参照ください。

#virtualenvで仮想環境を作る

##virtualenvをインストールする

ここを参考にしました。
https://qiita.com/kaki_k/items/1fff7fefcf26dc4b69bc

```pip install virtualenv```
コマンドプロンプトで実行してみるとがっつりエラー。
パーミッションがどうのと言ってますね。。。
```Could not install packages due to an EnvironmentError:　・・・```

これはコマンドプロンプトを「管理者として実行」することであっさり解決しました。

##環境を作る
コマンドプロンプトで仮想を作りたいフォルダに移動します。
例えばドキュメントフォルダにenv1という環境を作りたい場合

> $> cd C:\Users\{ユーザー名}\Documents
> $> virtualenv env1

この手順でいけるんじゃないかなと。

###アクティベートで躓く

さて、仮想環境に入りたいのですが。。。

仮想作ったフォルダで
> $> Scripts¥activate
を実行しても、私はうまくいきませんでした。。。

> $> cd Scripts
> $> activate
これでうまくアクティベートできました。

###仮想環境から抜けるときは

> $> cd Scripts
> $> deactivate

これですね。

#djangoを導入する

##djangoを仮想環境にインストールする
env1の中にDjangoをインストールします。
アクティベートの際チェンジディレクトリしている場合は元の仮想環境直下に移動します。
```(env1) C:\Users\{ユーザー名}\Documents\env1>pip install django```
これでインストール完了です。

#後日編集します
djangoは今すぐ使う用事ないので、いったんここまでの作業です。
あとは勉強あるのみ！
Windows10にてAtomでPythonの環境を作る

#背景
会社のPCが入れ替わったので環境作り直します。

##前編があります
この記事は続きです。Atomでなんでもやろうという精神です。

##筆者のできること・やりたいこと
Pythonで作った数値計算アルゴリズムにUIをつけたい。
もっといい方法あるのかもしれないけど、djangoでやりたい。
HTML/CSS(Scss)は勉強したので習得済み。

#Pythonのインストール
Annacondaを使う手もあるんだけど、余計なのもインストールされちゃうしエディタかぶっちゃうし。
なので今回は純粋にPythonをインストールしてみます。

こちらを参考にします。
https://qiita.com/ryokurta256/items/7d5e87ad6827b20fddd0


Pythonをダウンロードします。
https://www.python.org/downloads/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/948bae8c-e813-30cb-ca49-3295e9382214.png)
黄色いボタンぽちっと。

インストーラを起動すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/ec4ad09d-f385-fe83-9764-dee91bd5b304.png)
今回は*Customize installation*を選択。
というのも、WindowsでPATHが上手く通らない事件を経験しているので。。
(筆者が無知なだけかも。)
今回は最初からPATHを通してもらいます。Pythonだけに蛇道。。。
Nextで進めて、*Advanced Options*にて*Add python to environment variables*にチェック入れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/cd6d092f-9049-bf2b-2385-0ba805e66b8a.png)
どうせ私しか使わないPCなので*Install for all users*にもチェック入れますか。(Pathが煩雑になるしね)

というわけでインストール完了です。

##Atom-runnerのインストール
Atomでインストールします。これね。
https://atom.io/packages/atom-runner
これでJupyterNotebookと同じことがAtomでできるはず！
(私はJupyterNotebookが嫌い。。。)

インストール完了しました。
Windows環境では、Atom-runnerの実行ショートカットキーは**「Alt-r」**です。
なぜ実行できない～と悩んでいたけど、簡単なオチでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/e6524ff5-4b5e-00e6-0878-5ba4d7a90d09.png)
無事実行確認ができました。おお、今回も順調～。

#おまけ

##Numpyのインストール

管理者権限でコマンドプロンプトを起動し
```pip install --proxy http://{ID}:{password}@:{プロキシサーバー}:{8080} numpy```
これでインストールできます。

#終わりに
JuyterNotebookは中間ファイルみたいなのができるでしょ～。
あれがよくわからなくてキライなんです。。。
PHPでメソッドチェーンの速度を計測してみた

# 概要
PHPでは，メソッドチェーンを使った処理のほうが遅くなると聞いたので，実際に処理時間を計測して比較してみました．

# 環境
- Macbook Pro (2018,i5,256GB)
- PHP 7.3.5 (Homebrew)

# 比較内容
次のパターンで計測しました．

1. class内でメソッドチェーンを使用
2. class内でメソッドチェーンを不使用
3. インスタンスに対して，メソッドチェーンを使用
4. インスタンスに対して，メソッドチェーンを不使用
5. インスタンスに対して，メソッドチェーンが使えるが，あえて使わない

# 比較用コード
コード内の"..."では同様の処理を50000行実行しています．

```php
class TestClass {
    public $count;

    public function __construct() {
        $this->count = 0;
    }

    public function noReturnThis() {
        $this->count += 1;
    }

    public function returnThis() {
        $this->count += 1;
        return $this;
    }

    public function callInClassChain() {
        $this->returnThis()-> ... ->returnThis();
    }
    
    public function callInClassNoReturn() {
        $this->noReturnThis();
        ...
        $this->noReturnThis();
    }
}

$test1 = new TestClass;
$test2 = new TestClass;
$test3 = new TestClass;
$test4 = new TestClass;
$test5 = new TestClass;

$time_start = microtime(true);
$test1->callInClassChain();
$time = microtime(true) - $time_start;
echo "クラス内チェーン:{$test1->count}：{$time}\n";

$time_start = microtime(true);
$test2->callInClassNoReturn();
$time = microtime(true) - $time_start;
echo "クラス内ノーチェーン:{$test2->count}：{$time}\n";

$time_start = microtime(true);
$test3->returnThis()-> ... ->returnThis();
$time = microtime(true) - $time_start;
echo "クラス外チェーン:{$test3->count}：{$time}\n";

$time_start = microtime(true);
$test4->noReturnThis();
...
$test4->noReturnThis();
$time = microtime(true) - $time_start;
echo "クラス外ノーチェーン:{$test4->count}：{$time}\n";

$time_start = microtime(true);
$test5->returnThis();
....
$test5->returnThis();
$time = microtime(true) - $time_start;
echo "クラス外ノーチェーン2:{$test5->count}：{$time}\n";
```

# 測定結果

数回計測を行い，中央値を取りました．
比は最も早かったクラス外ノーチェーンを基準にしたものです．

| 順位 | ケース | 処理時間(秒) | 比 |
| --- | --- | --- | --- |
| 4 | クラス内チェーン | 0.0020990371704102 | 1.12 |
| 3 | クラス内ノーチェーン | 0.0020008087158203 | 1.07 |
| 5 | クラス外チェーン | 0.0024318695068359 | 1.30 |
| 1 | クラス外ノーチェーン | 0.0018730163574219 | 1 |
| 2 | クラス外ノーチェーン(returnあり) | 0.0019741058349609 | 1.05 |

# まとめ
やはりメソッドチェーンを用いた処理は遅くなる傾向があるようです．しかしながら，クラス内でのチェーンはそこまで遅くならないようです．
また，遅くなると言っても5万回繰り返して数ミリ秒遅くなる程度なので，よほどのことがない限りは気にするる必要はないと思います．
Windows10にてHTMLとSASSの環境をATOMで作る

#背景
会社PCが更新されたので、改めて環境作ります。

#環境
ThinkPad X1 で環境を作ります。

- OS:　Windows10　Enterprise
- プロセッサ：Intel(R)Core(TM)i5-8250U CPU@ 1.60GHz, 1.80GHz
- 実装メモリ(RAM)：8.00GB
- システムの種類：64ビットオペレーティングシステム、x64ベースプロセッサ
- HDD:　SSD128GB　

#ATOMの環境構築
##ATOMのインストール
ATOM公式HP(自動でOS等認識します)
https://atom.io/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/e5fbc3d8-c948-76bd-7e6d-189c7741a438.png)

##ATOMの日本語化
**Install a Package**で**japanese-menu**を検索し、インストール。
https://atom.io/packages/japanese-menu

##タグの自動成型
**atom-beautify**を検索し、インストール。
https://atom.io/packages/atom-beautify

#Sass/Compassの環境構築
Sassが使える環境にしたいので、AtomにSassとCompassを導入します。
参考にしたHP
http://weblifetimes.com/atom-compass-compile/

##Rubyのインストール
インストーラはこちら。
https://rubyinstaller.org/downloads/
環境が欲しいだけなので「WITHOUT DEVKIT」から選択すればよいと思います。

Rubyのインストールにはこちらを参考にしました。
https://www.kenschool.jp/blog/?p=3898

今回はRuby2.5.3-1(x64) を選択。
*USE UTF-8 as default extarnal encoading.*にチェック入れてインストーラをインストールします。

###Proxy環境でMSYS2のインストールに躓く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/e9facba7-a458-873b-5988-7d8b685c5e68.png)
想定の範囲内だったけど、やっぱProxyめんどくさい。
https://qiita.com/kiyoneet/items/8bbc8ffd006855593e4e
ここを参考に、あらかじめダウンロードすることに。

http://www.msys2.org/
ここからMSYS2をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375367/fc3a8647-8da8-2e14-85fb-1cbd57d1ae58.png)
右のインストーラでよいはず。インストールして完了です。

##Sassのインストール
proxy設定しないとgemが使えないので、こちらを参考にインストール。
https://qiita.com/wakaba260/items/f7794cea3fac8c694dcf

SassはRubyのプロンプトで以下を実行
```gem install sass -r -p http://{ID}:{password}@{proxy server}:{port}/```
無事Sassインストール成功。

##Compassのインストール
Sassと同様にインストール。
```gem install compass -r -p http://{ID}:{password}@{proxy server}:{port}/```
インストール完了。順調～。

##Atomでコマンド実行できるようにする。
Atomでatom-terminal-panelをインストール。
https://atom.io/packages/atom-terminal-panel

これで、AtomでSassがコンパイルできるようになりました。

#最後に
何度も環境作ってて、あちこちページを行き来するのが嫌すぎて。。。
ちょっと纏めたいなと思って書き始めました。
c# async voidでawait Task.Run()失敗の巻

![これで失敗.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293616/13cecf41-d8fe-a0a0-9554-7d42ad0ff361.png)
##はじめに
```.cs
await Task.Run(() => HeavyMethod());
```

このようなサンプル良く見かけますね。何気なく使っていました。
実はこれで失敗したんです。
私は最近までTask.Runで包み込んでやると上記サンプルのようにHeavyMethodもTaskになるものだと勘違いしていました。
後から調べたらHeavyMethodの中身が問題で、awaitを使う場合async voidはUIのイベント処理以外は使うなと色々な所に書かれていますね。

例えばコマンド(Start）を送った後2秒待っでコマンド(End）を送る処理で、Start~Endが終わってから次の処理を実行することが条件になる場合、async voidを使うと期待通り動かないことがあります。
ご存知の方にはそれほど大げさなことでは無いかも知れませんが...書き留めます。

##async voidでは意図した動作にならない
上記のサンプル物まねでやった結果です。

```.cs
private async void button1_Click(object sender, EventArgs e)
{
    for(var i = 0; i < 3; i++)
    {
        await Task.Run(() => DelayMethodByAsyncVoid(i));
    }
}

async void DelayMethodByAsyncVoid(int id)
{
    System.Console.WriteLine("Start "+id);
    await Task.Delay(2000);
    System.Console.WriteLine("End " + id);
}
```

```
Start 0
Start 1
Start 2
End 2
End 1
End 0
```
ラムダ式の中はTaskですが``DelayMethodByAsyncVoid(i)``の中はTaskでは無いので``await Task.Delay``のところでTask完了となっているみたいです。
DelayMethodByAsyncVoidは非同期で動きます。
そもそもMethod 1つを呼ぶのにTask.Runを使うのが良いのかという疑問もあります。

##ラムダ式の中に処理を書く
ラムダ式の中に``DelayMethodByAsync(i)``の処理を書くとすべての処理がTaskとなりうまくいきます。

```.cs
private async void button2_Click(object sender, EventArgs e)
{
    for(var i = 0; i < 3; i++)
    {
        await Task.Run(async () =>
        {
            System.Console.WriteLine("Start " + i);
            await Task.Delay(2000);
            System.Console.WriteLine("End " + i);
        });
    }
}
```

```
Start 0
End 0
Start 1
End 1
Start 2
End 2
```

###async Taskを定義する
何でもかんでもTask.Runでやっていたのですが複数個所から呼ばれる場合async Taskで定義するのがすっきりします。

```.cs
private async void button3_Click(object sender, EventArgs e)
{
    for(var i = 0; i < 3; i++)
    {
        await DelayMethodByTask(i);
    }
}

async Task DelayMethodByTask(int id)
{
    System.Console.WriteLine("Start "+id);
    await Task.Delay(2000);
    System.Console.WriteLine("End " + id);
}
```

```
Start 0
End 0
Start 1
End 1
Start 2
End 2
```

##動作環境
<dl>
<dt>開発環境</dt>
<dd>Visual Studio Community 2017</dd>
<br>
<dt>ターゲットフレームワーク</dt>
<dd> .NET Fremawork 4.6.1</dd>
</dl>
Orientationのパラメータのまとめ[Swift](UIDeviceOrientation, UIInterfaceOrientation)

### 向きとrawValueの関係
`UIInterfaceOrientation`はDeviceではなくUIの向きである
`UIInterfaceOrientationLandscapeLeft` = `UIDeviceOrientationLandscapeRight`
`UIInterfaceOrientationLandscapeRight` = `UIDeviceOrientationLandscapeLeft`


### UIDeviceOrientation と UIInterfaceOrientation
**※enumは型のみ指定して値を入れない場合は0から代入される**

```swift
public enum UIDeviceOrientation : Int {

    case unknown //0 

    case portrait //1 //普通の縦向き

    case portraitUpsideDown //2 //逆さ向き

    case landscapeLeft //3 //homeボタンが右

    case landscapeRight //4 //homeボタンが左

    case faceUp //5 //地面に平行向き//スクリーンが上

    case faceDown //6 //地面に平行向き//スクリーンが下
}
```

```swift
public enum UIInterfaceOrientation : Int {

    case unknown //0 

    case portrait //1 //普通の縦向き

    case portraitUpsideDown //2 //逆さ向き

    case landscapeLeft //3 //homeボタンが左

    case landscapeRight //4 //homeボタンが右
}
```

### rawValue以外で取り出す方法
**普通に`rawValue`でやるとこうなる**

```swift
print(UIInterfaceOrientation.rawValue) //1
```

**case名で取り出したい**(ex. `1`ではなく`portrait`)
→どの値か事前にわかってない場合は`rawValue`以外は無理

```swift
print(UIInterfaceOrientation.portrait) //portrait
```

### 強制的に値をセット(回転させる)

```swift
override func viewDidLoad() {
        super.viewDidLoad()
        UIDevice.current.setValue(3, forKey: "orientation")
        //landscapeLeft //homeボタンが右
        //UIDevice.current.orientationを設定するのでforkeyはorientationじゃないとダメ
    }
```