OmniAICreator/Qiita-1.07M huggingface dataset:
UNIXコマンド入門 1/3

UNIXコマンドについて

UNIX...open source
互換OS...Linux
Linuxの配布形式＝ディストリビューション
有名なディストリビューションの系統：Red-Hat系等
Red-Hat系で有名なディストリビューションが
Red Hat Enterprise Linux
CentOS

使えるコマンドはPOSIXという共通規格

ファイル転送ツール内
-bin バイナリが入っている
catやcpといったシステムを動かすための基本コマンドの実行ファイルがたくさん入っています。

-etc
アプリケーションの設定不ファイルが入っている。

-home
各ユーザのホームディレクトリが入っている。
 -vagrant
  -薄くなったファイル：.ファイルと呼ばれる隠しファイル

-sbin
システム管理用のコマンドが入っている。

-user
一般的なアプリケーションが格納されている

-var
システムのログファイルなど、頻繁に書き換わるファイルが置かれている。

Terminal にて
pwd (print working directory)　現在のディレクトリを表示
ctrl+L or clear+ enter でクリアすることができる。

 1 つ上の階層に戻るには cd .. で戻ることができる。
 直前のディレクトリに戻るには cd - でもおっけー

Path の指定
相対指定:現在のディレクトリから見て相対的な場所を指定する方法
絶対指定:一番上の階層から絶対的に指定する方法

mkdir:ディレクトリを作るためのコマンド
-->mkdir myapp

ls(list):ディレクトリの内容を見る。 

cp myapp myapp2:myapp をコピーして myapp2 作る。
＊ただしディレクトリをコピーするには、再帰的にコピーするという意味で recursive の -r オプションを付ける

mkdir -p myapp3/config: myapp3ディレクトリを作って、
その中にconfigディレクトリを作る。
ただし、myapp3 ディレクトリが存在していない時は、
その場合は mkdir に parents オプション 
-p を付けてあげると config ディレクトリの親ディレクトリがなければ
合わせて作ってくれます。

mv myapp3 myapp2: myapp3をmyapp2の中に入れる。

rmdir: ディレクトリの削除コマンド(中身が空のディレクトリにしか使えない)
rm -r:　中身がある場合は、recursiveオプションをつけて削除する。

cat (myapp/hello.txt): ファイルの中身を見るコマンド

less (myapp/hello.txt): 長いファイルの中身を見るときに有用
スペースキー か Control + F でforward、 
Control + B でback
g でファイルの先頭、そして G (Shift + g) で末尾に移動することもできます。
*lessの終了方法はquitのq

cp myapp/hello.txt .  ファイルのコピー.一つで今のディレクトリを表現できる。
mv ファイルの移動.同じディレクトリ内で使うと名前の変更になる。
rm ファイルの削除

便利機能
-TABキーによるpathやcommandの補完
-control + c:コマンドを途中でキャンセル
-矢印キーの上下：コマンドの履歴の閲覧
-control + r:コマンドの履歴の検索
-history コマンドの履歴を閲覧
 --> !299 のように!+番号でそのコマンドを実行可能。
　　　!!で直前のコマンドを呼び出すことも可能。
　　　!-2で一つ前のコマンドを呼び出すことも可能。

*コマンドに渡した最後の文字列を再利用するには !$ を使えば OK 。
*!pw と打つと、pwで始まる直近のコマンドを打つことができる。
 !pw:p とすると、直近のコマンドを表示だけしてくれる。

コマンド　+ --help : コマンドの説明を表示。
man + コマンド:より詳しく説明を表示
本当の初心者のためのemunを使った状態管理(クリック一つで状態変遷させるやつ)の実装 rails


親切なコメントを受けて修正しました。
コメントまたは下記のリンクから詳しい説明と動画付きのページに飛べます。
https://qiita.com/jnchito/items/c7e93c7a1fc7fc34a177

#以下から本文(上記のリンクで十二分なので見る必要はないかもしれない)


参考　https://qiita.com/shizuma/items/d133b18f8093df1e9b70

前半部分の話は上記が詳しくてわかりやすいです。



ですが本当の初心者（僕を含めて）はroute や　controller や　view 周りなどはこれを見ただけは実装するのが難しいです。（簡単??）

ちなみに下記はinteger型の実装例です。




#controller
###article controller
```app/controllers/hoges_controller.rb

  def toggle_status
    if @article.draft?
      @article.published!
    elsif @article.published?
      @article.draft!
    end

    redirect_to "wherever you like"
  end
```
みたいな感じでcontrollerを定義する

#route

```app/config/routes.rb
修正前
get :toggle_status
修正後
patch :toggle_status
```

みたいな感じでrouteを設定する

#view

```app/views/articles/hoge.html.erb
修正前
<%= link_to article.status, toggle_status_article_path(article) %>
修正後
<%= link_to article.status, toggle_status_article_path(article),method: :patch %>
  
```

みたいな感じで程よい場所に設置する

#結論

一応これでボタン一つで状態を変遷させるやつが実装できます。

初心者はview controller model route 全て具体例がないと実装できません（泣）
そのようなクソ雑魚ナメクジも世の中には存在することを頭の片隅に置いて投稿してくれる人が増えれば幸いです。
jsonファイル内の欲しいデータをパス形式で取得するスクリプト

# なぜ作った

Firebase の RealtimeDatabase をバックアップデータから復元したい時がありました。
Blazeプランにしていれば、バックアップデータは毎日自動的に取っておいてくれます。
これを取って来て、さあ目的のjson部分を取り出そう…と思ったらこれが大変。

ファイルは巨大だし、中身は改行もなくとんでもない長い1行になっていて、データの確認するのも一苦労…
というわけで作ったスクリプト（Ruby）。


## スクリプト

```
#!/usr/bin/ruby
# coding: utf-8
require "json"

if ARGV[0] == "-h" then
puts <<-EOS
# 使い方
#
# ruby json_extraction.rb XXX.json path/to/json/data >> output.json
#
#   第1引数
#     jsonファイル
#
#   第2引数
#     path/to/json/data で、欲しいjsonデータをパス形式で指定
#       ex: user/12345/save/GameManager
#     配列の場合も、インデックスをそのまま書けばOK
#       ex: common/data_list/0/name
#
#   出力もjson形式。そのままGoogleRealtimeDatabaseにインポートできる形式
#
EOS
exit
end

# ファイル名
input_file_name = ARGV[0]

# 抽出パス
extraction_path = ARGV[1]

if input_file_name.nil? || extraction_path.nil?
  puts "引数が足りません (-h でヘルプ)"
  exit
end

# utf-8形式に変換（念のため）
`nkf -w --overwrite #{input_file_name}`

# JSONデータ
open(input_file_name) do |io|
  all_json = JSON.load io

  json = all_json
  extraction_path.split("/").each do |key|
    key = key.to_i if json.is_a? Array
    json = json[key]
  end

  puts JSON.pretty_generate json
end
```

## 使い方

スクリプト内に書いてある通り。
パスみたいな書き方指定にしてるのは、RealtimeDatabaseの流儀？に揃えたため。
解析入門 1 問題1.3 解答

松坂和夫 解析入門<1>(ISBN: 978-4007304514) の解答です。

## 問題 1.3

### 1
#### 問題
28-29ページの命題2を証明せよ。

命題2
(a) $a\ne0$、$ab=ac$ならば$b=c$。
(b) 乗法単位元 $1$ はただ1つである。
(c) $0$ でない元 $a$ の乗法逆元 $a^{-1}$ は $a$ に対して一意的に定まる。
(d) $a\ne0$ ならば $(a^{-1})^{-1}=a$。
(e) $b\ne0$ ならば、方程式 $bx=a$ は一意的な解 $x=ab^{-1}$ をもつ。

#### 公理
公理群(M)
**M1** 任意の $a \in F$、$b \in F$ に対して、それらの積 $ab$ が $F$ の中に定まる。
**M2** 乗法は可換である。すなわち、任意の $a,b \in F$ に対して $ab = ba$。
**M3** 乗法は結合的である。すなわち、任意の $a,b,c \in F$ に対して $(ab)c = a(bc)$。
**M4** $F$ の中に $0$ と異なる1つの元 $1$ があって、すべての $a \in F$ に対して $a1 = a$ が成り立つ。
**M5** $F$ の $0$ でない任意の元 $a$ に対し、$aa^{-1}=1$ を満たす $F$ の元 $a^{-1}$ が存在する。

#### 解答
(a) $aa^{-1}=1$ であるから、公理群(M)を用いて

```math
\begin{equation}
b = 1b = (a^{-1}a)b \\
= a^{-1}(ab) \\
= a^{-1}(ac) \\
= (a^{-1}a)c \\
= 1c = c
\end{equation}
```

(b) (a) において $c=1$ とおけば、$ab=a$ ならば $b=1$

(c) (a) において $c=a^{-1}$ とおけば、$ab=1$ ならば $b=a^{-1}$。これは $a$ の乗法逆元 $a^{-1}$ がただ1つであることを示している。

(d) $a^{-1}a=1$ であるから、$a$ は $a^{-1}$ の乗法逆元である。すなわち $(a^{-1})^{-1}=a$

(e) $x=ab^{-1}$ とおけば、

```math
\begin{equation}
bx=b(ab^{-1})=b(b^{-1}a)=(bb^{-1})a=1a=a
\end{equation}
```

### 2
#### 問題
$A$ を $R$ の下に有界な空でない部分集合とする。$-A$ を、$x \in A$ に対する $-x$ 全体の集合とすれば、$inf A=-sup(-A)$ であることを証明せよ。（ここでは定理2を仮定する。）

#### 定理2
順序体 $R$ は上限性質を満たす。（したがって下限性質も満たす。）

#### 解答
$A$ は下に有界であり、$R$ は下限性質を満たすので、$A$ の下限 $infA \le x \in A$ が存在する。$infA \le x$ の両辺に $-1$ をかけると $-infA \ge -x$。よって、$-infA \ge y \in -A$。したがって

```math
\begin{equation}
-infA = sup(-A) \\
infA = -sup(-A)
\end{equation}
```
JavaのLambdaをCodePipelineでリリースするサンプル周辺の豆知識

# TL;DR

こんな記事を書きました。
[JavaによるLambdaをCodepipelineで自動リリースする最小構成サンプル](http://qiita.com/kazurof/items/c364e58a9a75e5201499 "JavaによるLambdaをCodepipelineで自動リリースする最小構成サンプル") 

この記事で書かれているCodePipelineの周辺情報の私的メモです。

# CodePipeline全体の流れ

## 1. Source ステージ

githubリポジトリの定時監視と更新があったらコードを取得する。

## 2. Build ステージ

CodeBuild によるビルド。buildspec.ymlの記載通りビルドが実行される。

1. `gradlew` でjarファイルの作成がされる。
2. `aws cloudformation package` が実行され、以下の処理が実行される。
  1. 生成された jarファイルを `S3::auto-release-sample` に配置される。
  2. テンプレートファイル(`packaged-minimum-lambda-java-model.yaml`)を生成され、Codepipeline用に作られたS3バケットに配置される。

## 3. Staging ステージ

テンプレートファイルとjarファイルから、Lambda関数が構築される。

1. 前回実行結果との差分の抽出。（アクションモード：変更セットの作成または置換）
2. 差分から実際にLambda関数の構築を行う。（アクションモード：変更セットの実行）


# 雑駁な周辺知識

## S3

CodePipeline作成時にS3バケットが作られる。命名パターンは
`codepipeline-＜リージョン名＞-＜乱数値＞`
例： `codepipeline-ap-northeast-1-?????????????/`

内容としては、githubからダウンロードしたファイルすべてや、ビルド実行で生成されたテンプレートファイルが、それぞれzipで圧縮されて保存される。各ステップでの入出力アーティファクト名でフォルダが内部に作られる。


## 関連するロール

-  `cloudformation-lambda-execution-role`

Staging ステージでのCloudFormationが動作するためのロール。予め開発者が準備するロール。`s3:GetObject` `lambda:*` `cloudformation:CreateChangeSet`など。

- `code-build-＜ビルドプロジェクト名＞-service-role`

CodeBuild が動作できるようにするためのロール。 `S3::auto-release-sample`へ `s3:PutObject`ができること。`codepipeline-ap-northeast-1-121111111111/`へ、`s3:PutObject` `s3:GetObject` ができることなど。

参考：
http://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/setting-up.html?icmpid=docs_acb_console#setting-up-service-role


- `AWS-CodePipeline-Service`

AWS CodePipeline が動作するためのロール。ポリシーの中身を見るに、`codecommit`や、`codedeploy` `elasticbeanstalk`, `autoscaling`など、今回やりたい処理以外の設定も入っているので、典型的な設定が全て入っているものと思われる。


- `＜スタックの名前＞-AutoReleasedLambdaRole-＜乱数値＞`

Lambda が実行されるときのロール。CloudFormationでLambdaが作成される際に自動的に生成される。`AutoReleasedLambdaRole`はおそらく固定文字列。
内容は、`AWSLambdaBasicExecutionRole` が付いているもの。（詳細未検証）

Lambdaの実行に色々なロール設定が必要な場合は別途用意必要かも。（未検証）（予め用意するか、CloudFormationのテンプレートに設定するか）
ローカルでDNSのタイムアウトをテストする

http://blog.livedoor.jp/xaicron/archives/51759149.html

こちらの記事でperlで指定した秒間sleepするDNSサーバーを立ち上げるっていうのがあって、タイムアウトを確認したいだけならUDPの53ポートをlistenすれば良さそう。

```shell-session
$ sudo nc -u -l 53
```

後は/etc/reslove.confを編集すれば良いんだけど、OSXの場合はネットワーク設定から変更する必要がある。

<img width="668" alt="スクリーンショット 0029-09-26 21.45.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/974/c2166c28-fb01-1a1f-fbf7-583fe7d95f14.png">
[WIP] Rails + Webpacker + Vue + Jestのためのテスト環境構築

Rails + Webpacker + Vue + Jestでテスト環境を作りました
とりあえず環境ができるとこまでをメモがわりに

## Install

- install jest
`docker-compose run --rm app bin/yarn add jest --dev`

- babel用のライブラリを追加
`docker-compose run --rm app bin/yarn add babel-jest babel-polyfill --dev`

- 設定追加
  - touch `vendor/package.json`

    ```json
    {
      "jest": {
        "testPathDirs": ["<rootDir>/../app/javascript/packs"],
        "moduleDirectories": ["<rootDir>/node_modules"],
        "moduleFileExtensions": ["js", "vue"]
      }
    }
    ```

  - edit `package.json`

    ```json
    ...
    "scripts": {
      "test": "./node_modules/.bin/jest"
    }
    ```

とりあえずFailできるとこまで動いた

```
# bin/yarn test
yarn test v0.27.5
$ ./node_modules/.bin/jest

// なんか色々エラー

Test Suites: 8 failed, 8 total
Tests:       0 total
Snapshots:   0 total
Time:        13.825s
Ran all test suites.
error Command failed with exit code 1.
```

## 動作確認用のコード

```javascript
// app/javascript/packs/sample.js
function sum(a, b) {
  return a + b
}

module.exports = sum
```

```javascript
// app/javascript/packs/test/sample.test.js
const sum = require('../sample.js')

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3)
})
```

## 動くようにライブラリ・設定追加

- add jest preprocessor
`docker-compose run --rm app bin/yarn add jest-vue-preprocessor --dev`

```json
{
  "jest": {
    ...
    "moduleNameMapper": {
        "^vue$": "vue/dist/vue.common.js"
    },
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
      ".*\\.(vue)$": "<rootDir>/node_modules/jest-vue-preprocessor"
    }
  }
}
```

## :tada: Pass! 

```
bin/yarn test app/javascript/packs/test/
yarn test v0.27.5
$ ./node_modules/.bin/jest "app/javascript/packs/test/"
 PASS  app/javascript/packs/test/sample.test.js
  ✓ adds 1 + 2 to equal 3 (3ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.552s
Ran all test suites matching /app\/javascript\/packs\/test\//i.
Done in 37.26s.
```

## Todo

- Vueのコンポーネントテスト
- `yarn test`にディレクトリ指定を渡さなくてもよくしたい

### 参考文献
https://github.com/pstjean/webpacker-jest
https://hackernoon.com/jest-for-all-episode-1-vue-js-d616bccbe186
https://facebook.github.io/jest/docs/en/webpack.html
https://alexjoverm.github.io/2017/08/21/Write-the-first-Vue-js-Component-Unit-Test-in-Jest/
Rubyの良さについて

いにしえの言語であるCとFortranしか使ったことのなかったWeb未経験者が、実際にRubyを使ってみて感じたメリットなどや調べたものをまとめる。

#Rubyとは？
RubyはしばしばWebプログラミングに使われる言語である。開発者のまつもとゆきひろ氏は大学時代からプログラミングそのものに興味を持っていた。彼には私自身もセミナーでお会いしたことがあるが、とても気さくで親しみやすく、一方でとても情熱を持った方であった。

>開発者のまつもとゆきひろは、「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミングを楽しむことである (enjoy programming)」と述べている。

>[Ruby - Wikipedia](https://ja.wikipedia.org/wiki/Ruby)

#Rubyの良さ
- オブジェクト指向である
- 括弧がなくても良い、無限ループとしてwhileやloopのどちらを使っても良い、%記法が使えるなど文法に自由度が聞く
- RubyonRailsやSinatra、Padrinoといった便利なフレームワークがある
- ライブラリが豊富である
- ググれば大概解決する
WindowsにPostgreSQL対応のSonarQubeをインストールする方法

## 1. はじめに
Windowsに静的ソースコード解析を行うSonarQubeサーバをインストールする方法と、そのリポジトリとしてPostgreSQLを利用するように変更する方法について説明します。
なお、SonarQubeの初期状態はインメモリデータベースのh2dbを利用します。

### 1.1. 検証環境
* Java 1.8.0_131
* SonarQube 5.6.6

## 2. インストール手順
### 2.1. 資材のダウンロードとインストール
https://www.sonarqube.org/downloads/ からSonarQubeのZipファイルをダウンロードします。今回は「`sonarqube-5.6.6.zip`」としました。
インストールはダウンロードしたZipファイルを展開すれば完了です。
ここでは`C:\work`にインストールすることにします。

### 2.2. 起動と停止
`{SonarQubeのインストールディレクトリ}/bin`にOS種別毎のディレクトリがあります。例えば64bit版Windowsの場合は「`windows-x86-64`」ディレクトリになります。起動、停止等のスクリプトはここに格納されています。

例）windows-x86-64　起動、停止のスクリプト

| 項番 | スクリプト | 説明 |
|:----:|:---------|:-----|
| 1 | InstallNTService.bat |SonarQubeサーバをWindowsのサービスとして登録する |
| 2 | StartNTService.bat |SonarQubeのサービスを開始する |
| 3 | StartSonar.bat |SonarQubeサーバを通常のプロセスとしてコマンド実行する |
| 4 | StopNTService.bat |SonarQubeのサービスを停止する |
| 5 | UninstallNTService.bat |登録されているSonarQubeのサービスを削除する |
| 6 | wrapper.exe |Javaのラッパー |

今回はコマンドプロンプトから「`StartSonar.bat`」スクリプトを実行して、SonarQubeサーバを起動します。

```console:SonarQubeサーバの起動
C:\work\sonarqube-5.6.6\bin\windows-x86-64>StartSonar.bat
wrapper  | --> Wrapper Started as Console
wrapper  | Launching a JVM...
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
jvm 1    |   Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved.
... 省略 ...
jvm 1    | 2017.09.25 20:39:02 INFO  app[o.s.p.m.Monitor] Process[ce] is up
```

Webブラウザで http://localhost:9000/ にアクセスして、トップ画面が表示されれば正常にインストールされています。
ちなみに、トップ画面の下部にデフォルトの組み込みDBは評価目的で利用してね、という警告メッセージが表示れていると思います。

```
Embedded database should be used for evaluation purpose only
The embedded database will not scale, it will not support upgrading to newer versions of SonarQube, and there is no support for migrating your data out of it into a different database engine.
```

**SonarQubeサーバを終了させるには、起動させたコマンドプロンプトでCtrl+Cで終了します。**

## 3. PostgreSQL対応
### 3.1. リポジトリとして利用するデータベースの準備
SonarQubeのリポジトリとして利用するデータベースを作成します。スキーマの構築はSonarQubeが実施してくれるため、データベースとアクセスできるユーザを作成するだけです。

| 項番 |	項目 | 値 |
|:----:|:----|:---|
| 1 | ポート番号 | 5432 |
| 2 | データベース名 | sonarDb01 |
| 3 | ユーザID | sonarUser |
| 4 | パスワード | sonarPass |

### 3.2. コンフィグレーションの修正
準備したデータベースにアクセスするため`{SonarQubeのインストールディレクトリ}/conf/sonar.properties`を修正します。

```properties:sonar.properties（14,15行目）
（修正前）
#sonar.jdbc.username=
#sonar.jdbc.password=
↓
（修正後）
sonar.jdbc.username=sonarUser
sonar.jdbc.password=sonarPass
```

```properties:sonar.properties（36行目）
（修正前）
#sonar.jdbc.url=jdbc:postgresql://localhost/sonar
↓
（修正後）
sonar.jdbc.url=jdbc:postgresql://127.0.0.1:5432/sonarDb01
```

### 3.3. 動作確認
先程と同様に`StartSonar.bat`でSonarQubeサーバを起動した後、Webブラウザで http://localhost:9000/ にアクセスします。
トップ画面を確認すると警告メッセージはなくなり、画面下部のフッターが以下のように表示されると思います。

```
SonarQube™ technology is powered by SonarSource SA
Version 5.6.6 - LGPL v3 - Community - Documentation - Get Support - Plugins - Web API 
```

## 4. さいごに
WindowsにSonarQubeサーバをインストールする方法と、リポジトリとしてPostgreSQLを利用するように変更する方法について説明しました。
通常のシステム開発ではCIにて静的ソースコード解析を実行し、その結果を保持し続けるため、デフォルトのh2dbを利用することはほぼありません。
今回はPostgreSQLを利用しましたがMySQLやOracle、SQL Serverにも対応していますので、開発システムで利用するRDBMSをリポジトリとして利用することをお勧めします。
Windows10 +  python3 + logger  でログファイルの出力にUTF-８を使うよう指定する

python3 の初心者がてこずったので、メモしておく。
　（2017.09.26記 2018.11.10書き直し）

### 対象読者
Windows10にもpython3にも慣れていないが、pythonでloggingモジュールを使いたいぐらいにはpython経験のある人

### 環境
OS：Windows10
Python処理系：　Anaconda4でインストールしたpython3.6.0

### おこなったこと
loggingモジュールのFileHandlerオブジェクトに文字コードを指定する。

やりかたは２つある

1. 実行するスクリプト内に直接記述する
1. loggingモジュールの設定ファイル内に記述する

* １の例

　 FileHandler オブジェクトをつくるときの引数に encoding='utf-8' と指定する

```py3
from logging import getLogger, FileHandler, Formatter, INFO, WARN

logger = getLogger("logger")

handler = FileHandler(filename="test.log", encoding='utf-8')
handler.setLevel(WARN)
handler.setFormatter(Formatter("%(asctime)s %(levelname)8s %(message)s"))

logger.addHandler(handler)

#出力処理
logger.debug("debug あいうえお")
```

* ２の例

loggingモジュールの設定ファイルをsample_logging.conf とする。そのなかのfileHandlerの設定を次のようにする

```text:sample_logging.conf
[handler_fileHandler]
class=FileHandler
formatter=simpleFormatter
args=('%(logfilename)s', 'w', 'utf-8')
```
args= で始まる行が、1の例のFileHandler オブジェクトをつくるときの引数に相当する
この設定ファイルを使うスクリプトは以下のようになるはず。（logging.configを使い設定ファイルを読んでいる）


```py3
import logging
import logging.config


if __name__ == '__main__':
    logging.config.fileConfig("sample_logging.conf", \
        defaults={'logfilename': 'logs/sample.log' })

```



### （蛇足）このメモを書いた理由
Windows でPython3を使うときの常識として
「テキストファイルを作成するとそのファイルの文字コードはWindowsの文字コード（cp932）となるのがデフォルト」
がある。

何も考えずに python3 on windows で次のようなスクリプトを実行すると

```py3
# -*- coding: utf-8 -*-# python3 でテキストファイルを出力するテスト

s = 'あいうえお'

with open('tmp.txt', 'w') as f:
    f.write(s)
```

作成されたテキストファイル　tmp.txt の文字コードはcp932 となる。
Windowsに慣れていない人はこれをSublimeTextなどで開くと文字化けするので驚く。
（慣れていない人はWindowsのメモ帳は自動判別するので文字化けしないが、SublimeTextなどは自動判別なんてしない、とかいう基本的なことを知らなかったりする）

pythonスクリプトで出力ファイルの文字コードをUTF-8にしたいときは明示的に指定する必要がある。

例えば以下のようにする。

```py3

# -*- coding: utf-8 -*-
# python3 でテキストファイルを出力するテスト
import codecs

s = 'あいうえお'

with codecs.open('tmp8.txt', 'w', 'utf-8') as f8:
    f8.write(s)
``` 


（私は以上のことを知らなかったのでいきなり自作pythonスクリプトのログファイルが文字化けするのを見て？？？となったのだった。
ネットを検索して初めて知り、なるほど、ではログファイルの出力でも同様の指定をすればよいのだろう、どこでどう指定すればよいのか？となった。
すぐにはピタッとした例がヒットせず、あちこちさまよった末にやりかたがわかったので、ここに結果だけシンプルにメモしておこうと思った次第。）
ちょっとずつ読むドメイン駆動設計 第ニ部 モデル駆動設計の構成要素 第四章 ドメインを隔離する8

# アンチパターン 利口なUI(スマートUI)

言うまでもなくアンチパターンとして紹介されていますが、実はこの章では、同時にドメイン駆動設計の難点や利口なUIとは別のアンチパターンも紹介されていました。

## ドメイン駆動設計の難点

- 習得が難しい
- 各レイヤを管理するオーバーヘッド
- 専門家の手が必要
- 単純なプロジェクトでは効果が薄い

熟練したチームであればオーバーヘッドの時間は縮められます。

## いつの間にか利口なUIになってることも

利口なUIとは、ビジネスロジックをユーザーインターフェイスに入れてしまうパターンです。
アンチパターンとして紹介されてますが、それがわかっていてもいつの間にか、ユーザーインターフェスにビジネスロジックが入ってしまっていることもあるかも。

テンプレートエンジンを使用しているときなど、htmlの中にifやforが入っていたらそこが危険ですね。ifの条件にビジネスロジックが入っていたり、forで繰り返すリストの取得方法が入っていたり・・・

## 利口なUIの利点

**単純なアプリケーション**であれば、すぐに作れて、有能でない開発者でも作れるし、プロトタイプから要件を引き出し変更することも可能です。また、RDBとの統合も機能して、保守する際も、特定の画面だけいじればいいので素早く作り替えが可能です。

## 利口なUIの末路

利口なUIで作成されたアプリケーションはそれ以上は成長できないです。
最初は作って終わりの予定であったアプリケーションでもその多く利用され続け、要件は追加され、複雑さを増していくことが多いと思います。
そういうアプリケーションは

- ビジネスルールは再利用できず、適用先にコピペすることになる(経験ありますねぇ)
- 複雑さを増したため、あとからドメイン駆動設計を適用しようとした場合は、リファクタリングではなく、完全に作り直しになる。(こちらも経験ありますねぇ)

なので、ドメイン駆動設計でアプリケーションを作成する場合は**始めから**適用しなければならないということです。

## プロトタイプ用途ではどうか

先ほど、利口なUIであれば素早く作ったプロトタイプから要件を引き出し変更することも可能とありましたが、これもすぐに限界が来るはずですよね。

プロトタイプやイテレーションを利用して徐々に複雑にしていこうと思うのであれば、やはり初めからドメイン駆動設計を適用する必要があると思います。

絶対に捨てる前提であれば有りかもしれませんが、勇気が必要なのと、プロトタイプから要件は引き出せるが、プロトタイプを作っている間は対象のドメインについての学習はできません。その兼ね合いはとても難しそうですね。


## 他のアンチパターン　トランザクションスクリプト

利口なUIとドメイン駆動設計の間のパターンとして、**トランザクションスクリプト**を上げています。
つまり、ユーザーインターフェイスとアプリケーションは分離するけど、ドメインモデルは作らないというパターンです。

このパターンであれば、まだ、将来的にドメイン駆動設計に移行できるかもしれないと言っています。
ドメイン駆動設計に移行するには、アーキテクチャがドメインに関するコードを分離していて、"凝集度が高いドメインの設計"と"システムの他の部分"が疎結合である必要があります。それができていればトランザクションスクリプトでも"おそらく"・・・ということです。
[Git]制限のある100MG以上のプッシュをしてしまって、プッシュができなくなった場合

<h1>起こったこと</h1>
Unityでそこそこサイズのでかいものをインポートしたり、そのアセットを使ったりして、一区切りついたしプッシュするかって思ってプッシュしたら、エラーが出た。
ファイルサイズの大きいものがありますよっていう部分は、僕の場合はこの二つがあった。

remote: warning: File <font color="DeepPink">Assets/MyAssets/Subway Set/Textures/RubbleNormalsMap.tga</font> is 64.00 MB; this is larger than GitHub's recommended maximum file size of 50.00 MB
とか、
remote: error: File <font color="DeepPink">Library/metadata/18/18ec2d52be8f4524a97c25a2ed27838e</font> is 128.01 MB; this exceeds GitHub's file size limit of 100.00 MB

制限以上のプッシュしてしまったって思ってローカルのファイルを削除しても意味がないのでエラーは変わらない。でかいサイズをプッシュしようとした履歴が残ってしまうのが原因。

<h1>解決方法</h1>
～簡単にまとめると～
1. ローカルで問題のあるフォルダを削除
2. addしてcommit
3. 以下のコマンドを入力
4. 3.push

～詳しく～
エラー文の中にいくつか「remote:～」と表示されると思うが、サイズをオーバーしてますよって書いてある行だけを注目しましょう。
僕の場合は二か所ありました。

上記のエラー文の中での、
<font color="DeepPink">「Assets/MyAssets/Subway Set/Textures/RubbleNormalsMap.tga」</font>
と
<font color="DeepPink">「Library/metadata/18/18ec2d52be8f4524a97c25a2ed27838e」</font>
の部分がその問題のあるディレクトリです。(僕の場合)

以下のコマンドを入力しましょう。

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch 問題のあるディレクトリ" --prune-empty -- --all

僕は二つあったので、二回このコマンドを入力しました。
コマンドを打つとRewrite～と出る。出た後にWARNING～といくつか出るが気にしなくていい。

後は、addしてプッシュ

これで、プッシュできました。

<h1>感想</h1>
プッシュできるファイルサイズの制限があることは知っていたのですが自分がこの問題に遭遇することは今までなかったので、解決に少し時間がかかりました。
今度からこまめにプッシュするように意識する、インポートしたアセットのサイズを気を付ける、
この二つは忘れないようにしようと思いました。

コミットを取り消して、複数回に分けてプッシュしても解決できますね。
モンテカルロ法による円周率計算の本当の期待値

# 概要

モンテカルロ法による円周率計算はプログラミングや統計の練習問題としてよく出てくる。

試行回数$n$を大きくしていけば円周率$\pi$にだんだん近づくよね、というのがよくある結論だけど、浮動小数点型はあくまで離散値だから、本当の期待値は円周率$\pi$とは異なるのでは？という疑問が湧いた。

既に誰かが計算しているだろうと思ったのだが、ざっと検索して見つからなかったので、厳密な期待値を計算してみた。

## 方針

* 乱数生成器が$[0,1)$の浮動小数点数を生成するとき、実際には整数の乱数生成器を回して得たビット列
を浮動小数点型数の仮数部に放り込んだあと正規化している
から(仮数部+1)ビット分を使い、除算して得ている、とする。
* IEEE754 単精度浮動小数点型の場合の精度は24ビットなので、「$[0,1)$の範囲で一様分布する単精度浮動小数点数$x$、$y$を使って$x^2+y^2<1$となる点の個数をカウントする」のは、「$0$から$2^{24}-1$まで一様分布する整数$X$、$Y$のうち$X^2+Y^2<(2^{24})^2$となる点の個数をカウントする」のと同じ。
* ゴリ押しで格子点の個数を数えれば、本当の期待値になるはず。

乱数生成器は真の乱数を生成するものと仮定します。標準の`rand()`ではなくメルセンヌ・ツイスタなどの品質の良い擬似乱数生成器を使えばいいはず。

## ソースコード

精度が1ビットから24ビットまでの場合を計算。

~~~c:montecarlo.c
#include <stdio.h>
#include <math.h>

unsigned long long int f(unsigned long long int n){
  unsigned long long int i;
  unsigned long long int s = 0ll;
  unsigned long long int n2 = n * n;
  
  for(i = 0; i < n; i++){
    s += (unsigned long long int)floor(sqrt(n2 - i * i));
  }
  return s;
}

int main(){
  for(int k = 1; k <= 24; k++){
    printf("%d:%llu\n", k, f(1ll << k));
  }
}
~~~

## 計算結果

~~~
1:3
2:12
3:49
4:199
5:802
6:3213
7:12858
8:51465
9:205868
10:823524
11:3294182
12:13176730
13:52707104
14:210828591
15:843314616
16:3373259042
17:13493037215
18:53972150301
19:215888602681
20:863554412457
21:3454217650622
22:13816870607410
23:55267482435267
24:221069929749811
~~~

## IEEE754 単精度浮動小数点型(float)の場合

期待値は下記となる。

$$
221069929749811 \times \frac{4}{{(2^{24})}^2} = \frac{221069929749811}{70368744177664}
$$

これは$3.141592653574477\cdots$なので、小数点以下10桁まで$\pi$と一致する。

## IEEE754 倍精度浮動小数点型(double)の場合

倍精度では精度が53ビット。上記のプログラムでは27ビット以降はdoubleにキャストして減算するときに誤差が入ってしまう。

キャストが発生する`floor(sqrt(n2 - i * i))`の部分は、平方根の整数部を求めるだけで良いので、整数演算だけで実装するのはできそう。

だが時間がかかりすぎる(私の環境では31ビットのときの計算に約15秒かかったので、53ビット目を計算するのにかかる時間は約2年)問題は、ちょっと解決できそうにないので諦めた。別のアプローチが必要かも。

## ちなみに・・・

$X^2 + Y^2 = (2^n)^2$となる自然数$X, Y, n$の組は存在しないので、モンテカルロ法で$x^2 + y^2 < 1$をカウントするのと、等号を含めた$x^2 + y^2 \leq 1$をカウントするのは、数学的には同じ結果になる。

## そもそも・・・

「確率的に」「近似値」を求める方法の厳密な期待値なんて計算する意味あるの？と言われると・・・

# とりあえず結論

* float型で実装したモンテカルロ法の期待値は$\pi$ではなく$\dfrac{221069929749811}{70368744177664}$
* double型の場合の期待値を求めるのは諦めた
* $x^2 + y^2 < 1$をカウントするのと、等号を含めた$x^2 + y^2 \leq 1$をカウントするのは同じ
[iOS 11.1修正済] iOS 11のUIWebViewではtouch系イベントで動画を再生できない

###### 2017/09/28追記

iOS 11.1にて修正されていることが確認されました。

以下の内容は古い情報です。

# 状況
モバイル系OSのブラウザでは、通常単純にJavaScriptから動画再生処理を行っても再生されない。

再生するためには、下記のようにユーザーアクションによるイベントから再生処理を行う必要がある。

> In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.
https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html

しかし、例えば下記のコードのようにユーザー起点と思われるtouchstart, touchendなどのtouch系イベントでは、iOS 11のUIWebView限定で再生処理を行っても再生されなくなってしまった。

```javascript
playArea.addEventListener("touchend", ev => {
  videoElement.play();
});
```

以下のような処理だと再生される。

```javascript
// 無難にclick
playArea.addEventListener("click", ev => {
  videoElement.play();
});

// mouseupでも動いた
playArea.addEventListener("mouseup", ev => {
  videoElement.play();
});
```

恐らくバグだと信じているので、Appleにはバグ報告を送った。

##### 2017/9/27追記
iPadだけの問題の様子

# 教訓
UIWebViewはバグが放置されがちだから早急にWKWebViewに乗り換えるべきと思われる
数式, TeX 混じりの文章を書く方に軽く見て欲しい文献

#　本日は
Qiita に限ったことではないが，数式をTeXで書く人に軽く読んで欲しいリファレンスのご紹介．

##　Qiitaで数式をどうやって書くの？

- [Qiitaの数式チートシート](https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada)
- [amsmathの数式環境まとめ](https://qiita.com/t_kemmochi/items/a4c390b4967b13f3afb7)

のようなリファレンスがあるので参考にして見てください．よくまとまっております．
Qiitaでは数式を[MathJax](https://www.mathjax.org/)を用いて数式を表記するらしいので

- [MathJaxの使い方(http://www.eng.niigata-u.ac.jp/~nomoto/download/mathjax.pdf)](http://www.eng.niigata-u.ac.jp/~nomoto/download/mathjax.pdf)
- [MathJaxの使い方(http://genkuroki.web.fc2.com/)](http://genkuroki.web.fc2.com/)
- [Easy Copy MathJax](http://easy-copy-mathjax.xxxx7.com/)

なども参考になります．可換図式もかけるらしいです．

- [Qiitaで可換図式を描く](https://qiita.com/karrym/items/72d380fb014c5f959cbe)

## この記事をわざわざ書いた理由

書き方HowToを教えないのになんでこんな記事を書いたかと言いますと，ローマン体（立体）の慣習の無視した表記をしている人が意外にも多いからです．
例えば典型的な例として三角関数, 対数関数の数式が混じった式で

```math
sin^2x+cos^2x=1
```

```math
ln(ab)=lna+lnb
```

というようなことをする人がかなり多くいます．

これに疑問を感じない方は是非こちらを読んでいただきたい：

- [数学の常識・非常識—由緒正しい TEX 入力法](https://www.math.tohoku.ac.jp/tmj/oda_tex.pdf)

全部で18ページありますが，とりあえず3ページまで読んで欲しいです．この文献の存在を知っているかそうでないかでTeXに対する感じ方が違ってきます．著者は数学専門の方です．数学を専門とする学生，特に大学院修士以上の人を対象としたTeXの指導文献には必ずと言って良いほどこれを文献として多く引用しています．
例えば

- [数学論文の書き方第１回：入門編](https://www.math.kyoto-u.ac.jp/~arai/latex/presen1.pdf)

- [論文作成に関する注意](http://www.math.sci.osaka-u.ac.jp/~ochiai/ronbunsakusei.html)

などがそうです．

数学を専門としない人々から見ると堅苦しく聞こえると思いますが，TeXをソースコードと見たときのコード規約に相当する概念だと思っていただくと”なるほど”と思っていただけるでしょう．

追記しましたー＞　[TeX スタイルガイド（文献紹介のみ）](https://qiita.com/SatoshiTerasaki/items/c2b1da3203034c539aca)


# 最後に
単に知ってないだけだと思いますが，技術者向けにTeXの作法を書いている文献がネットではなく紙媒体であってもいいと思うんですよね．出版社さん是非お願いします．
Know More about the Shiba Inu Breed

<p>Numerous surveys have shown that having an animal companionship can give the best feeling in life. Talking about dogs, they can be considered as the man's best friend that not only share affection, but also offer their helping nature in their own ways. Owning a dog can provide you emotional, physical as well as social benefits. All the breeds of dog are super cute and adorable, but <b>Shiba Inu</b> is the most famous amongst all.</p>

<p>Everyone wants someone to care for them, and bringing <b>Shiba Inu</b> at your home can fulfill your this particular wish. They can make you feel safe as well as make you enjoy in their fulfilled companionship. Many elderly couples, with no grandchildren or kids at home, feel loneliness in their lives. As Shiba Inu is a loyal, active and an adorable breed of dog, bringing it at your home can lift your mood and make you feel overjoyed. Apart from the aforementioned facts, spending time with Shiba Inu is also beneficial for those, who are experiencing depression, trauma or any mood disorders. In such stressful conditions these flurry friends can help people improve their quality of life and stay active.</p>

<p>Talking about social aspects of having <b>Shiba Inu</b> as the most adorable flurry friend, they can create a great sense of closeness and happy living. Most of the families surveyed before and after adopting Shiba Inu, have reported feeling happier and safer. Also, having it can allow you remain physically more active. Apart from feeding, grooming and caring, you can also stay active by taking them for a walk. In this way, <b>Shiba Inu</b> can positively transform your daily lives and gives you something to look forward and work every day.</p>

<p>But before bringing <b>Shiba Inu</b> to your home, you should collect all the information and the tips for their proper health care. There are certain sources available on internet where you can find all you need to know about Shiba Inu health care, Shiba.pro is one such reliable name in them. From feeding them to managing their routine, this website offers you all the important tips and facts about your <b>Shiba Inu</b>.</p>

<p><b>About Shiba.pro:</b></p>

<p>Shiba.pro is the most popular source where you can find all the relevant information about <b><a href="https://www.shiba.pro/">S</a><a href="https://www.shiba.pro/">hiba Inu</a></b>, their likes, dislikes and character. With the help of this source, it becomes easy to train it in a proper manner.</p>

<p>To know more, you can visit <b><a href="https://www.shiba.pro/">S</a><a href="https://www.shiba.pro/">hiba.pro</a></b>.</p>
git-svnでコミットする

あまりやらなくて忘れてしまうのでruby/rubyにコミットする時の最低限の情報をメモしておく。

## git-svnのスナップショットを持ってくる
一からgit-svnの用意をするのは時間がかかりすぎて非現実的なので、 `wget https://svn.ruby-lang.org/ruby-svn.tar.gz` をやる。

解凍したリポジトリを ~/src/github.com/ruby/ruby-svn とかに置いておく。

## svnリポジトリにsshできるようにしておく
`ssh -T svn.ruby-lang.org`とかできるようにしておく。

```
Host svn.ruby-lang.org
  HostName svn.ruby-lang.org
  Port 22
  User svn
  IdentityFile ~/.ssh/id_rsa.ruby
```

### git-svnのスナップショットのsvn-remote.svn.urlの確認
`git config -l`とかやると`svn-remote.svn.url=svn+ssh://svn@svn.ruby-lang.org/ruby`とかになっている。なので`ssh -T svn@svn.ruby-lang.org`が通る必要がある。

## git-svnのインストール
```
sudo apt install git-svn
```

## git svn rebase
```
git svn rebase
```

`git pull`相当の操作がgit svn rebaseになる。

## git svn dcommit
```
git svn dcommit
```

trunkブランチを`git svn rebase`で最新にした後、ローカルで普通に`git commit`した後`git svn dcommit`をするとsvnリポジトリにコミットされる。
【メモ】$.Deferred() を順次実行したい

たとえばsetTimeoutで１秒ごとの処理を順次実行したい場合、よくあるサンプルを元に$.Deferredで書くと、以下の実行結果が１秒後に全部表示されてしまいました。

```
delay:0
delay:1
delay:2
delay:3
delay:4
tasks done.
```
やりたいのは0〜4までを１秒ごとに（確実に完了してから）実行すること。
以下のように書いたら解決しました。

```js
    // 順次実行したいメソッド
    var delay = function (param) {
        return function(){
            var $deferred = new $.Deferred();
            setTimeout(function(){
                console.log('delay:'+param);
                $deferred.resolve();
            }, 1000);

            return $deferred.promise();
        }
    };

    // タスクを詰め込むDeferredを用意
    var tasks = (new $.Deferred()).resolve();

    // タスクを登録
    for(var i = 0; i < 5; i++){
        tasks = tasks.then(delay(i));
    }

    tasks.done(function(){
        console.log('tasks done.');
    });

```
ポイントはdelayをreturn functionで返す点。
普通に書いてしまうと `tasks.then(delay(i))` の時点で実行されてしまうので１秒後に0〜4が一気に実行されてしまいました。

まあ当然といえば当然ですがこれに気がつくのに非常に時間が掛かったのでメモ。
HomesteadによるLaravel環境構築


## Homesteadとは
　LarvalのためのVagrantのBOX。
Homesteadでは、Laravelに必要なPHPモジュールやライブラリがあらかじめ用意されており、素早くLaravelの仮想環境を構築できる。自動的にSSL証明書も発行してくれるので、最初からHTTPS環境でもアクセスできる。（警告はでるが）

### Homesteadがインクルードしているソフトウェア

* Ubuntu
* Git
* PHP 
* Nginx
* MySQL
* MariaDB
* Sqlite3
* PostgreSQL
* Composer
* Node (With Yarn, Bower, Grunt, and Gulp)
* Redis
* Memcached
* Beanstalkd
* Mailhog
* ngrok


## インストール手順
　Homestead環境の構築方法には、2つある。

* グローバルで構築する方法
* プロジェクト毎に構築する方法

　グローバルにインストールすると、プロジェクト間で予期せぬ汚染を招きそうなので、ここではプロジェクト毎に構築する方法を説明する。


**前提**

* Virtual BOX, Vagrantやcomposer等、Vagrant環境を構築するのに必要なツールはすでにインストール済みであること


### HomesteadのVagrant BoxをVagrantのリストに追加する

```bash
vagrant box add laravel/homestead
```


### プロジェクト毎にインストール
　環境を構築したいディレクトリを作成し、composerでインストール。

```bash
mkdir /Users/yumataesu/Sites/yout_site
cd yout_site
composer require laravel/homestead --dev
```

### vagrant fileとHomestead.yamlを生成する
Mac / Linuxの場合

```bash
php vendor/bin/homestead make
```

Windowsの場合

```bash
vendor\bin\homestead make
```


### Vagrant起動

```bash
vagrant up
```

http://homestead.app でアクセスできるか確認。
ドキュメントルートは空なので、 **NginxのNo input file specified.というエラーメッセージがでる。**Larval自体は、手動でインストールする必要がある。


### Homestead.yamlを編集し、Larvalをインストール
　homestead.yamlはHomesteadの設定ファイル。
ここを編集してゲストマシンとホストマシンのディレクトリを同期設定をする。

* mapは、ホストマシン側で同期したいディレクトリを指定する。（ここでは、rakufile内にwebというディレクトリを作成した）
* toは、ゲストマシン側で同期したいディレクトリを指定する。

```:Homestead.yaml
folders:
     -
         map: /Users/username/Sites/myhomestead/web
         to: /home/vagrant/Code
```


### 仮想環境へログインし、共有ディレクトリまで移動する
```bash
vagrant ssh
cd /home/vagrant/Code
```

### 2017年9月26日現在の5.5.X系では、Laravelをインストールする前にcomposerのアップデートが必要
```bash
composer global update
```

### Laravelをインストール
```
laravel new
```

これで、http://homestead.app でアクセスするとLaravelのHello Worldが表示される。

![スクリーンショット 2017-09-26 13.10.45.png](https://qiita-image-store.s3.amazonaws.com/0/104234/8d43d2e0-7514-612c-15fc-8833e337aac5.png)



### アクセスするドメインを変更する場合
#### homestead.appを変更する場合、Homestead.yamlのsitesプロパティを編集する。

* map:アクセスするドメインの設定
* to:ゲストマシンNginxのドキュメントルートの設定

```Homestead.yaml
sites:
    -
        map: myhomestead.app
        to: /home/vagrant/Code/public
```
仮想マシンのNginx設定を更新するため以下を再実行する

```
vagrant reload --provision
```

#### hostファイルも更新する
　仮想マシンのIPは、Homestead.yamlのipプロパティを確認。

```:hosts
192.168.10.10 myhomestead.app
```
HTTPSの静的コンテンツをホストするならs3よりNetlifyが俺の求めていたものだった

# 事の発端
社内から静的コンテンツをホストしてHTTPS使える環境が欲しいんだよねー。と要望を受けた。
私はAWSが得意なので考えた。

「静的コンテンツならs3か」
「s3でHTTPSならs3の前段にCloudFrontでSSL証明書入れるか（ちょっと面倒だな）」
「CloudFrontにSSL入れるなら無料のACMだな」
「ACM使うならメール認証だしSES要るな（面倒くせぇ）」
「SESでメール受信するならs3・・・・・・・・・・」
### ガシャーン！（ちゃぶ台の音）
### 「俺がしたいのはこれじゃない感」

# ということで
何か上の環境を一発で作れるツールあるかなぁ。と調べているとNetlifyというサービスが引っかかった。

# Netlifyってなに？
どうも静的コンテンツをホストしてくれて、SSLが使えるとな。Githubと連携して？
ふむふむ。使ってみよう。

ということでGithubにリポジトリを作って5分位でデプロイ出来る環境が出来ました。
SSLとDNSも5分位で設定完了。

### 「俺が求めていたものはこれだった」


# Netlifyの紹介(検索したら色々出てくるけど)
## URL
https://www.netlify.com/

## ほどんどのことが無料
- 商用利用可
- カスタムドメインのHTTP
- CIによるデプロイ
- フォーム処理
- A/Bテスト
- コミュニティサポート
- etc...

## 有料版で出来ること
- チームや複数レベルの管理機能
- メールとチャットのサポート
- SOC2準拠
- などその他色々

## デプロイ
- Git系リポジトリと簡単に連動しpushするだけでデプロイ可能

## DNS
- 任意のDNSでも、NetlifyのDNSでも可

## SSL証明書
- 無料(Let's Encrypt)
- カスタムドメインも1ボタンで発行

## パフォーマンス
- 自動でCDN付き
- スケーラブルらしい（静的コンテンツだけだもんね）

## ABテスト(BETA)
- ワンクリックでGitのブランチ毎にABテストが出来る

## フォーム
- フォームはHTMLで作れる
- データベース不要
- メール、Slack、Webhookへ通知可能

## セキュリティ
- 有料版ではSOC2取ってるくらいだから強そう
- 基本静的コンテンツだけだからよっぽどじゃないと問題にならない？

## ちょっとした機能
- デプロイ履歴とログが残る


### 結論：めっちゃ簡単だったので使ってみてください
https://www.netlify.com/
メモdark_net_rosで座標の抽出

自分で表記を実行する場合の手順を示す

1.ROSCOREの起動
roscore

2.USBカメラの起動
rosrun usb_cam usb_cam_node /usb_cam/image_raw:=/camera/rgb/image_raw
カメラのセット
rosparam set usb_cam/pixel_format yuyv
2の手順の際に画像に遅れが発生する場合は画像のレート、幅の修正を行う
rosparam set usb_cam/framerate 20
rosparam set usb_cam/image_height 240
rosparam set usb_cam/image_width 320

3.darknetの起動
roslaunch darknet_ros darknet_ros.launch 

4.darknetの出力値の参照
rostopic echo /darknet_ros/bounding_boxes

GPUの稼働状況を把握するときは
sudo ~/tegrastats

参考文献
https://qiita.com/nnn112358/items/d696681d5b0577d633b6
不要なbranchを削除する(忘備録メモ)

##local

**branch一覧をみる**

```
$git branch
```

**mergeした不要なbranchの削除**

```
$git branch --delete 削除したいbranch名
```

##remote
**リモートbranch一覧の表示**

```
git branch --remote
```

**リモートとローカル全てのbranch一覧の表示**

```
git branch --all
```

**リモートbranchの削除**

```
git push --delete origin 削除したいbranch名
```
大中小項目番号を自動で振りたい(試験項目作成)

試験項目作成時とか、項番を自動的にインクリメントしたい
かつ、項目名が入っている場合だけとか

``` 大項目用数式.
=IF(ISBLANK(INDIRECT(ADDRESS(ROW()-1,COLUMN()+1,4))),
    IF(NOT(ISBLANK(INDIRECT(ADDRESS(ROW(),COLUMN()+1,4)))),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))+1,
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))
    ),
    IF(ISBLANK(INDIRECT(ADDRESS(ROW(),COLUMN()+1,4))),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4)),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))+1
    )
  )

```

``` 中小項目用数式.
=
IF(ISBLANK(INDIRECT(ADDRESS(ROW(),COLUMN()-1,4))),
  IF(ISBLANK(INDIRECT(ADDRESS(ROW()-1,COLUMN()+1,4))),
    IF(NOT(ISBLANK(INDIRECT(ADDRESS(ROW(),COLUMN()+1,4)))),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))+1,
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))
    ),
    IF(ISBLANK(INDIRECT(ADDRESS(ROW(),COLUMN()+1,4))),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4)),
      INDIRECT(ADDRESS(ROW()-1,COLUMN(),4))+1
    )
  ),
  1
)
```
Vagrantで共有フォルダの内容がリアルタイム同期されない件


どうやら素の状態では仮想マシン起動時に `rsync` で同期するだけのようです。

リアルタイムで同期させるには、VitualBoxの仮想マシンに `Guest Addtions` が必要みたいです。
`Guest Addtions` のインストールで少々嵌ったのでメモを残しておきます。

## 環境
- ホスト: macOS
- ゲスト: CentOS7（[公式サイトからダウンロードしたbox](https://app.vagrantup.com/centos/boxes/7/versions/1708.01)で作成）

## 依存パッケージをインストール

インストールの前に CentOS の `kernel` を更新しておきます。

```ゲスト側で実行
# yum update kernel -y
```

終了したら、依存パッケージをインストールします。

```ゲスト側で実行
# yum install kernel-devel gcc -y
```

終了したら、<font color="red">**必ず**</font>仮想マシンを停止させます。
停止しなかった場合、このあと実行する `Guest Addtions` のインストールが失敗します。

```ホスト側で実行
$ vagrant halt
```

## Guest Addtionsのディスクイメージをマウント

停止したら、VirtualBoxマネージャから対象の仮想マシンに光学ドライブを追加します（空のままでOK）。

![vbox_drive.png](https://qiita-image-store.s3.amazonaws.com/0/169798/102ebefe-0edf-3b37-081b-a97a31da072f.png "vbox_drive.png")

ドライブを追加したら、仮想マシンを起動させます。

```ホスト側で実行
$ vagrant up
```

起動したら、VirtualBoxマネージャから対象の仮想マシンのコンソールを起動し、メニューバーの`Devices`→`Insert Guest Addtions CD Image...`を実行します。

実行後に特にメッセージなどは表示されないので、そのままCentOS にディスクイメージをマウントします。

```ゲスト側で実行
# mkdir /mnt/cdrom
# mount /dev/cdrom /mnt/cdrom
```

## Guest Addtionsのインストール

環境変数を設定して、インストールスクリプトを実行します（環境変数の内容はバージョンにより可変）。

```ゲスト側で実行
# export KERN_DIR=/usr/src/kernels/3.10.0-693.2.2.el7.x86_64/
# /mnt/cdrom/VBoxLinuxAdditions.run 
Verifying archive integrity... All good.
Uncompressing VirtualBox 5.1.28 Guest Additions for Linux...........
VirtualBox Guest Additions installer
Copying additional installer modules ...
Installing additional modules ...
vboxadd.sh: Starting the VirtualBox Guest Additions.

Could not find the X.Org or XFree86 Window System, skipping.
```

最後の `Could not find the X.Org or XFree86 Window System, skipping.` は無視して構わない感じです。

## 共有フォルダをマウント

ひとまず、仮想マシンを停止させます。

```ホスト側で実行
$ vagrant halt
```

`Vagrantfile` に共有フォルダ設定を追加します。

```ruby:Vagrantfile
config.vm.synced_folder "../data", "/vagrant_data"
```

ちなみに共有フォルダ設定が追加されていない場合でも、`Vagrantfile` のあるフォルダが `/vagrant` にマウントされるようになっています。これはデフォルトで `rsync` で同期されるようです。
これをリアルタイム同期に変更したい場合は、`Vagrantfile` に下記の設定を追加します。

```ruby:Vagrantfile
config.vm.synced_folder ".", "/vagrant", type:"virtualbox"
```

仮想マシンを起動させます。

```ホスト側で実行
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...

(snip)

==> default: Rsyncing folder: /foo/bar/ => /vagrant
==> default: Mounting shared folders...
    default: /vagrant_data => /foo/bar/data
    
(snip)

```

```ゲスト側で実行
$ ll / | grep vagrant
drwxr-xr-x.   2 vagrant vagrant   25 Sep 26 07:11 vagrant
drwxr-xr-x.   1 vagrant vagrant  102 Sep 26 08:17 vagrant_data
```

このようにしてマウントされた共有フォルダは、双方向の変更がリアルタイムで同期されます。
PHPでEXIFのOrientationを元に画像を回転

EXIFのOrientationを見て画像を回転させる処理です。
訳あってPHP5系で実装しましたが、PHP7系でも動くと思います。

注意点としては、rotate()関数内でメモリを大量に使用するためmemory_limit()で上限を上げています。
「allowed memory size」が発生するケースもあったので、余裕をもって設定しましょう。
※ 1.7MBの画像で128MBを使い切ったケースがありました。

このあたりでメモリ使用量が一気に上昇します。
imagecreatefromstring()
imagerotate()
imagejpeg()
imagepng()
imagegif()


``` Image.php
<?php
class Image {

	/**
	 * 画像（バイナリ）のEXif情報を元に回転する
	 */
	public function rotateFromBinary($binary) {
		$exif_data = $this->getExifFromBinary($binary);
		if (empty($exif_data['Orientation']) || in_array($exif_data['Orientation'], [1, 2])) {
			return $binary;
		}
		return $this->rotate($binary, $exif_data);
	}

	/**
	 * バイナリデータからexif情報を取得
	 */
	private function getExifFromBinary($binary) {
		$temp = tmpfile();
		fwrite($temp, $binary);
		fseek($temp, 0);

		$meta_data = stream_get_meta_data($temp);
		$exif_data = @exif_read_data($meta_data['uri']);

		fclose($temp);
		return $exif_data;
	}

	/**
	 * 画像を回転させる
	 */
	private function rotate($binary, $exif_data) {
		ini_set('memory_limit', '256M');

		$src_image = imagecreatefromstring($binary);

		$degrees = 0;
		$mode    = '';
		switch($exif_data['Orientation'])
		{
			case 2: // 水平反転
				$mode = IMG_FLIP_VERTICAL;
				break;
			case 3: // 180度回転
				$degrees = 180;
				break;
			case 4: // 垂直反転
				$mode = IMG_FLIP_HORIZONTAL;
				break;
			case 5: // 水平反転、 反時計回りに270回転
				$degrees = 270;
				$mode    = IMG_FLIP_VERTICAL;
				break;
			case 6: // 反時計回りに270回転
				$degrees = 270;
				break;
			case 7: // 反時計回りに90度回転（反時計回りに90度回転） 水平反転
				$degrees = 90;
				$mode    = IMG_FLIP_VERTICAL;
				break;
			case 8: // 反時計回りに90度回転（反時計回りに90度回転）
				$degrees = 90;
				break;
		}

		if (!empty($mode))
		{
			imageflip($src_image, $mode);
		}
		if ($degrees > 0)
		{
			$src_image = imagerotate($src_image, $degrees, 0);
		}

		ob_start();
		if (empty($exif_data['MimeType']) || $exif_data['MimeType'] == 'image/jpeg') {
			imagejpeg($src_image);
		} elseif ($exif_data['MimeType'] == 'image/png') {
			imagepng($src_image);
		} elseif ($exif_data['MimeType'] == 'image/gif') {
			imagegif($src_image);
		}
		imagedestroy($src_image);
		return ob_get_clean();
	}
 }

```

``` php
// 使い方
$Image = new Image();
$binary = $Image->rotateFromBinary(file_get_contents($path_to_file));

```

## 参考URL
http://php.o0o0.jp/article/php-orientation
http://blog.diginnovation.com/archives/1104/
CentOS 7 で SQL Server 2017 の Docker を試す

## SQL Server 2017 on Docker
SQL Server 2017 RC2 の Docker イメージが [Docker Hub](https://hub.docker.com/r/microsoft/mssql-server-linux/) で公開されているので、CentOS 上の Docker で検証した。

パッケージインストールや詳細情報は「[SQL Server 2017 を CentOS 7.4 で試す](https://qiita.com/bezeklik/items/3f88046dd779e86029a2)」を参照。

## 検証環境
* VirtualBox 5.1.28
* CentOS 7.4.1708 (minimal)
    * Docker 17.06.2 (docker-ce-stable)
    * Docker Compose 1.16.1 (GitHub)
    * SQL Server 2017 (RC2) - 14.0.900.75 (Docker Hub) (microsoft/mssql-server-linux)

## Docker / Docker Compose
```bash
yum clean all && yum -y update && reboot
yum -y install epel-release && yum -y update && yum -y install yum-axelget
yum -y install yum-utils && \
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && \
yum -y install docker-ce && systemctl start docker && systemctl enable $_ && \
curl -o /usr/local/bin/docker-compose -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` && \
chmod +x /usr/local/bin/docker-compose
```

## docker-compose.yml
```bash
cat << "_EOF_" > docker-compose.yml && docker-compose up -d
version: '2'
services:
  mssql:
    image: microsoft/mssql-server-linux
    container_name: mssql
    hostname: mssql
    environment:
      ACCEPT_EULA: Y
      SA_PASSWORD: 'P@ssw0rd'
      MSSQL_PID: 'Developer'
      MSSQL_LCID: 1041
    ports:
      - '1443'
    volumes:
      - './sqlserver-data:/var/opt/mssql'
_EOF_
```
`environment` の `MSSQL_LCID` に `1041` を指定すると日本語版がインストールされる。

```bash
docker-compose ps
```
```
Name               Command               State                 Ports
----------------------------------------------------------------------------------
mssql   /bin/sh -c /opt/mssql/bin/ ...   Up      1433/tcp, 0.0.0.0:32772->1443/tcp
```
起動を確認。

## mssql-tools
```bash
yum -y install https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm && \
ACCEPT_EULA=Y yum -y install mssql-tools && \
ln -sv /opt/mssql-tools/bin/* /usr/local/bin/
```
CentOS から `sqlcmd` コマンドを実行したいので `mssql-tools` パッケージをインストールする。

## sqlcmd
```bash
sqlcmd -S `docker inspect -f '{{.NetworkSettings.Networks.root_default.IPAddress}}' mssql` -U SA -P 'P@ssw0rd' -Q "SELECT @@VERSION" -W
```
```

-
Microsoft SQL Server 2017 (RC2) - 14.0.900.75 (X64)
	Jul 27 2017 08:53:49
	Copyright (C) 2017 Microsoft Corporation
	Developer Edition (64-bit) on Linux (Ubuntu 16.04.2 LTS)

(1 rows affected)
```
CentOS から mssql コンテナにリクエストを投げて値の取得が成功。
分析サーバーでjupyter notebookを起動してローカルからアクセス

## 導入
タイトルの通り、かねてよりサーバーでjupyterを起動してローカルからアクセスしたいと思っていましたが、Qiitaの記事を参考にしてもうまくいかず、悶々としていました。

ですが、ちょうど今しがたできるようになったので忘れないためにもかいておこうと思い投稿しました。

追記(2019/06/06):

jupyterのバージョンが1.0.0にアップデートされていたので

それに合わせてこの記事も編集しました。

## 目的

踏み台サーバー("humidai")を経由して分析サーバー("bunseki")に入り、
分析サーバーでjupyterを起動したのちにローカルからアクセスすること

## 環境
python: 3.7.3
OS: linux
jupyter 1.0.0

## 手順

### 0. インストール
まずは分析サーバーでjupyterをインストールします。

```
$ pip install jupyter
```

### 1. jupyterのパスワードの設定

分析サーバーで以下を行います。

```
$ ipython
In [1]: from notebook.auth import passwd
In [2]: passwd()
Enter password: 
Verify password: 
Out[3]: 'sha1:...' # これをコピーしておく
```

### 2. コンフィグファイルの作成

```
$ cd ~
$ mkdir .jupiter
$ cd .jupyter
$ vim jupyter_notebook_config.py
```

jupyter_notebook_config.pyには以下のように記述します。

```python:jupyter_notebook_config.py
c = get_config()

c.NotebookApp.ip='0.0.0.0' # 任意のipアドレスからアクセス可能, jupyter==1.0.0ではこうしないと動かなかった
c.NotebookApp.password = 'sha1:...' # コピーしておいた文字列をペースト
c.NotebookApp.open_browser=False # ブラウザは自動で開かない
c.NotebookApp.port=9000 # サーバーのportを適当に設定しておく
```

### 3. ローカルポートフォワード

一旦サーバーからログアウトします。
ローカルから、port番号を指定して分析サーバーにssh接続します。

```
$ ssh -L <localのport番号>:localhost:<分析サーバーのport番号> bunseki
```

※多段SSHの設定がまだの方は[こちら](https://qiita.com/ik-fib/items/12e4fab4478e360a82a1)を参照してください。

### 4. Jupyterの起動

分析サーバーの任意の場所でjupyterを起動します。

```
$ jupyter notebook
```

### 5. ローカルからアクセス

任意のブラウザから、以下のURLにアクセスします。
<localのport番号>には、先ほど指定したlocalのport番号を用います。

```
http://localhost:<localのport番号>
```

jupyterが開けたら自分で設定したパスワードを入力して完了です！

お疲れ様でした。

jupyterを終了させたい場合はCtr-Cで。
Git/GitLabの使い方(忘備録メモ)

##gitのレポジトリ作成
gitlabからレポジトリを取得。

```
$ git clone レポジトリ名
```
##公開鍵の作成・登録
**1. キーペア(公開鍵と秘密鍵)を作成**

```
$ ssh-keygen -t rsa
```

(~/.ssh以下にid_rsa(秘密鍵)、id_rsa.pub(公開鍵)の2ファイルが作成される。)

**2. gitlabの'SSH Keys'へ移動**
<鍵の名前>.pubの方をコピペする
SSH Keyが作成される。

##gitの使いかた

**Branchの作成**

```
$ git branch ブランチ名
```

**書いたコードをpushするまで**

1 コードをadd

```
$ git add -A
# もしくは
$ git add .
```

2 コードをcommit

```
$ git commit -m 'コメント'
```

3 コードをpush

```
$ git push -u origin ブランチ名
```


**pullしたいとき**

1 pullしてきたいbranchに切り替える

```
$ git checkout ブランチ名
```

2 fetchでコードを取ってくる

```
$ git fetch --prune
```
3 pullでコードを統合する

```
$ git pull 
```

***特定のコミットまで戻す***

```
$ git log
```
履歴を確認し、戻りたいコミットのハッシュをコピペ

```
$ git reset --hard
```
戻す
TomcatがOutOfMemoryErrorを起こした時に自動的に再起動するように設定する

メモリリークは起こるもの。
しかし、長期休暇の最中などに「サイトが落ちた」の連絡を受けるのは御免を蒙りたいので、方法を調べました。


# １：OutOfMemoryError発生時に自動で実行したいバッチファイルを用意する。

例:
↓のようなファイルrestartTomcat.shを作り、適当な場所（/usr/local/tomcat/binなど）に配置します。
※「chmod +x restartTomcat.sh」などで、実行権限を付けておきます。

```sh:restartTomcat.sh
#!/bin/bash

#tomcat再起動（例）再起動以外に実行したいコマンドがあるなら一緒に書きます。メール飛ばすとか。
systemctl restart tomcat.service
```


# ２：TomcatのjvmオプションにXX:OnOutOfMemoryErrorを追記する。

環境変数CATALINA_OPTSに以下のオプションを追加して、OutOfMemoryError時に実行するコマンドを指定します。

- -XX:OnOutOfMemoryError

Tomcatのjvmオプションを指定する一つの方法としては、
/usr/local/tomcat/binに「setenv.sh」というファイルを置けば、Tomcat起動時にcatalina.shから読み込まれます。

例：

```sh:setenv.sh

export CATALINA_OPTS="$CATALINA_OPTS -XX:OnOutOfMemoryError=\"/usr/local/tomcat/bin/restartTomcat.sh\""

```

これで、OutOfMemoryError時にrestartTomcat.shを実行してくれます。


# ３：HeapDumpも一緒に出力する。

HeapDumpも出したい場合は、環境変数CATALINA_OPTSに以下の2つのオプションを追加します。

- -XX:+HeapDumpOnOutOfMemoryError（OutOfMemoryError時に、HeapDumpを出力します。）
- -XX:HeapDumpPath（上記のHeapDumpの出力先を指定します。）

例：

```sh:setenv.sh

export CATALINA_OPTS="$CATALINA_OPTS -XX:+HeapDumpOnOutOfMemoryError"
export CATALINA_OPTS="$CATALINA_OPTS -XX:HeapDumpPath=/usr/local/tomcat/logs"
export CATALINA_OPTS="$CATALINA_OPTS -XX:OnOutOfMemoryError=\"/usr/local/tomcat/bin/restartTomcat.sh\""

```



※ただ、Tomcatが再起動するより前にHeapDumpが完了しているかが不透明なため、
HeapDumpを確実に出力したいならば、HeapDumpOnOutOfMemoryErrorの代わりに、restartTomcat.shの中からダンプさせるなどして、ダンプの出力前にTomcatが再起動しないようにするべきかも・・・
NetBeans (PHP) Auto Bracket 機能の不具合

## はじめに

わたしは PHP の編集に [ねこび～ん](https://ja.netbeans.org/) を使っています。ねこび～んには...

1. "(" 括弧を入力すると ")" が自動的に入力される。
2. その時点で挿入キャレットは "(" と ")" の間にある。
3. 続けて ")" を入力すると、余計な ")" は入力されずに挿入キャレットが右に移動するだけ。

という便利な機能があります。

これが上手く動かないファイルがありました。ファイルによって違うので、編集中のファイルに何かしらの原因があると考えました。

最終的に、下記のサンプルコードで再現することがわかりました。

## 再現コード

```php
<?php

$a = "($b)c";

?>
```

新しく空の .php ファイルを作成して上記のコードを入力した後、関数の呼び出し＿＿何でもかまいません。例えば `phpinfo();` ＿＿を入力すると、最後の ")" を入力したときに異なる挙動をします。

二重引用符の中で括弧にはさまれた変数の展開の括弧の後に何か文字がある、というコードで発生するようです。もし同様のことで悩んでいる人がいらっしゃいましたら、ファイル内に上記のようなコードがないかどうか探してみてください。

## 対象バージョン

NetBeans 8.0.2 と 8.2 で確認しました。
PHP プラグインのバージョンは以下の通りです。
バージョン: 1.58.1 ソース: NetBeans IDE 8.0.2 (Build 201411181905)
バージョン: 1.63.1 ソース: NetBeans IDE 8.2 (Build 201609300101)
日本語のユーザ名でeclipseでmaven

#概要
日本語氏名をユーザ名に設定されている状況でmavenを利用できるようにする。

##Cドライブ直下等の日本語を含まないフォルダを作成する。
ここでは仮に「C:m2」とする。
##C:m2配下にrepositoryフォルダを作成する
##C:m2配下にsettings.xmlを作成する。
##settings.xmlを開き、以下を記載する
```xml
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                          https://maven.apache.org/xsd/settings-1.0.0.xsd">
	<localRepository>C:\m2\repository</localRepository>
      <interactiveMode/>
      <usePluginRegistry/>
      <offline/>
      <pluginGroups/>
      <servers/>
      <mirrors/>
      <proxies/>
      <profiles/>
      <activeProfiles/>
    </settings>
```
##eclipseにて設定読み込み先を指定する。
メインメニュー＞ウィンドウ＞設定＞Maven＞ユーザー設定にて、
上記のsettings.xmlを指定し、「設定の更新」ボタンを押下する。
GoogleAppEngineのmanaged sslを試してみた話

#managed sslの記事
managed sslリリースの記事を見かけたので試す！
[Publickyさんの記事](http://www.publickey1.jp/blog/17/google_app_engine_managed_ssl.html#1505771623146)
[Google Cloud Platform Blog](https://cloudplatform.googleblog.com/2017/09/introducing-managed-SSL-for-Google-App-Engine.html)

#カスタムドメインの登録
SSL設定する前にまずはカスタムドメインの登録
カスタムドメインを登録する前はこんな感じのURL
https://[プロジェクト名].appspot.com/
※デフォルトのURLだと実はhttps！

##GAEへカスタムドメインを設定
まずはカスタムドメインを設定することから

##1.設定を選択
左メニュー→App Engineを選択→設定を選択
<img width="1280" alt="gae_ssl_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/6a20586e-b492-9fd5-b68f-700986f44671.png">


##2.設定画面へ
　画面上部の「カスタムドメイン」を選択後、「カスタムドメインを追加」をクリック！
<img width="1280" alt="gae_ssl_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/9c324568-dff6-e357-1fbb-fab22b5ea981.png">

##3.新規ドメインの追加
- 使用するドメインを選択するで「新しいドメインを確認」を選択
- テキストエリアに取得したドメインを入力
- 確認ボタンクリック
　確認ボタンくクリック後、ドメインの所有権確認をしますが
　キャプチャ忘れ、、、画面の手順に沿って操作を行えばOK！
<img width="1280" alt="gae_ssl_03.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/f719d27c-1568-eb03-d314-c68f06a0723c.png">

##4.ドメインがGCPプロジェクトにマッピングされる
続行ボタンをクリック
<img width="1280" alt="gae_ssl_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/2c84ea52-5566-6596-8e4b-834f482b3558.png">

「Googleは無料の自動更新SSL証明書をアプリケーションに追加します」って記載されてますね！
あれ？アルファ？ドキュメントにはベータって記載されてたけど、、、

##5.DNSレコードの更新
3で表示されている値を使ってDNSレコードを更新
<img width="1280" alt="gae_ssl_05.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/eb89fd1c-d81a-f2a6-5c95-0d4a7ccedba7.png">

##6.Done
これでSSLの設定完了！
簡単！
※全てのオペレーション完了後すぐにはSSLが設定されない
　SSLセキュリティの列にアラートアイコンが表示されてオンマウスすると「まだ反映されてません。自動で反映されます」的な説明が表示されます。
<img width="1280" alt="gae_ssl_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/89613/2eb457e7-27b8-6934-7326-f2b4435d2fd9.png">

#終わり
とりあえずmagaged sslを試してみた。
自分でSSL取得しないでいいので経済的でいいね。
まだ、アルファ？ベータなので商用ではまだ使えなさそうだけどGAはよ！