OmniAICreator/Qiita-1.07M huggingface dataset:
『Go言語でつくるインタプリタ』を読んでみて

[Go言語でつくるインタプリタ](https://www.oreilly.co.jp/books/9784873118222/)を読んだので、感想など。

# 学び

- Go言語の雰囲気が結構つかめた。
- 字句解→構文解析→評価という流れのインタプリタの基礎がわかった。割と泥臭い実装だった。木構造がすごい便利に活用される事例だったな。
- TDDな感じで最初にテストを書いて、それが通るようにコードを追加していく様を通じて、TDDの効果的な進め方が疑似体験できた感じ。
【SAPUI5】Uncaught ReferenceError: sap is not definedの解決方法

##事象
Fioriスタイルのアプリケーションを作り、index.htmlファイルから実行したところ以下のようなエラーになりました。

Uncaught SyntaxError: Unexpected token :
Uncaught ReferenceError: sap is not defined

![image.png](https://qiita-image-store.s3.amazonaws.com/0/276021/24f5d091-a32e-5d60-24b2-1b222259fe01.png)

##ソース

```html
<!DOCTYPE html>
<html>
	<head>
		<!-- bootstrap of SAP UI5 -->
		<script 
			id="sap-ui-bootstrap"
			src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
			data-sap-ui-libs="sap.m, sap.ui.layout, sap.ui.table"
			data-sap-ui-theme="sap_bluecrystal"
			data-sap-ui-xx-bindingSyntax="complex"
			data-sap-ui-resourceroots='{
				"oft.fiori.nov": "./"
			}'>
		</script>
		<script>
			//Component.js日本語
			sap.ui.getCore().attachInit(function(){
				var ComponentContainer = new sap.ui.core.ComponentContainer({
					name: "oft.fiori.nov"
				})
				ComponentContainer.placeAt("content")
			});					
		</script>
	</head>
	<body class="sapUiBody">
		<div id="content"></div>
		
	</body>
</html>
```

##原因
スクリプト内に日本語のコメントがあるため、sap-ui-core.jsファイルの一部が文字化けしていました。このため後続のライブラリが読み込めず、メソッドを実行しようとしたときに"sap is not defined"というエラーが出ていました。

##解決方法
日本語のコメントを削除することで解消しました。
Docker ImageをGCP Container RegistryにPushする方法

###はじめに
GCP Container RegistryにDocker Imageをpushする方法の備忘録です。

###手順
````
$ gcloud config list
````

`[core]
account = hogehoge@example.com
disable_usage_reporting = False
project = hogehoge`

```
$ gcloud auth configure-docker
```
`The following settings will be added to your Docker config file`
`located at [/Users/user/.docker/config.json]:
 {
  "credHelpers": {
    "gcr.io": "gcloud",
    "us.gcr.io": "gcloud",
    "eu.gcr.io": "gcloud",
    "asia.gcr.io": "gcloud",
    "staging-k8s.gcr.io": "gcloud",
    "marketplace.gcr.io": "gcloud"
  }
}`

`Do you want to continue (Y/n)? `

→yes

```
$ docker build -f ~/Dockerfile -t [image name] .
```
`Successfully built ●●●●
Successfully tagged ●●●●:latest`

```
$ docker images
```
→buildしたimageを確認できる。

```
$ docker tag [image name] gcr.io/~/[image name]:latest
```
```
$ gcloud docker -- push gcr.io/~/[image name]
```

`8bac3adefc84: Pushed
 9317358e9e38: Pushed`

→成功です。
#エンジニア の仕事術。口頭で話しかけるか  #Slack などのチャットツールを使うか。どっちにするか？ ここでもコストとオーバーヘッドの関係性を考えたい。TCP と UDP のプロトコルの違いみたいな。 

#エンジニア の仕事術。口頭で話しかけるか、Slackなどのチャットツールを使うか。どっちにするか？ ここでもコストとオーバーヘッドの関係性を考えたい。TCP と UDP のプロトコルの違いみたいな。 

世の中の多くの物事と同じで、ここでもオーバーヘッドとコストの問題が絡んでくる。投資があり、回収がある。

# チャットやメール

- オーバーヘッドが少ない、一瞬で伝えられる。
- 情報量の少ない、意思疎通が簡単な連絡に向いている。
- 逆に複雑な話や、言い方が難しくて、人間感情が絡みそうな連絡だと、コストの大きさが響く。

# 口頭

- オーバーヘッドが大きい。
- 自分のコストは軽いが、相手の作業を中断させるし、注意力を奪うので、相手は最初に大きなコストを払うことになる。
- オーバーヘッドを回収できるぐらいの価値のある、情報量の交換が必要な場合であれば、口頭を選ぶのが良いかもしれない。

# 個人的なこと

- 脊柱菅狭窄症が重くて歩きづらい時期は、Slackでの連絡がほとんどになる。
- 連絡したいのが複雑な話だったりすると、テキスト作成のコスト、相手の理解のコストが重くのしかかり、オーバーヘッドの軽さで回収できなくなる。
- このように、様々なパラメータでコストとオーバーヘッドの関係が変わってくるので、やり方を固定するのではなく、そのつど最終コストが低い方を選んでいく感じ。



# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
JenkinsのRole-based Authorization Strategyプラグイン使用時にリモートビルドでエラー

Jenkinsのユーザ情報をActive Directoryで制御していて、且つ、権限管理を「Role-Based Strategy」に設定した場合に、リモートビルドがうまくいかなくてハマったので残しておきます。

# 環境
* Jenkins : 2.150.1
* Role-Based Strategyプラグイン : 2.9.0

# Jenkinsの管理設定

## Active Directory管理

* [Jenkinsの管理]→[グローバルセキュリティの設定]→[セキュリティを有効化]にチェックを入れて、Active Directory情報を入力し保存します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/d490d7f1-33b9-6594-bbf0-3b9e5658ead4.png)

## Role-Based Strategy設定

* [Jenkinsの管理]→[プラグインの管理]の順に選択し、「Role-based Authorization Strategy」にチェックを入れてインストールします。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/bff1978f-0653-1a88-72aa-b557930ca558.png)

* [Jenkinsの管理]→[グローバルセキュリティの設定]→[権限管理]の順に選択し、「Role-Based Strategy」にチェックを入れて保存します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/3cf0ec0e-2b30-5fde-b3e4-b49a7652f73e.png)

* [Jenkinsの管理]→[Manage and Assign Roles]の順に選択します（Manage and Assign Rolesは、前の手順でRole-Based Strategyにチェックを入れてないと表示されません）  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/6468f0ef-8ed6-90dd-1d2c-8349ffc9ec07.png)

* [Assign Roles]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/1c209785-4009-fef4-8875-829413ab57ef.png)

* 初期状態はこんな感じになってるはずです。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/ac06d733-f080-2e85-6758-45f9b1bea510.png)

# リモートビルドでエラー

この状態でリモートビルドを実行しようとするとエラーになります。
これは大文字のユーザ「Shingo_Kawahara」ではadmin権限があるが、リモートビルドからユーザ指定で実行しようとした場合、JenkinsユーザIDの小文字「shingo_kawahara」を使おうとして、権限を持っていない為です。（エラーメッセージ見ても分からない・・・）  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/881d5e72-99dc-750d-a50d-a9a2ff17afa5.png)

* ということで、小文字のJenkinsユーザIDも権限を付与してあげると、無事リモートビルドが通ります。表示名じゃなくて、JenkinsIDをちゃんと確認したほうがいいですね。。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/de63333f-b09f-a01d-7d5d-2115df3872c7.png)

# 参考：リモートビルド実行手順

[Jenkinsでパラメータ付きジョブをリモートビルドする](https://qiita.com/shingo_kawahara/items/ac40592726f3756a5c3d)
metasploit起動時のDB接続エラーの解消

metasploitを起動したら以下の警告が表示された。

```
[-] **rting the Metasploit Framework console...|
[-] WARNING: No database support: No database YAML file
```

ぐぐったら以下のコマンドやってみれば？となっていたので実行

```
sudo /usr/bin/msfdb stop
sudo /usr/bin/msfdb run
```

そうしたら以下のエラーが出るようになった

```
Failed to connect to the database: could not connect to server: Connection refused
Is the server running on host "localhost" (::1) and accepting
TCP/IP connections on port 5432?
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
```

5432に接続できないけど？ って言われているので開放されているポートを調べてみた

```
┌─[marseille@parrot]─[~]
└──╼ $sudo netstat -napA inet
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      844/sshd
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      626/cupsd
tcp        0      0 127.0.0.1:5434          0.0.0.0:*               LISTEN      746/postgres
tcp        0      0 192.168.164.149:22      192.168.164.1:52988     ESTABLISHED 1198/sshd: marseill
udp        0      0 0.0.0.0:68              0.0.0.0:*                           757/dhclient
udp        0      0 0.0.0.0:68              0.0.0.0:*                           764/dhclient
udp        0      0 0.0.0.0:47673           0.0.0.0:*                           637/avahi-daemon: r
udp        0      0 0.0.0.0:631             0.0.0.0:*                           687/cups-browsed
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           637/avahi-daemon: r
```

何故かpostgresqlが5434で動いているので、msfconsoleが起動する際に読み込まれる設定ファイルを編集した。
編集するのはport:5432をport:5434に。

```
┌─[marseille@parrot]─[~]
└──╼ $cd /usr/share/metasploit-framework/config
┌─[marseille@parrot]─[/usr/share/metasploit-framework/config]
└──╼ $sudo vim database.yml
```

そうしてmetasploitを起動する。

```
┌─[marseille@parrot]─[~]
└──╼ $msfconsole

 _                                                    _
/ \    /\         __                         _   __  /_/ __
| |\  / | _____   \ \           ___   _____ | | /  \ _   \ \
| | \/| | | ___\ |- -|   /\    / __\ | -__/ | || | || | |- -|
|_|   | | | _|__  | |_  / -\ __\ \   | |    | | \__/| |  | |_
      |/  |____/  \___\/ /\ \\___/   \/     \__|    |_\  \___\


       =[ metasploit v5.0.0-dev                           ]
+ -- --=[ 1849 exploits - 1046 auxiliary - 321 post       ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops            ]
+ -- --=[ 2 evasion                                       ]
+ -- --=[ ** This is Metasploit 5 development branch **   ]

msf5 > db_status
[*] Connected to msf. Connection type: postgresql.
```

無事接続されている。
iOSで画像アセットの利用有無を調べる

# 概要
iOSアプリの開発を続けているうちに、**利用していない画像がプロジェクトに含まれてしまう**ことがあります。
無駄な画像ファイルが含まれていると、パッケージのダウンロードサイズが増えるため、定期的にチェックして削除すると良いです。

そのための[shtnkgm/AssetCatalogChecker](https://github.com/shtnkgm/AssetCatalogChecker)という画像の利用有無をチェックするためのShellScriptを作成しました。

# 使い方
以下のようにShellScriptをダウンロードして実行するだけです。

```bash
# ShellScriptをダウンロードします。
wget https://raw.githubusercontent.com/shtnkgm/AssetCatalogChecker/master/AssetCatalogChecker.sh

# パスを指定してShellScriptを実行します。 
# sh AssetCatalogChecker.sh <path_to_project>
$ sh AssetCatalogChecker.sh ./MyApp
==> Target Directory ./MyApp
==> ❌ "dev" not found
==> ✅ "Setting" found
==> ✅ "Crop" found
==> ✅ "Camera" found
==> ✅ "Highlight" found
==> ✅ "Delete" found
==> ❌ "Rainbow" not found
==> ✅ "Sun" found
==> ✅ "Upload" found
==> ✅ "Shadow" found
==> ❌ "Circle" not found
==> ✅ "DashedCircle" found
==> ✅ "RoundedSquare" found
==> ✅ "Exposure" found
==> ✅ "Rotate" found
==> 🍺 Finished!!!
```

# ShellScript

```Bash
#!/bin/bash

echo "==> Target Directory $1"

# CarthageとPods配下は除外する
find $1 -name "*.imageset" -not -path "*/Carthage/*" -not -path "*/Pods/*" | \
  sed "s/.*\///" | \
  sed "s/\.imageset//" | \
  while read -r name; do
    # 精度と検索速度向上のため、検索対象の拡張子を限定する
    grep -Er "\"$name\"|/$name\"" $1 --exclude-dir={Carthage,Pods,build,fastlane} --include='*.swift' --include='*.m' --include='*.xib' --include='*.storyboard' > /dev/null
    if [ $? -eq 0 ]; then
      echo "==> ✅ \"$name\" found"
    else
      echo "==> ❌ \"$name\" not found"
    fi
done
echo "==> 🍺 Finished!!!"
```

# 仕組み
指定したパス配下で画像アセットファイル(.imageset)を検索します。
画像アセットファイルに定義されている画像アセット名で検索し、以下の検索対象となるファイル内に画像アセット名の文字列が存在するかチェックします。

 - .xib
 - .storyboard
 - .m
 - .swift

Carthage、Pods配下は検索対象から除外されます。
namespaceが設定されている場合を考慮し、`"画像アセット名"`および`/画像アセット名"`でgrep検索をかけます。

# 注意事項
 - 画像の有無の検知は**あくまで目安**です。
 - 画像アセット名の文字列がヒットするか検索しているだけのため、実際に利用しているか、利用していないかは正しく判定できないことがあります。
 - 特にプログラムで文字列を組み立てて画像アセット名を指定している場合には検知できません。
.NET CoreでMagicOnionを動かしてみた

## MagicOnionとは
gRPCを用いた.NET/Unity間のリアルタイム通信ライブラリです
- https://github.com/Cysharp/MagicOnion

READMEでは、Windows上で動かすことを前提に書かれていたりしますが、
Linux/Macでも問題なく動作します。
(`Install-Package` コマンドなどが記載されているので)

## 検証内容
今回はUnityは一切使用しません
MagicOnionとはどういうものかをREADMEに沿って検証するのみとなっています

## 検証環境
- Mac OS Mojave 10.14.2
- .NET Core 2.1.301

## サンプルプログラムを動かす
READMEに沿って、サーバー/クライアントのコードを動かしてみます

### 準備
サーバー側/クライアント側の両方のConsoleプロジェクトを作成します

- サーバー側

```sh
$ mkdir Server
$ cd Server
$ dotnet new console
$ dotnet add package MagicOnion
```

- クライアント側

```
$ mkdir Client
$ cd Client
$ dotnet new console
$ dotnet add package MagicOnion
```

これで準備完了です

### サーバー側実装
https://github.com/Cysharp/MagicOnion#quick-start
こちらに記載されている、サーバー側プログラムをそのままコピーします
(Program.csとMyFirstService.cs)

### クライアント側実装
軽く動作検証するだけですので、ちょっとだけコードを変更し以下のようにします
また、クラアント側には `MyFirstService` の実態は不要でインターフェースを定義したファイルだけあれば良いです
(後述しますが、これがIDLとなります)

```csharp
class Program
{
    static void Main(string[] args)
    {
        // standard gRPC channel
        var channel = new Channel("localhost", 12345, ChannelCredentials.Insecure);

        // get MagicOnion dynamic client proxy
        var client = MagicOnionClient.Create<IMyFirstService>(channel);

        // call method.
        var result = client.SumAsync(100, 200).GetAwaiter().GetResult();

        Console.WriteLine("Client Received:" + result);
    }
}
```

手を加えた箇所は以下のところです
本来はasyncで非同期実行するところですが、`GetAwaiter().GetResult()` と書くと同期的に処理が終わるまで待機してくれます
(メインスレッドが固まるのでリリース開発版などでの利用はおすすめしません...)

```csharp
client.SumAsync(100, 200).GetAwaiter().GetResult();
```

## 動かしてみる
### サーバープログラムの起動
まず、サーバー側プログラムを動かします。
単純な検証ですので `dotnet run` コマンドで実行するだけです

```
$ cd Server
$ dotnet run
D0204 17:50:33.569109 Grpc.Core.Internal.UnmanagedLibrary Attempting to load native library "/Users/Hogehoge/.nuget/packages/grpc.core/1.17.0/lib/netstandard1.5/../../runtimes/osx/native/libgrpc_csharp_ext.x64.dylib"
D0204 17:50:33.672423 Grpc.Core.Internal.NativeExtension gRPC native library loaded successfully.
```
サーバーが待機状態で起動します

### クライアントプログラムの起動
```
$ cd Client
$ dotnet run
Client Received:300
```
サーバーからのレスポンスを受けることが確認できます
また、サーバー側のログにも以下のように表示され、リクエストを処理できたことが確認できます
```
D0204 17:52:40.951573 Received:100, 200
```

特に苦労することもなくあっさり動いてくれました

## ちょっと動かしただけでわかるメリット
### サーバー/クライアント間でのIDLが不要！
通信仕様を共有するために、中間言語で書かれたIDLだったり、SwaggerなどでのAPI仕様を共有することが多いですが、MagicOnionでは、C#のインターフェースファイルをクライアントに渡すだけでサクッと通信ができます

## デメリット
当たり前ですがすべてC#縛り...

## その他1
コンパイル時に、

```
MyFirstService.cs(22,39): warning CS1998: この非同期メソッドには 'await' 演算子がないため、
同期的に実行されます。'await' 演算子を使用して非ブロッキング API 呼び出しを待機するか、
'await Task.Run(...)' を使用してバックグラウンドのスレッドに対して 
CPU 主体の処理を実行することを検討してください。
```
という警告が出ますが、無視で。作者のサイトでも公式に言及されています
(`Generalized async return types (Task-like)` は別途勉強しておかないと...)
http://neue.cc/2017/04/06_551.html

## その他2
最近は、BlazorというWebのフロントエンドをC#で書けるものも出てきているので、
MagicOnionはUnity以外でも用途は色々とあるのではとちょっと思いました
https://blazor.net/
Git を WSL と Win32 の両方で使ってるときの git status の高速化

Git を WSL と Win32 の両方で使っているとき、たまに `git status` などのコマンドがめちゃくちゃ遅くなることがあります。常識的に考えて WSL と Win32 の両方で Git を使うようなことはないかと思いきや、PhpStorm や Sublime Text のプラグインとかで使われているので結構な頻度で起こります。

これは Git がインデックスとワーキングツリーとの比較で `stat(3)` の多くの情報を用いてファイルの更新の有無を判断しているためです。

次のように `core.checkStat` を `minimal` にすれば `mtime`（秒単位）とファイルサイズのみで比較されるようになるので、だいぶ改善します。

```sh
# WSL
git config --global core.checkStat minimal
# Win32
git.exe config --global core.checkStat minimal
```

## 詳細

`git status` を連続して実行しているときはそれほどは遅くないですが、

```sh
# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.239s
user    0m0.016s
sys     0m0.297s

# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.243s
user    0m0.000s
sys     0m0.328s
```

Win32 側の `git status` を実行すると・・・

```sh
# Win32
$ time git.exe status
On branch master
nothing to commit, working tree clean

real    0m0.491s
user    0m0.016s
sys     0m0.016s
```

その直後の WSL の `git status` がめちゃめちゃ遅いです。

```sh
# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.958s
user    0m0.234s
sys     0m0.766s
```

その後はもとに戻ります。

```sh
# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.232s
user    0m0.000s
sys     0m0.266s
```

`core.checkStat` を `minimal` にすれば WSL と Win32 で交互に実行しても速度はあまり変わらなくなります。

```sh
# WSL
git config --global core.checkStat minimal

# Win32
git.exe config --global core.checkStat minimal

# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.259s
user    0m0.016s
sys     0m0.313s

# Win32
$ time git.exe status
On branch master
nothing to commit, working tree clean

real    0m0.146s
user    0m0.000s
sys     0m0.016s

# WSL
$ time git status
On branch master
nothing to commit, working tree clean

real    0m0.263s
user    0m0.031s
sys     0m0.313s
```

## もっと詳細

Git のインデックスファイルにはステージしたファイルだけでなく、ワーキングツリーのファイルのメタ情報も含まれています。`git status` するとワーキングツリーを走査してファイルのメタ情報をインデックスと比較し、ファイルが更新されていればファイルを読んでハッシュを再計算してインデックスを更新したうえでその情報を用いて `git status` の結果が表示されます。

インデックスには stat 構造体の多くが記録されており、デフォルトではこれらの多くの情報を用いてワーキングツリーとインデックスが比較されるのですが、WSL と Win32 では一致することが決して無いので（dev とか ino とか uid とか gid とか）、WSL と Win32 で交互に実行すると常にすべてのファイルが更新されたものとしてファイルの読み込みが発生します。

`core.checkStat` を `minimal` にすると、ワーキングツリーとインデックスの比較が mtime（秒単位）とファイルサイズでのみ比較されるようになるため、WSL と Win32 で交互に `git status` しても問題ありません。

## 参考

- https://stackoverflow.com/questions/4084921/what-does-the-git-index-contain-exactly
- https://github.com/git/git/blob/master/Documentation/technical/index-format.txt
    - インデックスの構造について
- https://git-scm.com/docs/git-config#git-config-corecheckStat
    - core.checkStat について
rails PDFファイルをマージするには Combine PDF gem

# gem combine_pdf
rails内でPDFファイルをマージ(コンバイン）したく探しました。
そしたら、ありました。

[combine_pdf](https://github.com/boazsegev/combine_pdf)

こんな感じ

``` ruby:公式より抜粋
 pdf = CombinePDF.new
 pdf << CombinePDF.load("file1.pdf") # one way to combine, very fast.
 pdf << CombinePDF.load("file2.pdf")
 pdf.save "combined.pdf"
```

loadメソッドの引数はファイルパスのみ対応のようです。
pdf.saveで指定したファイルパスにマージ後のPDFファイルを生成します。


carrierwave+S3 railsでの使用例を書きに載せてみる。

``` ruby:hoge.rb(モデル)
class Hoge < ApplicationRecord
  mount_uploader :pdf, FileUploader
end 

```

``` ruby:例
pdf = CombinePDF.new

hoge = Hoge.find(1) # model Hoge
hogehoge = Hoge.find(2)

pdf_object1 = open(hoge.pdf_url)
pdf << CombinePDF.load(pdf_object1.path)

pdf_object2 = open(hogehoge.pdf_url)
pdf << CombinePDF.load(pdf_object2.path)
```
Jenkinsでパラメータ付きジョブをリモートビルドする

# 環境

* Jenkins : 2.150.1

# ユーザToken取得

* Jenkinsにログインした状態で右上のログインユーザ名から[設定]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/156f4346-40b9-76bd-8296-98542aeb3cda.png)

* [Add new Token]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f92dbe75-7595-8f6e-8f9b-3f338b69d821.png)

* Key名を入力し[Generate]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f9561743-e422-55cc-8c8d-a70357bcab9b.png)

* tokenが発行されるのでコピーしておきます。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/eb7af816-2e3f-cdad-789a-0338c3deb2eb.png)

# ジョブ作成

* プロジェクト名を入力して[フリースタイル・プロジェクトのビルド]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/25dcc6c1-6e3d-9c8c-a9a8-6532157a5e63.png)

## General

* [ビルドのパラメータ化]にチェックを入れ、[文字列]を選択します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/83f5bea7-445b-9f15-900d-92f7ed862fab.png)

* 文字列は任意の値を入力します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/615b50a8-0b7f-7523-c738-a83d25cc7460.png)

## ビルド・トリガ

* [リモートからビルド]にチェックを入れ、認証トークンに任意の値を入力します。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/de85476a-6215-7494-be53-dcab6a32a6c6.png)

## ビルド

* [シェルの実行]を選択します。ここではパラメータに指定した変数を出力しています。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/3ae92a32-bc0d-0843-5792-f3b6e57b1878.png)

# リモートビルド

* curlでジョブをビルドします。  

```
$ curl --user "[Jenkinsユーザ名]:[事前にコピーしたAPIToken]" \
  "http://[Jenkinsホスト]:8080/job/XXX/job/remoteBuildTest/buildWithParameters?token=authenticationTokenTest&action=start"
```

* ジョブが動いて、ちゃんと指定したパラメータが取れてればOKです。  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/7d5fabd9-ce84-b0ba-b410-2bf9ecc95a44.png)
Go言語 インストール手順 @Windows10

Windows10の環境へGo言語をインストールする手順を記載

https://golang.org/dl/

上記URLにアクセスし、
<img width="365" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/68222ba5-6617-bacd-a99b-bd253d153b8b.png">

Windowsのインストーラをダウンロードし、起動させる

<img width="365" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/ccabac2e-c3e9-feb5-b91c-eb4fa6995535.png">
[Next]をクリック

<img width="365" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/e5b03381-c379-10fc-fbb1-eca6f5a6e8aa.png">
[I accept the therms int Lisence Agreement]にチェックを入れて
[Next]をクリック

<img width="364" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/84988b46-46c9-d6ca-70af-795ad6b5c988.png">
インストール先のフォルダを選択して
[Next]をクリック

<img width="364" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/aa46318b-f7e1-8a9e-0e7b-5068433aeec3.png">
[Install]をクリック

<img width="364" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/39bed3fe-b7a8-2cee-8682-5dadc9b35a7e.png">

<img width="364" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/265300/a94fc171-4de2-5449-43e3-5c7e9622741b.png">
[Finish]をクリックしてインストール終了

コマンドプロンプトを起動させ

```
go version
```
と入力し、

```
go version go1.XX.X windows/amd64
```
上記のようにVersionが表示されていれば正常にインストールされている
Github Organization リポジトリに push できないときの一つの対処法

Github Organization の設定でサードパーティアプリケーションでのアクセスポリシーが **Restricted** になっていると，サードパーティアプリケーションからの push ができない．

↓ここで設定を変更可能．

https://github.com/organizations/[organization_name]/settings/oauth_application_policy

-----

SourceTree から Github Organization リポジトリへ push しようとすると `permission denied` になってしまい，push できない問題に直面した．

Organization での自分のユーザー ID の Role を admin に変更しても，リポジトリに Collaborator として追加しても push できず，[この記事](http://www.kisse-logs.com/2017/07/19/github-organization-push-404/)のようにリモート URL を`https://github.com/~` から `https://[ユーザーID]@github.com/~` に変更してもうまくいかなかった．

サードパーティアプリケーションでのアクセスポリシーがデフォルトで **Restricted** になっていたようだ．
Cloud9でRailsプロジェクトを作成しよう

Cloud9でRailsプロジェクトを実際に作成する手順の備忘録的なものです。
DBをデフォルト以外に設定しようとすると意外と面倒だったりするので、備忘録的に残したいと思います。

※今回はCloud9を使える前提で進めます。
　Cloud9を使えるまでの手順は下記を参照してください


[AWSでCloud9を使えるようにしよう](https://qiita.com/kumas/items/26d507c5452865433085)

####①Railsプロジェクトのインポート####

下記コマンドを実行するとプロジェクトのテンプレートが作成されます。

```
$ rails new test
```
testはプロジェクト名です。

作成の前に今回のプロジェクト用のディレクトリを作成しましょう。

```
$ mkdir rails_test

$ cd rails_test
```
ルートパスに作成することをお勧めするので、「cd ..」等のコマンドを使って、ルートに移動しておいてください。

作成後は、作詞したディレクトリまで移動して、プロジェクトをインポートします。

```
$ rails new project
```

上記コマンドでrails_test/projectというパス構成ができ、project以下に必要なフォルダ構成が作成されるはずです。

####②DB設定####

DBはデフォルトでsqlite3が入っているため、sqliteを使う場合は、そのままで次に進んでください
今回はMySQLを使うので、設定を入れます。

Gemfileの設定を下記に変更してください

```
# Use sqlite3 as the database for Active Record
#gem 'sqlite3'

#下記に変更
gem 'mysql2'
```
この状態で、bundle installを実行するとうまくいくはずが・・・・・
下記エラーが発生

```
An error occurred while installing mysql2 (0.5.2), and Bundler cannot continue.
Make sure that `gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'` succeeds before bundling.
```

gemのインストールのバージョン違いかと思いましたが、どうやら違うようです。
下記エラーが発生してしまいました。

```
$ gem install mysql2 -v '0.5.2' --source 'https://rubygems.org/'
・
・
・
・
ERROR:  Error installing mysql2:
　ERROR: Failed to build gem native extension.

```

調べてみると下記方法で解決するようです。

```
$ sudo yum install mysql-devel
```

MySQLのインストールが整ったら、設定ファイルを修正します
config/database.ymlのdevelopmentの設定を以下に修正しました

```
development:
  adapter: mysql2
  encoding: utf8
  database: rails_test
  pool: 5
  username: root
  password: 
  host: localhost
```

今回はローカル環境のみの設定なので、developmentの修正のみを行います。
「database:」は作成するデータベース名、「username:」はユーザー名(今回はローカル環境のみのため、rootユーザーを使ってます)を表記してください

####③Angularの導入####
ここは使わなければとばしてください
Angular.jsを使うときはGemfileに下記の設定を追加してください

```
gem 'angularjs-rails'
```
####④インストール####
②、③で行った変更をまとめて追加します

```
$ bundle install --without production
```
ローカル環境のみのため、withoutを使っています

```
Bundle complete! 18 Gemfile dependencies, 79 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
```
これでプロジェクトに適用できたため、サーバーに接続します

```
$ sudo service mysqld start

$ rails server -b 0.0.0.0
```
sqliteのときとは違い、MySQLに接続が必要な所だけ注意してください。
デフォルトのRailsページが表示されたら、成功です!

Gemfileに設定記載すれば、大体インストールしてくれそうですね。
DBの設定ファイルはほかの言語とそこまで違わない印象でした。
ただ、mysql-develに関してはもう少し調べてみようと思いました。
Rubyでobject_idからinstanceを探す方法

## #object_idで取得した値から、そのinstanceを取得する

開発中、たまにチェックする、instanceのobject_id。
object_idは取得は簡単だが、意外と知らない、その逆は！

`ObjectSpace._id2ref(object_id)`で取得できる！
と言う備忘録です。

```ruby
integer = 1
#=> 1

object_id = integer.object_id
#=> 3

object = ObjectSpace._id2ref(object_id)
#=> 1

integer.equal?(object)
#=> true
```
Rails でアノテーションを活用しよう！

#概要

アノテーションコメントを活用することで、確認すべき箇所や修正すべき箇所をコメントと併せてコード上に残し、後から確認することができます。


#書き方

シャープ + 半角Space + アノテーションキーワード + コロン + 半角Space + コメントで記述します。

```
# KEYWORD: comment
```

複数行に渡る場合は

```
def bar
  # FIXME: This has crashed occasionally since v3.2.1. It may
  #   be related to the BarBazUtil upgrade.
  baz(:quux)
end
```

ソースコードと同じ行に描く場合は

```
def bar
  sleep 100 # OPTIMIZE
end
```


#.html.erb  に書く場合

viewファイル（.html.erb）に書く場合は、少し書き方が異なります。

```
<% #KEYWORD comment %>
```



#アノテーションキーワード

Ruby Style Guideによると、以下のアノテーションキーワードが使用できます。

|キーワード|内容|
|---|---|
|TODO	|あとで追加すべき機能|
|FIXME	|修正が必要なコード|
|OPTIMIZE	|遅い・非効率など最適化すべきコード|
|HACK	|リファクタリングした方が良さそうなコード|
|REVIEW	|レビューすべき箇所|
|OTHER	|必要に応じてキーワードを追加。Readmeに記載すべし|


参考までに Ruby Style Guide の原文も

- Use TODO to note missing features or functionality that should be added at a later date.
- Use FIXME to note broken code that needs to be fixed.
- Use OPTIMIZE to note slow or inefficient code that may cause performance problems.
- Use HACK to note code smells where questionable coding practices were used and should be refactored away.
- Use REVIEW to note anything that should be looked at to confirm it is working as intended.
- Use other custom annotation keywords if it feels appropriate, but be sure to document them in your project's README or similar. 



#アノテーションコメントを一覧表示する

ターミナルから以下のコマンドでプロジェクト内のアノテーションコメントを一覧表示できます。

```
$ rake notes
```

特定のキーワードのアノテーションを表示するには、以下のコマンドを実行します。

```
$ rake notes:custom ANNOTATION=TODO
```


カスタムキーワードも同様に、以下のコマンドで表示できます。

```
# CUSTOM: comment
```


```
$ rake notes:custom ANNOTATION=CUSTOM
```




#参考

Ruby Style Guide
https://github.com/rubocop-hq/ruby-style-guide#comment-annotations

Ruby | アノテーションコメント（TODO、FIXME、OPTIMIZE、HACK、REVIEW）
https://qiita.com/tbpgr/items/1c046a877c6be4d89876

Rails | コード内のコメントを見つける方法 (TODO、FIXME、OPTIMIZE、HACK、REVIEW)
https://qiita.com/Yinaura/items/69584a09fee58efd163e

rake notesがviewファイル(.html.erb)で出てこない時の対処法
https://qiita.com/ihatov08/items/20f029950917b1d6905c

Rubyスタイルガイドを読む: コメント、アノテーション、マジックコメント
https://techracho.bpsinc.jp/hachi8833/2017_02_20/35769
ポインタをテンプレート引数にする

先日の [yhpg]( https://yhpg.doorkeeper.jp/ ) の懇親会で、関数へのポインタをテンプレート引数にできるという話を聞いた。
私はてっきり無理だと思っていたんだけど、テンプレートの黎明期からできた模様：

> このほかの *template-arg* は、 *constant-expression*(定数式)であるか、外部リンケージのオブジェクトや関数、あるいは静的クラス・メンバのアドレスでなければならない。

( 注解 C++リファレンスマニュアル p430 )

知らなかった。

まあ知っていても使う機会はなかなかなさそうではあるけれど。

## 関数へのポインタをテンプレート引数にする

例えば以下のような感じ。

```c++:ptrtemplate1.cpp
// clang++ -std=c++11 ptrtemplate1.cpp
#include <iostream>

template< char const *func()>
void foo()
{
  std::cout << "FOO[" << func() << "]\n";
}

char const * bar()
{
  return "bar";
}

int main()
{
  foo<bar>(); //=> FOO[bar]
}
```

## グローバル変数へのポインタをテンプレート引数にする

グローバル変数へのポインタはテンプレート引数にできるが、ローカルな変数はテンプレート引数にできない。
以下の通り：

```c++:ptrtemplate2.cpp
// clang++ -std=c++11 ptrtemplate2.cpp
#include <iostream>

char const * bar = "bar";

template< char const ** str >
void foo()
{
  std::cout << "FOO[" << *str << "]\n";
}

int main()
{
  foo<&bar>(); //=> FOO[bar]
  char const * baz = "baz";
  foo<&baz>(); //=> エラー。
}
```

## メンバへのポインタをテンプレート引数にする

注解 C++リファレンスマニュアル の記述からはわからないが、メンバへのポインタもテンプレート引数にすることができる。
以下の通り：

```c++:ptrtemplate3.cpp
// clang++ -std=c++11 ptrtemplate3.cpp
#include <iostream>

struct Hoge
{
  char const * fuga;
  char const * piyo;
};

Hoge hoge()
{
  return { "fuga", "piyo" };
}

template< char const * Hoge::*m >
void foo()
{
  std::cout << "FOO[" << (hoge().*m) << "]\n";
}

int main()
{
  foo<&Hoge::fuga>(); //=> Foo[fuga]
  foo<&Hoge::piyo>(); //=> Foo[piyo]
}
```

## いずれも

いずれも、なかなか使い所のない機能だと思う。
Raspberry Pi 3にUbuntu MATE をインストール 

Raspberry Pi 3 にUbuntu MATEをインストールする記事はたくさんありますが、wifiやgpioが使えると書いてある記事と使えないと書いてある記事があったので、まとめました。

# 環境
Raspberry Pi 3 Model B++
イメージ作成PC : Ubuntu 16.04
SDカード : [サンディスク 32GB](https://www.amazon.co.jp/gp/product/B06XWMQ81P/ref=ppx_yo_dt_b_asin_title_o02__o00_s00?ie=UTF8&psc=1)
インストールOS : Ubuntu MATE

# インストール手順
## OSイメージのダウンロード  
[公式サイト](https://www.raspberrypi.org/downloads/)で`Ubuntu MATE`を選択し、表示された画面で順に`Download Ubuntu MATE`、`Raspberry Pi`、`16.04.02`、`ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz`と選択します  

## イメージを解凍  
```
$ xz -dv ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz
```  

## SDカードへOSイメージを書き込む  
```
$ df -h # デバイス名のチェック。こちらの環境では/dev/sde1, /dev/sde2でした
$ sudo umount /dev/sde1
$ sudo umount /dev/sde2
$ sudo dd bs=4M if=ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img of=/dev/sde
```
参考 [Linux(Ubuntu)で、RaspberryPiのSDカードをインストールする方法](https://qiita.com/takanemu/items/8fa157688efe0d4b01a6)

## Raspberry Piの起動
Raspberry PiにSDカードを挿入して起動します。表示された画面に従って言語などの設定を行います。

## wifi, bluetooth
特別な設定をしなくても使用可能です。

## Raspi専用カメラ
Terminalで以下のコマンドで設定画面を表示し、`Interfacing Options` -> `Camera` を選択し`Enable`にします。  

```
$ sudo raspi-config
```
再起動後`raspistill`コマンドで撮影できます  

```
$ raspistill -o image.jpg
```
参考 [Raspberry Pi Ubuntu Mate Setup Guide Part 1](https://www.youtube.com/watch?v=BnFdoExhQ08)  

## GPIO
特別な設定をしなくても使用可能です。以下のコマンドでGPIOの状態を確認できます。  

```
$ gpio readall
```
pythonでGPIOを使う場合はライブラリのインストールが必要です。  

```
$ pip install RPi.GPIO
```
python3を使う場合は`pip3`としてください。  
LEDを点灯させるテストコードも作成しました。3秒おきにLEDが点滅します。  

```python:led.py
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.OUT)
GPIO.output(21, False)
state = True

for i in range(0, 5):
    if state == True:
        GPIO.output(21, False)
        state = False
    else:
        GPIO.output(21, True)
        state = True
GPIO.cleanup()
```
# その他設定
## 日本語入力
セットアップ時に言語を日本語にしていてもそのままでは日本語入力ができません。  
1. デスクトップの左上のメニューから`システム`->`設定`->`ユーザ向け`->`言語サポート`を選択する
2. 表示された画面で`インストール`を選ぶ
3. 再起動
4. `システム`->`設定`->`ユーザ向け`->`言語サポート`を選択する
5. `システム全体に適用`を選択
6. 再起動
7. `システム`->`設定`->`ユーザ向け`->`言語サポート`を選択する
8. `キーボード入力に使うIMシステム`で`fcitx`を選択
9. 再起動
参考 [第49回「ラズパイ3×Ubuntu MATEで遊ぼう！(1)日本語入力の設定方法」](https://deviceplus.jp/hobby/raspberrypi_entry_049/)

## SSH
```
$ sudo apt install openssh-server
$ sudo ufw allow 22
$ sudo /etc/init.d/ssh restart
$ sudo systemctl enable ssh
```
xwindowを使う場合は更に以下を設定する  

```
$ sudo vi /etc/ssh/sshd_config

X11Forwarding yes # no になっていればyesに変更する

$ sudo /etc/init.d/ssh restart
```
React Routerでのページ遷移を簡単に説明

#概要
Reactで開発を行う際、ページ遷移にはReact Routerが使われます。
今回はこれを使って簡単なページ遷移を実装します。
#インストール
まずは必要なライブラリをインストールします。

```terminal
npm install --save react-router-dom
```
#実装
実装していきます。
以下のコードをみてください。

```javascript:src/components/App.js
import React from 'react';
import { BrowserRouter, Route } from 'react-router-dom';

const PageOne = () => {
  return (
    <div>
      PageOne
    </div>
  );  
}

const PageTwo = () => {
  return (
    <div>
      PageTwo
    </div>
  );
}

const App = () => {
  return (
    <div>
      <BrowserRouter>
        <div>
          <Route path="/" exact component={PageOne} />
          <Route path="/pagetwo"  component={PageTwo} />
        </div>
      </BrowserRouter>
    </div>
  );
};

export default App;
```
コードをみてわかる通り、PageOneとPageTwoという２つのコンポーネントがあります。
必要なものとしてBrowserRouterとRouteを取ってきます。
BrowserRouterで遷移させたいコンポーネントをラップします。
Routeのところにはpathとexactとcomponentがあります。
みてわかると思いますが、pathには入れたいURL、componentには表示したいコンポーネントを入れます。
exactは簡単にいうと、pathに入っているURLを正確に読み取ります。
つまり、上のコードのexactを消してしまうと"/pagetwo"に飛んだ際にPageOneも表示されてしまいます。
次に以下のコードをみてください。

```javascript:src/components/App.js
import React from 'react';
import { BrowserRouter, Route, Link } from 'react-router-dom';

const PageOne = () => {
  return (
    <div>
      PageOne
      <Link to="/pagetwo">
        <button>
          show PageTwo when you click this!!
        </button>
      </Link>
    </div>
  );  
};

const PageTwo = () => {
  return (
    <div>
      PageTwo
      <Link to="/">
        <button>
          show PageOne when you click this!!
        </button>
      </Link>
    </div>
  );
};

const App = () => {
  return (
    <div>
      <BrowserRouter>
        <div>
          <Route path="/" exact component={PageOne} />
          <Route path="/pagetwo"  component={PageTwo} />
        </div>
      </BrowserRouter>
    </div>
  );
};

export default App;
```
ここでは新たにLinkを取ってきています。
これはtoキーワードに表示したいページのURLを入れてラップすることでコンポーネントからページ遷移することができます。
つまり上のコードではボタンをクリックすることでPageOneとPageTwoを行き来しています。
#まとめ
今回は簡単にReact Routerについて説明しました。
BrowserRouter以外にもHashRouterやMemoryRouterがあるみたいですが、標準はBrowserRouterなのでしょうか？
参考になれば幸いです。
【メモ】Kotlinコルーチンで並列処理の待ち合わせをしたい

RxJavaだったら `zip` とかを使えば並列処理の待ち合わせは出来るのですが、Kotlinのコルーチンの場合、どうすればよいのかわからなかったので雑にメモ。

※ ここでの `並列処理の待ち合わせ` は、「複数の処理を同時に行い、すべての処理が終わったタイミングでなにかする」、を指しています。複数のAPIを呼び出して、全部取得できたタイミングでViewを更新する、とかのやつです。

# サンプルコード
他にも色々と記述の仕方があるかもしれませんが、下記のような感じで並列処理の待ち合わせがいけるようです。

```kotlin
// 並列で処理したい関数1
suspend fun fetchStringA(): String = withContext(Dispatchers.IO) {
    delay(1000) // 1秒遅延
    "StringA"
}

// 並列で処理したい関数2
suspend fun fetchStringB(): String = withContext(Dispatchers.IO) {
    delay(2000) // 2秒遅延
    "StringB"
}

// 並列で処理を行う時
launch {
    coroutineScope {
        val a = async { fetchStringA() }
        val b = async { fetchStringB() }

        // 2秒後にログが出力される
        Log.d("LOG", "${a.await()} ${b.await()}")
    }
}
```

`coroutineScope` で囲んだ上で `async/await` でやるみたいです。

# 参考 :bow:
圧倒的にわかりやすいスライド。並列処理もこちらのスライドでわかりました。 :bow: :bow:
**Androidと非同期処理 とCoroutine1.0.0**
https://speakerdeck.com/sys1yagi/androidtofei-tong-qi-chu-li-tocoroutine1-dot-0-0

コルーチンに関して解説してくださっています。コルーチンをちょっと理解した後に聞くと「なるほどぉ」となるかもしれません。
**dex.fm 062: Kotlin Coroutine**
http://dex.fm/post/180685011923/062-kotlin-coroutine
Headless Chrome でファイルダウンロード先のパスを設定する方法

## 背景
Selenium を使って Headless Chrome で E2E テストを行う場合に、ファイルをダウンロードできるかどうか、ダウンロードしたファイルが正しいかどうかをテストしたい場合があります。このとき、Chrome に適切なオプションを渡すことでダウンロード先を指定します。 このとき、素の Chrome と Headless Chrome では指定の仕方が異なるので、その方法をまとめます。

## 解決策

Headless Chrome の場合、selenium に対して `send_comand` によってパラメータを登録する必要があります。
`downloadPath` に対して、ダウンロード先のパスを設定します。

```javascript

const fetch = require('node-fetch');
browser.getSession().then((session) => {
  const sessionId = session['id_'];
  fetch('http://localhost:4444/wd/hub/session/'+ sessionId + '/chromium/send_command', {
    method: 'POST',
    body: JSON.stringify({
      'cmd': 'Page.setDownloadBehavior',
      'params': {'behavior': 'allow', 'downloadPath': './path/to/download' }
    }),
  });
});
```

ここでは、 selenium へ HTTP リクエストを送信するのに `node-fetch` を使っています。 await/async を使わずにそのまま Promise を処理しています。他の HTTP ライブラリを使ったり、 await/async で書くことも可能です。


### 参考： 素の Chrome の場合

```javascript

capabilities = {
  browserName: "chrome",
  chromeOptions: {
    prefs: {
      'download': {
        'prompt_for_download': false,
        'directory_upgrade': true,
        'default_directory': './path/to/download',
      }
    }
  },
};
```

`default_directory` に対して、ダウンロード先のパスを設定します。

## 参考文献
- [seleniumにて ヘッドレス オプション使うと、CSV ファイルがダウンロードできない](https://teratail.com/questions/129394)
- [Issue 696481: Headless mode doesn't save file downloads](https://bugs.chromium.org/p/chromium/issues/detail?id=696481#c86)
- [Protractor file download test fails when headless chrome](https://stackoverflow.com/questions/48831273/protractor-file-download-test-fails-when-headless-chrome)
[セキュリティの勉強]DoS攻撃とDDoS攻撃

# はじめに
セキュリティ勉強のためこのページを作成しています。
意見や指摘等があればコメントください。

# DoS攻撃
Denial of Serviceの略。「サービスの拒否(直訳)」
攻撃対処のサーバに対して大量・大容量のデータを送信することで、サービスを提供できないようにする攻撃。

DoS攻撃の分類には2種類存在する。

- フラッド型
    : プロトコルを攻略して(※要調査)、サーバ等のネットワーク機器が処理できない量のデータを送りつける。
- 脆弱性型
    : サーバやアプリケーションの持つ脆弱性を利用してDoS攻撃を行う。


攻撃者の行動目的は主に三つ考えられる。

1. 私怨
    : 個人的な恨み妬み等を理由とする。
2. 囮
    : 本来の目的を目立たなくさせるために攻撃を仕掛ける。
      DoS攻撃を仕掛け、管理者が気を取られている間にネットワーク内部に侵入するなどをする。
3. 脅迫
    : 攻撃を執拗に行い、攻撃中止を条件に金銭を要求する。

# DDoS攻撃
Distributed DoSの略。
トロイの木馬などの不正なプログラムで乗っ取った端末を用いて分散化したDoS攻撃。

DoS攻撃は1or少数の端末からの大量・大容量データ送信に対し、DDoS攻撃は乗っ取った多数の端末からのデータ送信攻撃である。

DoS攻撃と同様に2種類存在する。

- 帯域幅攻撃
    大量のパケットを送信することで、ネットワーク機器のリソース消費や帯域幅占領を行う。それにより負荷を増大させて輻輳やサーバダウンを狙う。
- アプリケーション層攻撃
    TCPやHTTPパケットを大量に送ることで、負荷を増大させる攻撃。送信されるパケット内容が日常的に存在するものであることから、DDoS攻撃だと気付きにくい特徴がある。

---
DoS攻撃の種類にはさらに詳細なものがあるらしいので、後日追加する予定。
Bootstrap4を使ってポートフォリオサイトを制作してみました。

##なぜ作ろうと思ったか
[Web白熱教室のBootstrap](https://tsuyopon.xyz/learning-contents/web-dev/css/)コンテンツを学習して、これなら簡単にポートフォリオを作れるのでは？と思った。

##完成したサイト
https://atlansien.github.io/Bootstrap4_portforio1/
[コード](https://github.com/atlansien/Bootstrap4_portforio1)

##作った際に調べたもの
###Position:fixedを適応したい   
Bootstrap4では、fixedを適用する場合、クラス値に

```
fixed-top
```
と記入する。なお、その際は他のエレメントに重ならないよう`body`に

```
padding-top
```

を入れる必要がある。
###中央寄せの方法

ブロックを中央寄せする場合は

```
mx-auto //マージン左右をauto
```

と入力する。また、文字の中央揃え```(text-align:center)```の場合は

```
text-center
```

と入力する。

###navbarのボタンをクリックすると指定のコンテンツに飛ぶようにした。
指定のコンテンツの`id`値を設定し、ボタンの`href`にid値を入力した。
###横幅いっぱいの写真の上に文字を置けるようなブロックを作りたい
親要素の横方向全てを使用できる`jumbotron-fluid`を使用した。
    
###自己紹介欄を作りたい
`grid`システムを利用して画面を縮小した際も紹介文が見えるようにした。

###Bootstrap4の説明文を横いっぱいに広がらないようにしたい。
`width`に`％`を使うことで画面を切り替えても左右に一定の空きが出るようにした。

##つまづき
・各コンテンツに移動する際にnavbarを連動してactiveにしたかったが方法がイマイチわからなかった。

・各コンテンツに移動する際アニメーション効果をつけてスクロールさせたいと思いProgateで学んだScrolltopを使用してみたがうまく動かなかった。（違う方法があるのかも）

・今あるコンテンツの下に無料のテンプレート一覧紹介を作りたかったがサムネイルを綺麗に並べることができず消去した。
<img width="1280" alt="スクリーンショット 2019-02-04 18.50.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/349049/6dccc2c6-778e-8a28-1ee7-ac6c7d1d9a3e.png">

参考：https://blackrockdigital.github.io/startbootstrap-creative/

・自分のスキルをグラフで表示できるようにしたかったがそのような機能はBootstrapになかったので断念した。

##感想
やはり構築自体が簡単にできるとは言っても、フレームワークやデザインを学んでいない完全な初心者がテンプレートもなしに０からサイトを作るのは難易度が高いと感じた。（制作時間のうち半分はデザインを考えていた）またコード自体も検索して出てきたコードをそのまま打ち込んだだけとういう部分もあるのでなぜここにこの値が必要なのかというのもふんわりとしかわかっておらず、まだまだ知識不足であると痛感した。
次回作る際にはもう少し学習をして挑みたい。
Node.js、Angularのビルド時間をgulpで短縮する

Node.js、Angularのビルドを順番に行っていると、プロジェクトが大きくなっていくのに伴い、時間がかかるようになります。
これを何とか少しでも短縮できないかと調べたところ、gulpを使う事で実現できそうなのでやってみました。

# パッケージのインストール
gulpとwebpack(Node.jsのwebpackに利用)に必要なパッケージをインストールします。
> npm install gulp webpack webpack-stream gulp-typescript --save-dev

# gulpfile.jsの作成
プロジェクトのルートに、gulpの動作を設定するgulpfile.jsを作成します。

```javascript:gulpfile.js
const gulp = require('gulp');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');
const gulpTypescript = require('gulp-typescript');
const exec = require('child_process');
const del = require('del');

const webpackConfig = require('./webpack.config');

const typescriptProject = gulpTypescript.createProject('./tsconfig.json');

// ビルドモジュールの削除
gulp.task('clean', () => {
    return del(['./dist']);
});

// Node.jsのビルド(webpack)
gulp.task('server', () => {
    return webpackStream(webpackConfig, webpack)
            .pipe(gulp.dest('dist/server'));
});

// Sequelize-Typescriptのmigrationファイルのトランスパル
gulp.task('db', () => {
    return gulp.src('./src/db/**/*.ts')
            .pipe(typescriptProject())
            .js
            .pipe(gulp.dest('./dist/db'));
});

// angularのビルド
gulp.task('angular', () => {
    return exec.exec('ng lint && ng build --ts-config ./src/app/tsconfig.json');
});

// clean=>server,db,angularの実行
gulp.task('default',
    gulp.series(
        'clean',
        gulp.parallel('server', 'db', 'angular')
    )
);
```

# gulpの実行
gulpを実行します。
> npx gulp

# package.jsonのbuildにnpx gulpを指定
package.jsonのscriptのbuildに、npx gulpを設定しましょう。
VisualStudio Codeだと、Ctrl+Shift+Bで実行できます。
```json:package.json
{
    "script": {
        "build": "npx gulp"
    }
}
```

# ビルド完了
Ctrl+Shift+Bでビルドしてみましょう。
> Executing task: npm run build <
> npx gulp
>[09:45:19] Using gulpfile gulpfile.js
>[09:45:19] Starting 'default'...
>[09:45:19] Starting 'clean'...
>[09:45:19] Finished 'clean' after 15 ms
>[09:45:19] Starting 'server'...
>[09:45:19] Starting 'db'...
>[09:45:19] Starting 'angular'...
>[09:45:25] Finished 'db' after 6.56 s
>[09:45:32] Version: webpack 4.29.0
>Built at: 2019-02-04 09:45:32
>        Asset      Size  Chunks             Chunk Names
>    server.js  32.6 KiB    main  [emitted]  main
>server.js.map  27.6 KiB    main  [emitted]  main
>Entrypoint main = server.js server.js.map
>[09:45:32] Finished 'server' after 13 s
>[09:45:46] Finished 'angular' after 27 s
>[09:45:46] Finished 'default' after 27 s

この例で言うと、dbとserverとangularのビルドを並列で実行しているので、20秒ほど短縮されたことになります。
そもそも RPC ってなんだ

## RPC とは

```
y = f(x)
```

みなさんがいつも行っているこれです。

具体的にすれば、

```php:server.php
$userName = DB::table('users')->find($userId)->name;
```

こう。なんでも良いんですけど。

この「関数呼び出し」を、実はローカルではなく **別の環境に接続して代わりに実行しよう** 、というものが Remote Procedure Call です。

上記のデータベース取得も、別の環境(DB)に接続して代わりに取得しているので RPC っぽいです。

厳密には、別の環境側でも同じような形で関数が呼ばれるものが RPC となります(上記の例だと SQL に変換して送信するので RPC ではない)。

## RPC の居場所

```ts:client.ts
const username = await (await fetch(`/users/${userId}/name`)).text()
```

クライアントからサーバにデータを取得しにいったり、

```ts:client.ts
await fetch(`/users/${userId}/name`, {
  method: 'PATCH',
  body: 'newHero',
})
```

サーバのデータを更新したりすることはよくあると思います。

でも、わかりづらいですよねこれ。

どうしてわかりづらいかって、

- どのパスがどんな動作を提供しているのかわからない
- どんな値を渡すのか、どんな値が返ってくるのかわからない
- もう何もわからない

つらい。

クライアントとサーバの距離感は遠く離れ、惑星間で通信を行うような気持ちになります。

そこをラッパーでなんとか名前と型を付けて紐付けようとするのがよくあることです。

```ts:client.ts
const username = await Server.getUserName(userId)
```

```ts:client.ts
await Server.updateUserName(userId, 'newHero!')
```

ずいぶんわかりやすくなりました。

名前と型をつけることによって、謎は闇に消え去りました(かのように見えます)。

---

この状態である程度通信わかりづらい問題は、クライアント目線では解決出来ています。

しかし、反対側であるサーバはどうでしょう。

```php:server.php
Route::get('/users/{userId}/name', function (req, res) {
  return DB::find(req.userId)->name; 
});
Route::patch('/users/{userId}/name', function (req, res) {
  $user = DB::find(req.userId);
  $user->name = req.body;
  $user->save();
});
```

うわー、わかりづらい！

クライアントの要求に答えていたら、わからないことだらけになってしまいました。

サーバは基本的に「リクエストを受け付け、レスポンスを返す」なので、 `y = f(x)` である所の `f(x)` を実装します。

```php:server.php
function getUserName(int $userId): string {
  return DB::find($userId)->name;
}
function updateUserName(int $userId, string $newName): void {
  $user = DB::find($userId);
  $user->name = $newName;
  $user->save();
}
```

おお、これも名前付けと型付けによってわかりやすくなりました。

---

あれ、ちょっと待ってください。

よく見たら、同じ関数がクライアントにもサーバにもありませんか？

はい、これが **Remote Procedure Call** です。

サーバが実装している関数を、クライアントが叩く。逆も OK です。サーバから別のサーバに RPC を叩くことも良く行われます。

サーバとクライアントで惑星間くらいの距離感があったのが、 RPC のおかげで近所くらいまで近づいた気がします。

RPC を使うだけだと「お手軽嬉しい仲良し機能！」なんですが、 **RPC 自体の実装をするとなると結構過激** です。

「静的に型をつけつつ、クライアントとサーバで整合性を常に取れるようにする」という厳しい要件を達成するため、歴史的に難しい様々な実装がなされてきました。

インターフェース記述言語(IDL)という新しい言語を用意して、そこに関数のインターフェースを記述し、そのファイルからクライアント・サーバ双方の言語に合わせたコードを生成するのが一般的です。

[ONC-RPC](https://ja.wikipedia.org/wiki/Open_Network_Computing_Remote_Procedure_Call) や [SOAP](https://ja.wikipedia.org/wiki/SOAP_\(%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB\)) 、 [XML-RPC](https://ja.wikipedia.org/wiki/XML-RPC) や最近だと [Protocol Buffers](https://ja.wikipedia.org/wiki/Protocol_Buffers) なんかが人気のようです。

## MagicOnion

[Cysharp/MagicOnion](https://github.com/Cysharp/MagicOnion) という新しい RPC ライブラリが最近登場しました。

これは **クライアント・サーバ共に C# のみ** 、という縛りを設けることにより、**「C# のインターフェースを定義するだけ」** で RPC を実装出来てしまうという凄いものです。

C# の静的型付けに関する豊富な機能のおかげで、 IDL すら不要にしてしまいました。

ここまで距離が近づくと、クライアントとサーバはもう親友ですね。

## 参考資料

- [遠隔手続き呼出し - Wikipedia](https://ja.wikipedia.org/wiki/%E9%81%A0%E9%9A%94%E6%89%8B%E7%B6%9A%E3%81%8D%E5%91%BC%E5%87%BA%E3%81%97)
- [Cysharp/MagicOnion: Unified Realtime/API Engine for .NET Core and Unity.](https://github.com/Cysharp/MagicOnion)
画像の背面に隠れる要素のクリックを有効にしたい

## 概要
例えば日本地図のイメージマップをつくって、クリックするとツールチップを表示させたい。でもツールチップとイメージマップを繋ぐ線に透過pngを使っていると、背面にある<area>タグがクリックできなかったりします。

前面にある要素が邪魔して背面の要素がクリックされない。。
これをなんとかして有効化したい。。


そんな場合でもしっかりプロパティが用意されていました。
今回は自分用の備忘録になりそうです。


## 解決方法
**ズバリ`pointer-events: none;`です。**
これを前面要素につけるだけ。`z-index`は関係ありません。(かといって取ってしまわないように..スタイルが崩れてしまいます。)

```style.scss
.tooltip{
/* {{略}} */
    &:after {
        content: "";
        display: block;
        width: 140px;
        height: 54px;
        background: url($imgurl + "fukidashi.svg") no-repeat center center / contain;
        position: absolute;
        left: -70px;
        bottom: 10px;
        pointer-events: none; /* これがポイント */
    }
}
```

### あとがき
無理！と思うことは大体できる。。(時間があれば)
と日々感じさせられます😊

**〜引用元〜**
https://qiita.com/riocampos/items/43b8c47e14d63dc6f6a4
今回は上記の記事を参考にさせていただきました！
ABテストで極大値に陥る問題

# この記事は
ABテストで小さい変更を繰り返すだけでは極大値にしかたどり着かないのでは？　と思ったので調査、まとめ

参考文献
[How to Get Over Local Maximum? Everyone Hits It Eventually](https://conversionxl.com/blog/local-maximum/)
[Radical Redesign or Incremental Change?](https://www.nngroup.com/articles/radical-incremental-redesign/)

# まとめ
##🚶原則小さい変更を繰り返し実施すること
小さいテストを繰り返すメリット

* 結果が見えやすい
* 複利で大きな結果が期待できる
* ユーザを混乱させるリスクが低い
* 開発者にアジャイルな文化が根付く

## 🏃大きな変更を実施するタイミングは？
* 小さな変更による改善が見られなくなってきている、極大値にはまっている場合
* システムが古すぎる場合（スマートフォン非対応など）
* サイトの統一感がすっかり無くなってしまっている場合
* サイト全体のCVRが低すぎて、もはや小さな変更ではどうにもならない場合
* 競合他社よりはるかに劣っている場合

## 🤔そもそも「大きな変更」とは何か？

* ページ全体の再設計
* 事業・コンセプトの変更
* フロー内の横断的な変更（ステップ数を減らすなど）

これらを含まないものが「小さな変更」。

## ❗大きな変更を入れる上での注意
### ユーザの動向を理解しておくこと
* 日々の監視によるユーザ理解
* 小さな変更によるABテストからのユーザ理解

### 必ずABテストを実施すること
* 大胆な変更で顧客を大量に失った例 http://readwrite.com/2010/09/23/digg_redesign_tanks_traffic_down_26

### 科学的な方法論と直感的な感覚の両方が必要
* 科学志向のテスト方法論を知っておくこと
* しかし全てを計算して作れるわけではなくやはり直感的感覚も求められる

### 「隣の芝は青い」との戦い
* モダンにすればKPIが向上するとは限らない
* 「何年も更新していない」「古くて素人っぽい」という理由だけで大胆なリデザインをするのは危険

### ユーザに学習コストが発生する
* ユーザーを新しいインターフェースに切り替えるコストが発生する
* もし戻すことがあれば再度学習コストが発生する
緯度経度からストリートビューで建物の画像を取得する

この記事は
===

* 建物の緯度経度だけがわかっている状況から、Googleストリートビューを使ってその建物の画像を取得してみたので備忘録です

やりたかったこと
===

* 単純に建物の緯度経度をずらっと持っていて、その建物の画像を入手したかったです
* 今回は仮にジロリアン希代の名店[ラーメン二郎 目黒店](https://tabelog.com/tokyo/A1316/A131601/13003449/)の外観画像を入手したかったと仮定しておきます


Street view static API
===

* もともとGoogleが[緯度経度から画像を取得するAPI](https://developers.google.com/maps/documentation/streetview/intro)を準備しています
* GCPの設定で上記APIを有効化すると使えます
* こんな感じでURLを組み立てれば表示ができるようで、おおこれだ！となりました

```
https://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,-73.988354
&fov=90&heading=0&pitch=10
&key=YOUR_API_KEY
```


しかし
===

* うきうきしながらジオコーディングサイトで、ラーメン二郎目黒店の住所を ```35.634192, 139.707051``` の緯度経度に変換して、上記URLに入れ込んでみました

![jiro_meguro_road.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27361/d879d815-3fc7-9409-33b7-fcbded3ab500.jpeg)

* 道ですね
* どうやら上記URLの ```heading``` というパラメータがカメラの角度を示しているみたいです
* デフォルト0 (=真北) なので全然違う方向を向いちゃってるわけですね

headingを計算する
===

* ブラウザから該当の緯度経度をストリートビューで表示すると、いい感じに建物が表示されているのですが、このAPIはそこまで親切ではないようです
* どうも自分で角度を計算して指定する必要があるっぽい
* で、その辺りを作ったのが下記コードです
  * 下記では１件だけですが複数件まとめて順序通り取得できるようにPromiseとかasync/awaitかましたりしてます
  * このへんは必須ではありません

```javascript

var latlngs = [
  [35.634192, 139.707051] //ラーメン二郎目黒店
];

var service = new google.maps.StreetViewService();
async function start() {
  for(var i = 0; i < latlngs.length; i++) {
      var latlng = latlngs[i];
      var lat = latlng[0];
      var lng = latlng[1];
      var targetLatLng = new google.maps.LatLng(lat, lng);
      await new Promise(function(resolve) {
        service.getPanoramaByLocation(targetLatLng, 1000, function(panoData){
            panoramaLatLng = panoData.location.latLng;
            var heading = google.maps.geometry.spherical.computeHeading(panoramaLatLng, targetLatLng);
            var url = "https://maps.googleapis.com/maps/api/streetview?size=1024x1024&location=" +
              lat + "," + lng +
              "&fov=90&heading=" + heading +
              "&pitch=10&key=YOUR_API_KEY"
            console.log(url);
            resolve();
        });
      })
  }
}
start();
```

* ポイントは下記でheadingを計算しているところです
* 撮影地点の緯度経度と建物の緯度経度を付き合わせて、グリッと回す角度を計算してくれてるみたいです

```javascript
var heading = google.maps.geometry.spherical.computeHeading(panoramaLatLng, targetLatLng);
```

* これを実行するとJavaScriptコンソールにURLが表示されます
* それを開いてみたのがこちら
![jiro_meguro.jpeg](https://qiita-image-store.s3.amazonaws.com/0/27361/0b3390d9-59d3-b578-86a4-82af2c58b6f4.jpeg)
* きたー

終わりに
===

* これでいろんな二郎の外観画像をたくさん収集できますね
* 巡礼系のサイト作ったりするときに役にたつかもしれません
Apache Benchテスト

#サーバの性能測定をしてみました

参考[Apache Benchでサクッと性能テスト](https://qiita.com/flexfirm/items/ac5a2f53cfa933a37192)

簡単に二つのインスタンスタイプの比較をしてみました
t2.micro
t2.medium

ab -n 10000 -c 1000  http://****/***

Failed requests:        0
Failed requests:        0

Requests per second:    630.44 [#/sec] (mean)
Requests per second:    648.42 [#/sec] (mean)

大まかに同じような結果が見られたが、ロードバランサで負荷分散するとリクエストの半分くらい処理に失敗します、、、
Rubyに配列の差分を取得するメソッドを追加する

ググったらこういう方法が出てきて、もっと簡単にできるのになーと思い投稿。
https://qiita.com/giiko_/items/381d31647b80d52edad9

実現方法

```rb
class Array
  def diff(values)
    (self | values) - (self & values)
  end
end
```

使い方

```rb
> [1,2,3,"a","b"].diff([1,2,3,"a","b"])
=> []
> [1,2,3,"a","b"].diff([1,3,"a"])
=> [2, "b"]
> [2,3,"b"].diff([1,2,3,"a","b"])
=> [1, "a"]
```
Rails ActiveRecordで任意のソートカラム・順指定をセキュアに実装してみた（下書き中）

本当にこのアプローチが正しいか検討しながら書いているのであしからず。
[sanitize_sql_for_order](https://api.rubyonrails.org/classes/ActiveRecord/Sanitization/ClassMethods.html#method-i-sanitize_sql_for_order)を使えばいいんじゃ？という説もあり

```rb
# Contorollerなどで
# SQLインジェクションできる実装
User.where(name: "Name").order(params[:f]=>params[:o])

# SQLインジェクション対策された実装
User.where(name: "Name").safe_order(params[:f], params[:o])
```

safe_orderメソッドは下記のように実装しています。

```rb
module SafeOrder
  extend ActiveSupport::Concern

  included do
    scope :safe_reorder, -> (key_string, order_string, **args) {
      if string = self.safe_order_string(key_string, order_string, **args)
        reorder(string)
      end
    }
    scope :safe_order, -> (key_string, order_string, **args) {
      if string = self.safe_order_string(key_string, order_string, **args)
        order(string)
      end
    }
  end

  class_methods do
    def safe_order_string(key_string, order_string, **args)
      args = {safe_keys: []}.merge args

      safe_keys = self.column_names.push(args[:safe_keys].map(&:to_s)).flatten.uniq
      _key = ([key_string.to_s.downcase] & safe_keys).first
      _order = ([order_string.to_s.downcase] & ["asc", "desc"]).first

      if _key.present? && _order.present?
        "#{_key} #{_order}"
      else
        raise "order by unknown keys" if Rails.env.development? || Rails.env.test?
        nil
      end
    end
  end
end
```