OmniAICreator/Qiita-1.07M huggingface dataset:
今年の言語はRust その３３


# 今年の言語はRust その３３

Rustを学びます

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル(英語)
https://doc.rust-lang.org/book/


## 実行環境

```sh
$ cargo -V
cargo 1.33.0 (f099fe94b 2019-02-12)

$ rustup -V
rustup 1.17.0 (069c88ed6 2019-03-05)

$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

$  cat /proc/version
Linux version 4.14.97-74.72.amzn1.x86_64 (mockbuild@gobi-build-64002) 
(gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC)) 
#1 SMP Tue Feb 5 20:59:30 UTC 2019

$ uname -a
Linux ip-10-100-0-8 4.14.97-74.72.amzn1.x86_64 
#1 SMP Tue Feb 5 20:59:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/\*release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Amazon Linux AMI release 2018.03

```



## 12 入出力プロジェクト
コマンドラインプログラムを構築する

### 12.6　標準出力ではなく標準エラーにエラーメッセージを書き込む

__標準出力__ と __標準エラー__

みなさん使い分けていますか？

使い分けきれますか？

私は使い分けきれません。

学びます。


#### エラーが書き込まれる場所を確認する


わざとエラーを起こして、標準出力を確認します


```bash
$ cargo run > output.txt

// 何も表示されない
```

output.txt

```txt
Error: not enough arguments
```

現在エラー文は__標準出力__ に出力されています

>そうです。エラーメッセージは標準出力に出力されているのです。このようなエラーメッセージは標準エラーに出力され、 成功した状態のデータのみがファイルに残ると遥かに有用です。それを変更します。


#### エラーを標準エラーに出力する

__めちゃくちゃ簡単((((；ﾟДﾟ))))ｶﾞｸｶﾞｸﾌﾞﾙﾌﾞﾙ__

```rust
println!("Error: {}", err);
```

を

```rust
eprintln!("Error: {}", err);
```
にするだけ。。

__e__ println

__めちゃくちゃ簡単((((；ﾟДﾟ))))ｶﾞｸｶﾞｸﾌﾞﾙﾌﾞﾙ__


めちゃくちゃ簡単！！！！！！！！

この章終わり！！！！！！！


Rust最高！


イエス！
ツイッターの動画をダウンロードできるサービスを作った話

# この記事について
更新情報などを書くのでアプデしたら毎回編集します。
[アクセスはこちらから](https://tweet-media-viewer.herokuapp.com/)

# 更新情報
2019/06/04 APIの脆弱性を修正したv2を公開
2019/06/02 APIの提供を開始
2019/04/22 鍵アカウントの取得に対応
2019/04/21 サービスリリース！
2019/04/20 開発開始

# なんで作ったのか
知り合いがツイッターの動画ダウンロードできたらいいなーって言ってたので作った。
他にも似たようなサービスはあるが、初心者などには使いづらいものばかりだったので色々改良した。

# 制作期間
2日です。はい。
前に作っていた[LastTweetViewer](https://last-tweet-viewer.herokuapp.com/)を改造したので短期間で終わった。

# 工夫
- iOSユーザーの初心者にも簡単にダウンロードできるようにショートカットから作成
- 説明を書きまくった

# 問題点(& Todoリスト)
- ~~非公開ユーザーのツイートはダウンロードできない~~
    - 非公開ユーザーのツイートは非公開アカをフォローしているアカウントでログインすることで解決
- ~~TwitterAPIの仕様で毎回mp4ファイルのJSONの位置が変わる~~
    - 対策しまくったおかげでなんとかなった<-!?
- アダルト系の動画をダウンロードされた
- そもそも認知度が低いのでユーザーが少ない
CSSのみで作る蛇腹型横スライド

むかしむかし、メインビジュアルを蛇腹のように折りたたみ、マウスオーバーするとビジュアルを大きく表示させるものをよく見かけました。
今はCSSだけで実現できますが、言ってしまえばただの「プルダウンの横版」って感じです。
メインビジュアル内に印象的に且つナビゲーション機能や補足情報を盛り込みたい時に使えるかもしれません。
スマートフォンではマウスオーバーの概念が無いのと、幅が狭いのでキツキツかもしれませんが。。。

ポイントは下記3つ。

- 画像は背景に指定
- 初期は等分割した幅を指定
- マウスオーバー時はそのボックス内の幅を指定

##DEMO
[デモはこちらから](https://tekutekustudio.com/demo)
※現状PCでしか動作しません。
スマートフォンはマウスオーバー概念が無いので、JSで処理する必要があります。

##CODE

###HTML
```html
<div class="mv-Accordion">
	<div class="mv-Accordion__box"></div>
	<div class="mv-Accordion__box"></div>
	<div class="mv-Accordion__box"></div>
	<div class="mv-Accordion__box"></div>
</div>
```

###CSS
```css

.mv-Accordion {
	width: 100%;
	height: 100vh;
	display: flex;
}
.mv-Accordion__box {
	width: 25%; /*初期の幅*/
	background-position: center center;
	background-repeat: no-repeat;
	background-size: cover; /*いかなるアスペクト比にもすべてが表示されるように指定*/
	transition: width 1s; /*アニメーションの秒数*/
}
.mv-Accordion__box:hover {
	width: 50%; /*マウスオーバーしたときの幅を指定*/
}
.mv-Accordion__box:nth-child(1) {
	background-image: url('../images/ph_1.jpg');
}
.mv-Accordion__box:nth-child(2) {
	background-image: url('../images/ph_2.jpg');
}
.mv-Accordion__box:nth-child(3) {
	background-image: url('../images/ph_3.jpg');
}
.mv-Accordion__box:nth-child(4) {
	background-image: url('../images/ph_4.jpg');
}
```

##対象ブラウザ
Edge、IE11、Chrome、Firefox、Safari
Handlerに引数を追加したい時


Handlerに引数を追加したい時のための対応方法です。
なお、利用価値は **<font color="Red">たぶんない</font>** です。


```go:main.go
package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

    router.GET("/suzuki", GetSampleSuzuki)
}
func GetSampleSuzuki(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"message": "Hello!"})
}
```

上記のようなソースがあった時に、`GetSampleSuzuki`に引数を追加する方法を記述します。



##元々のソース

```go:main.go
package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()

	router.GET("/suzuki", GetSampleSuzuki)
	router.GET("/tanaka", GetSampleTanaka)
	router.Run(":8080")
}

func GetSampleSuzuki(c *gin.Context) {
	user := "Suzuki"
	title := "ほげほげ"
	c.JSON(http.StatusOK, gin.H{"message": "Hello!", "user": user, "title": title})
}

func GetSampleTanaka(c *gin.Context) {
	user := "Tanaka"
	title := "ほげほげ"
	c.JSON(http.StatusOK, gin.H{"message": "Hello!", "user": user, "title": title})
}
```

実行すると、以下の結果が返ってきます。

localhost:8080/suzuki

```json:json
{
message: "Hello!",
user: "Suzuki",
title: "ほげほげ"
}
```


localhost:8080/tanaka

```json:json
{
message: "Hello!",
user: "Tanaka"
title: "ほげほげ"
}
```


userだけ違うだけで、ロジックは、ほぼ同じです。
これを共通化するために、以下のように変更しました。

## 修正後のソース

```go:main.go
package main

import (
	"net/http"
	"github.com/gin-gonic/gin"
)

func main() {
	router := gin.Default()

	router.GET("/suzuki", Adduser(GetSample))
	router.GET("/tanaka", Adduser(GetSample))
	router.Run(":8080")
}

func Adduser(fn func(*gin.Context, *string, *string)) gin.HandlerFunc {
	return func(c *gin.Context) {
		user := c.Request.URL.Path[1:]
		title := "ほげほげ"
		fn(c, &user, &title)
	}
}

func GetSample(c *gin.Context, user *string, title *string) {
	c.JSON(http.StatusOK, gin.H{
		"message": "Hello!",
		"user":    *user,
		"title":   *title,
	})
}
```

### 共通の関数(Adduser)の用意

まず、GetSampleSuzuki と GetSampleTanaka を共通化するために
`GetSample`を用意します。
引数は、`c *gin.Context` に加え、`user *string, title *string`を追加します。

`func GetSample(c *gin.Context, user *string, title *string) `のような形になります。

さらに呼出し元の `router.GET("/suzuki", GetSampleSuzuki)`の部分を
`router.GET("/suzuki", Adduser(GetSample))`のように変更し、共通の処理が行えるようにします。

Ginの`GET`の定義をみると、引数が`HandlerFunc`になっているので
'Adduser`の戻り値に`HandlerFunc`を返すようにします。
つまり、いつもの`func(c *gin.Context)`を返しようにします。
さらに、先ほど追加した'GetSamaple'と同じ引数の関数を呼び出すようにします。

よって、`func Adduser(fn func(*gin.Context, *string, *string)) gin.HandlerFunc `の形になります。

### 共通の関数(Adduser)の内容

いつもの `*gin.Context`をreturnし、 `HandlerFunc` を返すようにします。
その関数の中で、共通のuserとtitleの処理を追加し、引数の `fn func(*gin.Context, *string, *string)`の形式で`fn(c, &user, &title)` を返します。


#まとめ

以下のような形式で作成・対応できます。

```go:

func main() {
    router := gin.Default()
    router.GET("/suzuki", Adduser(GetSample))
}

func Adduser(fn func(*gin.Context, [型])) gin.HandlerFunc {
	return func(c *gin.Context) {
           // 追加した引数に対する処理
           fn(c, <引数名>)
	}
}

func GetSample(c *gin.Context, <引数名> [型]) {
         // 何かの処理
}
```

どのような場面で使うかは考えていません。
そもそも、以下の処理で名前の取得は可能だし。

```go:
func main() {
    router := gin.Default()
    router.GET("/:name", GetSample)
}

func GetSample(c *gin.Context){
        name := c.Param("name")
}
```
色々あってRSpecのstubで副作用を生み出したいとき

```ruby
allow(dbl).to receive(:foo) { do_something }
allow(dbl).to receive(:foo).with("args") { do_something }
allow(dbl).to receive(:foo).once { do_something }
allow(dbl).to receive(:foo).ordered { do_something }
```

`do_something`で何かをすればいい。
block の戻り値がその`stub`の戻り値になるので、同時に`and_return`は使えない。

参考: https://relishapp.com/rspec/rspec-mocks/v/3-8/docs/configuring-responses/block-implementation
EclipseでAzure Functions(Java)をデバッグする

EclipseでAzure Functions(Java)開発時のデバッグ方法です。
7071ポートが開放されない事象にあたったので、解決法を残します。

# 前提
* Azure Functionsがローカル実行できていること

# ブレークポイント設定

* Eclipseでブレークポイントを設定します。

# デバッグ実行

* コマンドプロンプトを開いて、以下コマンドを実行します。
    * EclipseからMavenプラグインを使って実行した場合、プロジェクトの実行を停止したときにfunc.exeが停止できずに残り続けます。結果、7071ポートをつかみ続けることになるため、コマンドプロンプトからmvnコマンドを実行しています。

```
mvn azure-functions:run -DenableDebug
```

* Eclipseを開いて、[実行]→[デバッグ構成]を選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/703c0e9c-d3c6-75ff-6ce2-6561810fa65c.png)

* [リモートJavaアプリケーション]を右クリックして[新規作成]を選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/b8120e7a-2346-dba1-86ad-46bdaa5c6caf.png)

* ポートを[5005]に設定して[デバッグ]ボタンを実行します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/f5e07120-9dda-b326-6bb8-047c1459597e.png)

* HTTPTriggerなりのイベントを発火させて、Functinosを実行させます。
* Eclipseでデバッグモードが起動すればOKです。

# 7071ポートが掴みっぱなしになったら・・・

* タスクマネージャーを開いて、func.exeプロセスを終了させればOKです。
ABC091 C - Flip,Flip, and Flip...... (300点)

#問題概要
[問題のリンク](https://atcoder.jp/contests/arc091/tasks/arc091_a)

$N$ 行 $M$ 列のマス目が与えられる。全てのマスの上にはカードが表になって敷き詰められている。

以下の操作を全てのマスについて一回ずつ繰り返す。
**「そのマスと辺または点で接する $8$ つのマスと、そのマスの合計 $9$ マスについて、カードが存在するなら裏返す。」**

全ての操作を行った後、裏になっているマスの数はいくつか。

#制約条件
- $1$≤$N,M$≤$10^9$
- 入力は全て整数である

#考えたこと
実験してみればわかるが、操作が奇数回行われれば、ウラになり、偶数回であればオモテになる。
よってそれぞれのマスについて操作が何回行われるか考えればよい。

自分含めて接しているマスの数と同じぶん処理が行われるので、四隅は4回、辺のマスは6回、それ以外のマスは9回処理が行われる。

(実験してみると以下のようなかんじ)
![IMG_1311.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326440/7bcb995a-4296-5f6e-6dcb-115c1dfa709c.jpeg)

よって、四隅と辺のマスを重複なく数え上げて、元のマスの数との差をとればよい。
「行または列が1」と「行と列が1」のコーナーケースがあることと桁溢れに注意して書けばACである。

#解答
```c.cs
using System;
using System.Linq;

class Program
{
    static void Main(string[] args) {
        long[] s = Console.ReadLine().Split().Select(long.Parse).ToArray();
        Console.WriteLine(solve(s[0], s[1]));
    }
    static long solve(long n, long m) {
        long count = 0;
        if(n==1 && m==1) count = 1;
        else if(n == 1 || m == 1) count = n * m - 2;
        else count = n*m - (2*(m+n)-4);
        return count;
    }
}
```
算術演算子%で余りがない場合には０が変数に入るのか

# 割り算で余りを求めるときに気になったこと

-算術演算子%で「余りがない」場合には「0」が変数に入るのか.
結論：「0」が入る

-Javaのプログラミングの課題に余りを表示せよというものがあった.
例えば、
・13を2で割ったときの余りは1　(13 % 2 = 1)
・45を7で割ったときの余りは3　(45 % 7 = 3)
ですよね.

では、割り切れる場合は何が表示されるのか.
・12 % 3 = ?
・66 % 11 = ? 

「0」なのか
「null」なのか
「空白」なのか

実験（割られる数：66、割る数：11）

```java:division.java

public class Main {
    public static void main(String[] args) {
        
        //割り算の数を取得（割られる数：dividend、割る数：divisor、余り：remainder）
        int dividend = 66;
        int divisor = 11;
        
        //余りの計算
        int remainder = dividend % divisor;
        
        //出力
        System.out.println(remainder);//0が出力される
    }
}
```

余りが数値で返るように演算子が作られているようです.
演算子自体がプログラムでどのように作られているのかが気になりました.
また勉強を重ねていきます.

#初投稿
-今回の投稿が初めての投稿となります.
社会人2年目が始まったばかりの駆け出しで大したことはできませんが、少しでも優れたエンジニアになりたいと思いアウトプットをしてみました。
背中を押してくれたきっかけは、技術書展6に足を運んだとき「ゼロから始めるアウトプット・ライフ～える子とボクと、時々、ロボ～」をいただき、読んでみたことです。
自分はこれからどんなエンジニアになっていくのかを考えたときにキャリアプランを立てることができず、不安ばかりでしたが、それはやめて、成長することでいろんなチャンスが巡ってくること、そのチャンスをものにできるエンジニアになることで将来のキャリアを積極的に描いていきたいと思います。
みなさんのご意見、ご感想、ご指摘、アドバイスをいただければ励みになります。
今後ともよろしくお願いいたします。
研究開発環境備忘録

# 概要
数値計算用のコードを書いていると、コードのバージョン管理とそのコードを使って計算したデータの管理を同時並行する必要があるが、自分人だと管理が適当になりがちである。管理が適当だとファイルが増えすぎて変なバグの温床になったり、どの段階のコードを使って計算したの
かなどが適当になりがちである。

そこで、自分が研究で使っている数値計算用のコードを整理して管理するための構成をまとめておく。

# やりたいこと
大まかな目的としては、次の通り。

 - 数値計算用コードの管理
    - モジュールやライブラリなどをまとめておく。
    - バージョン名を管理し、バージョンごとの変更点や修正点、問題点等をリストアップしておく。
 - 計算結果の管理
    - 計算用コードのバージョンごとに結果を管理する。
 - 計算結果を解析したものの管理
    - 結果を解析して得られた情報（図やグラフ、統計量etc）を、バージョンごとに管理する。


# 構成
上を踏まえて、次のように開発をする：

 - 数値計算用コードの管理
    - 計算用コード用にリポジトリを作る。リポジトリの内容は：
        - メインの計算用コード：主だった計算（MCMC）を行い、データをストックする。
        - 解析・表示用コード：MCMCの結果からデータを管理する。
 - 計算結果の管理
    - 計算用コードを別フォルダでcloneし、計算を開始する。
    - 計算結果はデータサイズが大きくなりがちだがGithub上だとファイルサイズの大きなデータは扱えないので、Google driveにデータをアップするようにする(GitLFSのほうがいいか？)。
 - 計算結果を解析したものの管理
    - 解析用コードは計算用コードと一緒に開発する。計算結果の解析も上の計算用フォルダで行う。
batの遅延環境変数についての備忘録

batで、if/forブロックの中で変数を取り扱う場合には注意が必要です。

通常、変数の値の読み出し時は```％var％```とします。
しかし、if/forブロック内で新たに
変数の値を変更した場合、これでは期待の値を得ることができません。

この現象の理由はbatではif/forブロック内の処理実行時に、
1. ブロックの最後の)までの読み出しを先に一気に行う
2. ブロック内の変数値を展開
3. ()中のループ処理へと入っていく
といった手続きが取られるためです。 

つまり、②の時点の変数の値が採用されるために
ループ内で変数の値を変更しても反映されないのです。

この現象を回避するには遅延環境変数を利用します。
ファイル冒頭へ、
```setlocal EnableDelayedExpansion```として、遅延環境変数を有効にした上で
変数の読出時には```!var!```とします。

これで②時点での変数読み出しを回避することができます。

```bat
@echo off
setlocal EnableDelayedExpansion

for  %%a in (*.txt) do (
	set name=%%a
	echo !name!
)

endlocal
```

*こちらも参照*
[batについての備忘録](https://qiita.com/mounntainn/items/a06d7c4038dfc38e3155#_reference-1b1a5b04613c8f628373)

参考
---
[batファイルでfor文内に変数を利用する場合の罠](https://blog.natade.net/2018/10/06/windows-bat-遅延環境変数-for-if/)
AWS Codecommit のリージョンを引っ越す

別に AWS Codecommit だけではなく、他の git リポジトリを別のサーバーに移行ができるという話し。

今回はヴァージニアリージョンにあるリポジトリを、東京リージョンへ移行させる。

## 簡単な流れ

1. 移行元の git ベアリポジトリをローカルに複製する
2. 移行先に git のベアリポジトリを作成する
3. ローカルに複製したベアリポジトリを、移行先のベアリポジトリに push する

## 作業の流れ
### 移行元の git ベアリポジトリをローカルに複製する

作業前の前提として、

* 移行元のベアリポジトリ: git-codecommit.us-east-1.amazonaws.com/v1/repos/your-repo-virginia
* 移行先のベアリポジトリ: git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo

と、既に移行元・移行先のベアリポジトリの操作ができる状態とする。

とする。

まずは、移行元のベアリポジトリを手元のローカルに複製する。

```shell-session
$ mkdir -p ~/git/bare
$ cd ~/git/bare
$ git clone --mirror ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/your-repo-virginia
Cloning into bare repository 'your-repo-virginia.git'...
remote: Counting objects: 98745, done.
Receiving objects: 100% (98745/98745), 807.93 MiB | 2.77 MiB/s, done.
Resolving deltas: 100% (98745/98745), done.
```

### 移行先に git のベアリポジトリを作成する

通常は github なり、AWS Codecommit を利用すると思うが、もし自ら用意するのであれば、こんな感じだろうか。
(既存のサービスを利用するのなら、この作業は必要ない)

git のベアリポジトリを運用するサーバーにログインをして、

```shell-session
$ sudo adduser your-repo-tokyo
$ sudo usermod -a -G your-repo-tokyo git
$ sudo su your-repo-tokyo -
$ mkdir ~/git/your-repo-tokyo.git
$ cd ~/git/your-repo-tokyo.git
$ git --bare init --shared
```

と実行する。

### ローカルに複製したベアリポジトリを、移行先のベアリポジトリに push する

```shell_session
$ cd ~/git/bare/your-repo-virginia.git
$ git remote add --mirror=push git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo git-codecommit.us-east-1.amazonaws.com/v1/repos/your-repo-virginia
```

と実行して、config に `git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo` の設定を追加する。
追加すると、こんな感じになっている。

```shell-session
$ cat ~/git/bare/your-repo-virginia.git/config
[core]
  repositoryformatversion = 0
  filemode = false
  bare = true
  symlinks = false
  ignorecase = true
[remote "origin"]
  url = ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/your-repo-virginia
  fetch = +refs/*:refs/*
  mirror = true
[remote "git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo"]
  url = git-codecommit.us-east-1.amazonaws.com/v1/repos/your-repo-virginia
  mirror = true
```

複製したベアリポジトリを、複製先に反映させる。

```shell_session
$ git push ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo
Counting objects: 98745, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (98745/98745), done.
Writing objects: 100% (98745/98745), 807.93 MiB | 4.45 MiB/s, done.
Total 26312 (delta 3123), reused 26312 (delta 3123)
remote: processing ...........
To ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo
 * [new branch]        master -> master
```

成功したら、他のブランチも反映させる。

```shell_session
$ git branch
  develop
  feature/20190422-your-branch
* master
  staging
$ git push origin
Total 0 (delta 0), reused 0 (delta 0)
To ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/your-repo-tokyo
 * [new branch]        develop -> develop
 * [new branch]        feature/20190422-your-branch -> feature/20190422-your-branch
 * [new branch]        staging -> staging
```
ABC - 038- A&B&C

#AtCoder ABC 038 A&B&C
[AtCoder - 038](https://atcoder.jp/contests/abc038)

#A問題

```java
	private void solveA() {
		String s = next();
		if (s.substring(s.length() - 1).equals("T")) {
			out.println("YES");
		} else {
			out.println("NO");
		}

		out.println("");
	}
```

#B問題

 - h1*w1のディスプレイと、h2*w2のディスプレイのhでもwでもどちらでもいいので長さが合えばよい。
 - set使ってloopまわしてもよかったかも、、、ifが多いのが既にちょっとなぁ

```java
	private void solveB() {
		int h1 = nextInt();
		int w1 = nextInt();
		int h2 = nextInt();
		int w2 = nextInt();

		if (h1 == h2 || h1 == w2 || w1 == h2 || w1 == w2) {
			out.print("YES");
		} else {
			out.print("NO");
		}

		out.println("");
	}
```

#C問題

 - 悩んだけど、累積和を使って解けた。多分、しゃくとり法でもいけると思う。

 - 組み合わせの数(重複組み合わせ)
    - {$1,2,3,4,5$} を $(1,2),(1,3),(1,4),(1,5),(2,2)...(5,5)$とするには、$n*(n+1) / 2 $
    - $nH_r = {n+r-1}C_r$
        - $nH_2 = {n+1}C_2$
            - $((n+1)\*n)/(2\*1)$
                - $((n+1)*n)/2$

```java
	private void solveC() {
		int numN = nextInt();
		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();
		long res = 0;
		long[] rui = new long[numN];
		int ruiCnt = 0;
		rui[ruiCnt] = 1;

		for (int i = 1; i < wk.length; i++) {
			if (wk[i - 1] < wk[i]) {
				rui[ruiCnt] += 1;
			} else {
				ruiCnt++;
				rui[ruiCnt] = 1;
			}
		}
		for (long i : rui) {
			/*
			 * 重複組み合わせ
			 * nHr=n+r−1Cr
			 *
			 * nH2 = n+1C2
			 *
			 * n*(n+1) /2
			 */
			long tmp = (i * (i + 1)) / 2;
			res += tmp;
		}
		out.println(res);
	}

```

#C問題：しゃくとり法

##参考
[しゃくとり法 (尺取り法) の解説と、それを用いる問題のまとめ](https://qiita.com/drken/items/ecd1a472d3a0e7db8dce)

 - 参考サイトを読んで。とてもわかりやすい（わかりやすいと自分が実装可能は別の話ですが）

 - 実際のところ、(1,1),(1,2),(1,3)...(5,5) という全ての組を一つ一つ数えているわけではない。
    - 具体的には、テストケース入力例1の場合の出力は(1,1),(1,2),(1,3),(2,2),(2,3),(3,3),(4,4),(5,5)となるが、
    - このロジックでは(left,right)=(2,2),(2,3),(3,3)は出現しない。

 - `res += right - left`　で該当箇所が出現しているとして回収している

```java
	private void solveC4() {
		int numN = nextInt();
		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();
		long res = 0;
		int left = 0;
		int right = 0;
		while (left < numN) {
			/*
			 * 継続条件
			 * １：問題文の条件
			 * wk[right - 1] < wk[right]
			 *
			 * ２：これも問題文の条件
			 * left == right
			 * ->
			 * left == right は条件を満たしているため
			 * 同じ位置の場合はrightを進める
			 */
			while (right < numN && (left == right || wk[right - 1] < wk[right])) {
				right++;
			}
			/*
			 * 差分を+していく
			 * (left , right]
			 */
			res += right - left;
			/*
			 * 左を進める
			 */
			left++;
		}
		out.println(res);
	}

```
VirtualBox に Ubuntu 19.04 をインストール

Arch Linux にインストールした Virtualbox に Ubuntu 19.04 をインストールしました。

インストールイメージは

```text
ubuntu-19.04-live-server-amd64.iso
```

1) VirtualBox の起動

```bash
virtualbox
```

![vm01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/cf9e815a-f7c5-2e42-c27d-331544d620d2.png)

2) New を選んで仮想マシーンを作成

![vm02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/0551647d-7cf1-1141-bead-3d5aef63eddd.png)

 ディスクサイズは、10GB にします。

![vm03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/44318033-363a-e78e-7c4b-3eeef47bf8fe.png)

ISO　イメージを選択します。

![vm04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/98b516b4-ff9c-d7e7-a61a-670d836337ce.png)

3) Ubuntu のインストールを始めます。

![vm05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/e653eabd-6d84-8af2-5bd5-a37d159d9813.png)

リブートします。

![vm06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/a2f2dcfd-691b-2eb6-32f3-cfc1a798f9ea.png)

4) コンソールからログインします。

![vm07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/be4bda75-1136-c2f3-1d59-49fbfec119eb.png)

5) ssh で接続する為に、ポートフォワードの設定をします。

![vm08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/efeef449-7e75-30a2-0b42-a3a118935f05.png)

「Settings」→「Network」→「Advanced」→「Port Forwarding」
Host Port 2000
Gest Port 22

![vm09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/f49f4444-a93c-8809-9768-040f0838921c.png)

6) ssh で接続します。

```bash
ssh -p 2000 uchida@localhost
```
[swift]UIView.animate()をしたら余計なアニメーションが追加されて困った

# はじめに

UIButtonをアニメーションさせたいと思い、`UIView.animate()`メソッドを実行したところアニメーション終了後に別の余計なアニメーションが加わり、全然思い通りに動いてくれませんでした。

随分長いこと悩まされたので備忘録的にメモ


# 原因

今回、`UIView.animate()`の他に`CAKeyframeAnimation`も併用して使っていたのですが、その際に`add(animation, forKey:)`していたアニメーションが残っていたようです。


# 解決法

適切な位置で`removeAllAnimation()`を呼び出すことで解決しました。


# 終わりに

検証はしていませんが、`UIView.animate()`を実行すると、`add(animation, forKey:)`されたアニメーションも一緒に実行される？みたいです。

まだそれぞれのanimationの違いもよくわかっていない状態なので、詳しい方がいたら教えていただきたいです......
【ワードプレス】記事毎に任意のcssやjsを挿入【カスタムフィールド】

プラグインを使わずに記事毎にcssやjsを挿入する方法。
ワープレ初心者自分用メモ。

<h3>1. テンプレートファイルの編集</h3>
通常、headタグの書き出しは`header.php`、body直前の書き出しは`footer.php`で行なっているようだ。
get_post_meta()を使用する。第二引数（`head_custom`と`body_custom`）が管理画面上の項目となる。

```header.php

// </head>前に追加
echo get_post_meta($post->ID, 'head_custom', true);
</head>
```

```footer.php
// </body>前に追加
echo get_post_meta($post->ID, 'body_custom', true);
</body>
```

<h3>2. カスタムフィールドの追加</h3>

WP管理画面の投稿編集画面の右上あたりから「表示オプション」を開き、「カスタムフィールド」をチェック。
head_custyomとbody_customを新規追加すると、以降選択できるようになる。
<img width="1273" alt="スクリーンショット 2019-04-22 18.26.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151314/9712096a-02ec-a9fd-9f8f-41e28281f6e0.png">

これで`get_post_meta()`を挿入した位置に値が展開される。
JavaScriptの引数の仕組みが分かってなかった件

# TL;DR


･代入元がObject型だった場合、引数には参照元のアドレスが格納される

# はじめに


この記事の経緯としては、  
下記記事を見ていたらこんなことが書かれていたから  
[3歳娘「パパ、もう参照渡しの話はやめて？」](https://qiita.com/Yametaro/items/45dbfd7f544a69ea7b36)

>ワイ「関数の中で配列aに要素を追加したり、一部を編集したりした場合は外のaにも変更が>反映されるけど」  
>ワイ「丸ごと上書きしてもうた場合は別もんになるから、外のaには影響なしや」  


なんで丸ごと上書きした場合は別物になるのかが分からなかった。  
というのがきっかけ


## よく分からんからソース書いて


・ 分かる

```javascript
(function(){
	let ary = new Array(0,0,0,0,0,0,0,0);
	f(ary);
	console.log("ary："+ary);
}());


function f(obj){
	obj = "aaa";
}

```

```
ary：0,0,0,0,0,0,0,0
```

・ 分からん

```javascript
(function(){
	let ary = new Array(0,0,0,0,0,0,0,0);
	f(ary);
	console.log("ary："+ary);
}());


function f(obj){
	obj[0] = "aaa";
}

```

```

ary：aaa,0,0,0,0,0,0,0

```


# 調べた結果


で調べているうちに下記記事を見つけた  

[JavaScriptはオブジェクトについて参照渡しだなんて、信じない](https://qiita.com/mozisan/items/1b9d4bf5a1bb341dd354)  


これを見て、引数がオブジェクト型の時の挙動が思っていたのとは違った  
今までは引数に配列を渡すと配列の値を直接いじっていると思っていたが、  
ここに入っているものはあくまで参照元のアドレスのコピーが入っているっぽい  
確かにそう考えるとすっきりする


# 試す

そもそもこれは別に関数の引数だけに限ったことではなく・・・  

・ 例１

```javascript
(function(){
	
	let val1 = {id:"123",name:"val1"};

	//val1のアドレスをval2に渡す
	val2 = val1;

	//id書き換え
	val2.id = "456";

	console.log(val1.id);
	console.log(val2.id);
}());
```

```
val1：456
val2：456
```

・ 例２

```javascript
(function(){

	let val1 = {id:"123",name:"val1"};

	//val1のアドレスをval2に渡す
	val2 = val1;
	
	//プロパティ追加
	val2.from = "japan";

	console.log("val1："+val1.from);
	console.log("val2："+val2.from);
}());
```

```
val1：japan
val2：japan
```


・例3

```javascript
(function(){

	let val1 = {id:"123",name:"val1"};

	//val1のアドレスをval2に渡す
	val2 = val1;
	
	//val2に文字列を代入
	val2 = "書き換え";

	console.log("val1："+val1);
	console.log("val2："+val2);
}());
```

```
val1：[object Object]
val2：書き換え
```

・例4  


```javascript
(function(){

	let val1 = {id:"123",name:"val1"};

	//val1のアドレスをval2に渡す
	val2 = val1;
	
	val1 = "";

	console.log("val1："+val1);
	console.log("val2："+val2);
}());
```

これで参照元のObjectは潰したし、val2も参照できなくなるやろ・・・  


```
val1：
val2：[object Object]
```

なくならんやんけ・・・・・・・・・・  


この辺は多分メモリーリークとかに関連する話で、  
JavaScriptにはガベージコレクションというその変数が使用されなくなると自動的に  
メモリを開放してくれる仕組みがあるが、val2がそのオブジェクトをまだ使っている！  
みたいな判定をしているので現段階ではまだメモリ上にあのオブジェクトが残っているという・・・  


まぁここは今回関係ないから今度また・・・  


# まとめ

引数がオブジェクトの場合アドレスが格納されているので、  
添え字やプロパティーで代入先を指定した場合には変更が適用される。  


何も指定せずまるっと変更した場合は元々入っていたアドレスが消える為  
オブジェクトの変更が適用されない  


# 参考URL


[3歳娘「パパ、もう参照渡しの話はやめて？」](https://qiita.com/Yametaro/items/45dbfd7f544a69ea7b36)  
[JavaScriptはオブジェクトについて参照渡しだなんて、信じない](https://qiita.com/mozisan/items/1b9d4bf5a1bb341dd354)  
[JavaScriptに参照渡し/値渡しなど存在しない](https://qiita.com/yuta0801/items/f8690a6e129c594de5fb)
リモートデスクトップがうまく接続できない時の対処法（レベル認証の確認）

リモートデスクトップを使用する際に、リモートコンピューターの電源を入れているかつネットワークに接続しているにも関わらず、
以下のようなエラーで指定のPCに接続できない場合の対処法。

![-ca7e9750-e41a-47dc-8560-860f9fc03cb6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386370/c08e17c9-5fc0-9450-2ce5-39a9f7e56efa.png)


リモートコンピュータのシステムプロパティのリモートの設定で以下の項目にチェックが入っていることを確認する。

![-83fcee66-3908-4042-8a34-186cc853ab19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386370/be3b89ed-9f41-6c56-e373-a24825883731.png)
pay.jp 継続課金のwebhookができない json

ほんと pay.jp 。
継続課金バグってるがね。

laravel　でも cakephp3 でもそうだが、
jsonを受信できるようにしないといけない。

例えば、pay.jpに登録したwebhook。
このアクセスが成功しなきゃだめ。

```

 https://your.com/payjps/webhook.json

```

ということで。

nginxの

```default.conf

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "POST, GET, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, Authorization, Accept";
add_header Access-Control-Allow-Credentials true;

```

を追加。

#cakephp3 の場合

これが大事ってのつけくわえる。
jsonも処理しろよって感じでね。

```

Router::defaultRouteClass(DashedRoute::class);
Router::extensions(['json']);//これが大事
Router::scope('/', function (RouteBuilder $routes) {

```

# laravel は忘れたので、また機会あれば。。。
shellでシングルクォートを使わずにJSONに変数を埋め込む

# はじめに

shellでシングルクォートを使わずにJSON内に変数を埋め込みたいときの方法メモ。

経緯としては、Dockerコンテナの実行時にcurlでJSONの送信をしたいが、bashのcオプションで指定するコマンド文字列をシングルクォートで囲んだ際に、JSON内の変数を展開させる方法でハマり、試行錯誤をした。

# 結論

以下のようにJSONを`"{\"key\":\"$VAR\"}"`と記述すれば、シングルクォートを使わずにJSON内で変数`$VAR`を展開することができた。

`Docker run [イメージ名:タグ名] /bin/bash -c 'VAR=$(hoge_val) && curl -X POST -d "{\"key\":\"$VAR\"}" "https://fugafuga_hogehoge"  -H "Content-Type:application/json"'`

# 参考

[bashでJSONに変数を埋め込むための3つの方法](https://dev.classmethod.jp/server-side/os/how-to-inject-variable-to-json-on-bash/)
[シェルスクリプトのシングルクオートとダブルクオート](https://qiita.com/tkms0106/items/4272ce690217c259739c)
Concourse で チームを使う

https://qiita.com/propella/items/86e1e932f27e9073a63b の続きです。

[Teams](https://concourse-ci.org/managing-teams.html) を使うと一つの Concourse サーバを複数の複数のプロジェクトで使い分ける事が出来る。

最初に fly login するとデフォルトでは main というチームで login している。Concourse 上に存在するチームを見るには、`fly teams` を使う。 -d で詳細。

```
$ fly -t tutorial teams -d
name
main
```

新しいチームを作るには `fly set-team` を使う。この例ではローカルユーザ `test`が入っているチーム `hoge-team` を作成する。`set-team` を複数回実行すると、最後の値で設定が上書きされる。

    fly -t tutorial set-team --team-name hoge-team --local-user test

チームにログインするには `fly login` を使う。`-n` は `--team-name` の代わり。

    fly login -n hoge-team

作ったチームを消すには `fly destroy-team` を作る

```
$ fly -t tutorial destroy-team --team-name hoge-team
!!! this will remove all data for team `hoge-team`
please type the team name to confirm: hoge-team
`hoge-team` deleted
```

Concourse では、github や gitlab など、様々なアカウントを使ってログインを行う事が出来る。詳しくは [Configuring Auth](https://concourse-ci.org/configuring-auth.html) に記載されている。

ちなみに、過去のバージョンでは `--allow-all-users` を使ってすべてのユーザがログインする team を作れたが、その後廃止されている。https://github.com/concourse/concourse/issues/2721
UniRx:一定間隔(Interval)で発行するObservableを停止・再起動させる。

UniRxは便利。
なんだけども、正直学習用の情報が少なく、親切に用意されている物が初心者に見えなかったりする。（まさに私）
UniRxを使ってみて、とりあえず躓いたのが一定間隔(Interval)で発行するObservableを停止させて、任意のタイミングで再起動させること。
とりあえず学習成果のコードは下記。

```C#
using UniRx;
using UniRx.Triggers; 
using UnityEngine;

System.IDisposable  hoge_obs;//クラス変数宣言

void Stream_start(int hoge_msec){
      hoge_obs = Observable
      .Interval(System.TimeSpan.FromMilliseconds(hoge_msec))
      .Subscribe(_ =>{
                 //一定間隔で実行する何か   
            });
}

void Stream_stop(){
      hoge_obs.Dispode();
}

void Start(){
//ZONEに侵入しら一定間隔実行開始
      this.OnTriggerEnterAsObservable()
      .Where(x => x.gameObject.tag == "ZONE")
      .Subscribe(_ => {
             Stream_start(100);
             });
//ZONEから出たら停止
      this.OnTriggerExitAsObservable()
      .Where(x => x.gameObject.tag == "ZONE")
      .Subscribe(_ => {
             Stream_stop();
             });
}

```

Observableをvarで宣言するとローカル関数なので、System.IDisposableとしてクラス変数宣言したところがポイント。
これが出来れば時間を変えながら一定間隔実行できるようになる。動き物を書くときとか大分楽になるはず。

でもやっぱりローカル関数の方が色々安全なのかなと初心者的に思ったりしますが、どうなんでしょうか。
もっと良い方法はある気がする。
あったら誰か教えてください。
Andrew Ng on Building a Career in Machine Learning を訳してまとめてみた（前編）

##はじめに
今回は、Andrew Ng 氏による、 Building a Career in Machine Learning という動画を前編・後編でまとめてみました。

- 前編: AI 分野におけるキャリア形成についてのまとめ
- 後編: [AI 分野における Andrew Ng 氏への質問と回答のまとめ](https://qiita.com/Yoshiyuki03/items/f3159317cf01eaf17858)

動画自体は約1時間と少し長めですが、興味のある方は本編もご覧になってみて下さい。
本編は[ここから](https://www.youtube.com/watch?v=4kiHsIaK9_w)どうぞ。

##Andrew Ng on Building a Career in Machine Learning

####AI の学び方について
- AI分野を学んでいく上で重要になるのは守備範囲を広げることと知識の深さを求めることの2点
- 分野についてはコース学習や論文で知識を習得
- 知識の深さは企業で働く中での実案件を経験すること
- MLを実際に構築したり、使用したりして理解することが大事

####AI の基本的な作業について

- 主なAIの作業内容
 - データセットのダウンロード
 - データの整理
 - PCA の結果について話し合う
- AI作業は泥臭い内容ばかりで、それは重要なプロジェクトでも変わらない
    - メディアはキラキラしたAIエンジニア像を喧伝するため実作業者は不安になりがち
- 泥臭い作業から素晴らしいものが生まれるので、逃げてはいけない


####生涯勉強である
- 常に技術書や論文を持ち歩き、空いた時間に勉強をして自身をアップデートしていく
- Andrew Ng 氏自身も、今も論文や技術書を持ち運び勉強を続けている
- 重要なのは、少しずづでも学び続けること
- 継続していくことが大事

####ソフトウェア分野以外に目を向ける
- ML を使う機会がソフトウェア業界の外にはたくさんある
- 伝統的なセクターの方がよりGDP成長の機会がある (=ビジネスインパクトを与えられる)
    - 農業や製造業などの領域


##おわりに
前編は以上です。後編では、Andrew Ng 氏への AI に関する質問と回答をまとめたものを紹介します。
timeコマンド

忘れてしまうので、自分用にメモ。timeコマンドには2種類ある。

GNU time

```
/usr/bin/time
```

とLinuxのtimeコマンド

```
time
```

の2種類。macOSにはどちらも標準装備されているが、GNU timeの方では表示されるはずのmemory usageなどの情報が表示されないらしい。

# 参考リンク

http://stupiddog.hatenablog.com/entry/2016/03/19/034935
[弊社weblog](https://staffblog.amelieff.jp/entry/2018/09/25/100000)
応用情報技術者試験対策　4 システムの構成要素 知識確認問題

##本投稿の趣旨
筆者が2019年秋期の応用情報技術者試験に向けての受験勉強の中で、各カテゴライズの知識確認問題を考えた。
筆者はまだ受験勉強中なので、これに応えれば合格率が上がると保証する類のものではないけど、同じく勉強中の同志の助けになればと思って投稿している。
尚、解答解説は他参考書や各種サイトに譲り、ここでは解答なしとして記載する。
また、内容は随時更新中（2019/4/22現在）

##4.1 システムの処理形態
<1> 集中処理システムを説明し、その長所と短所を挙げよ
<2> 分散処理システムを説明し、その長所と短所を挙げよ
<3> 水平機能分散について説明せよ
<4> 垂直機能分散について説明せよ
<5> 水平負荷分散について説明せよ
<6> グリッドコンピューティングについて説明せよ
<7> クラスタリングについて説明せよ。
　　また、代表的なクラスタリング構成を2つ挙げ、それぞれについて説明せよ。
<8> RPCの正式名称を解答し、それについて説明せよ
<9> NFSの正式名称を解答し、それについて説明せよ
Git はじめてみた（ブランチ編）

例として、**test_branch**というブランチを作成して作業するとする。

#ブランチ作成流れ
###1. ブランチ作成
```
$ git branch test_branch
```

###2. ブランチ確認
```
$ git branch
  test_branch
* master
```

`*`が付いてるのが、現在作業中のブランチ。
###3. ブランチの切り替え
```
$ git checkout test_branch
```

###おまけ
```
$ git checkout -b [ブランチ名]
```
で、作成しつつ切り替え出来る。

#ブランチでの作業
`git add` や `git commit` 等、いつも通り作業を行う。

#ブランチのマージ
```
$ git checkout master
$ git merge test_branch
```
まず、取り込み先ブランチ（master）に切り替えて、取り込むブランチを指定してmerge。

#ブランチの削除
```
$ git branch -d test_branch
```
マージが終わったら、ブランチの削除を行っておく。
branchコマンドに -d オプションを指定して実行。

---
#コマンドまとめ
###・ブランチ新規作成
```
$ git branch [ブランチ名]
```
###・ブランチ確認
```
$ git branch
```
###・ブランチの切り替え
```
$ git checkout [ブランチ名]
```
###・ブランチのマージ
```
$ git checkout [マージ先ブランチ名（master）]
$ git merge [マージ元ブランチ名]
```
###・ブランチの削除
```
$ git branch -d [ブランチ名]
```
5Gの概観を探る2　ノンスタンドアローン

　この記事は、第5世代移動通信システム(以下、5G)の概観を把握するために、役にたちそうな情報を取りまとめていく。
　その２。

#ノンスタンドアローンとスタンドアローン
　5Gの基本仕様は、その構成から以下に分類されている。
###ノンスタンドアローン　(NSA)
　「5G Phase1」で策定されたもの。
　LTE(4G技術)とNR(5G技術)を組み合わせて実現する。
　「NSA」と略される。

　基地局やコアネットワーク設備に4Gの設備を利用するため、設備投資の削減や4Gとの並行稼動が容易となり、5G開始当初にはメリットが大きいとされる。

###スタンドアローン　(SA)
　「5G Phase2」で仕様の詳細が策定される予定のもの。(まだ策定されていない)
　NR(5G技術)のみで実現する。
　「SA」と略される。
　
　5G専用設備で構成されるため、5Gの性能を最大まで引き出せることがメリットとされる。
　5G開始当初は「NSA」で構築されたとしても、最終的には「SA」に向かうものとして標準化が行われている。

#ノンスタンドアローンの構造

![Figure5.3.2_1TheNSAArchitecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356166/e90c2f74-f7e6-c373-d37c-2c714e4c19ad.png)
>3GPP「TR 21.915 V1.0.0  　Figure 5.3.2-1: The NSA Architecture」

 - en-gNB : 5Gの無線基地局。「ユーザ・データ(C-plane)」を扱う。
 - eNB : 4Gの無線基地局。制御信号(U-plane)を扱う。
 - EPC : LTEと同時期に策定されたコアネットワーク。4Gおよび5GのNSAで利用される。「Evolved Packet Core」。MMEおよびS-GWは、EPCを構成する設備。
 - コアネットワーク：「基幹通信網」「バックボーン」とも呼ばれる。基地局以降の通信事業者側のネットワーク。

NSAでは、5Gの通信が「制御信号(U-plane)」と「ユーザ・データ(C-plane)」に分割される。
制御信号(U-plane)は、eNBでコントロールされる。
ユーザ・データ(C-plane)は、en-gNBで送受信される。
5Gエリアではない場合、eNBでユーザ・データを送受信することも想定されている。
5Gの通信端末(スマホ等)は、en-gNBとeNBの双方にアクセスすることになる。


>https://www.nttdocomo.co.jp/binary/pdf/corporate/technology/rd/technical_journal/bn/vol25_3/vol25_3_003jp.pdf
>https://k-tai.watch.impress.co.jp/docs/column/keyword/1114990.html
>https://blog.goo.ne.jp/imssr_media_2015/e/911758d75e12f886bef99fd5fc06aab7
Windows10 WSL から Vagrant を起動する

# Windows10 WSL から Vagrant を起動する

### Virtualbox Install

https://www.virtualbox.org/
ここからWindows10上にインストールします。※5.2系で確認

### Ubuntu18.04LTS(WSL)をインストール

Microsoft Store でUbuntu18.04LTS をインストール
初期設定でユーザ名とパスワードが聞かれます。
任意の設定をしてください。
初回にRootになれるかの確認とupdateを行っておきましょう

```
$ sudo su -
[sudo] password for ubuntu:
apt-get update
apt-get upgrade
```

### Vagrant を WSLからインストールします。

https://www.vagrantup.com/downloads.html
上記のURLから Debian 64bit のリンクをCopyしてWSLから wget で
pkgを取得後インストールします。

```
wget https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.deb
dpkg -i vagrant_2.2.4_x86_64.deb
```


https://www.vagrantup.com/docs/other/wsl.html
公式の指示に従って、環境変数を追加します。

```bash
vi ~/.bashrc

...
...末尾に追記
export VAGRANT_WSL_WINDOWS_ACCESS_USER= [ウインドウズのユーザ名]
export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
#/mnt/c/[任意のDir名]でもOK
export VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH="/mnt/c/vagrant"
export PATH="$PATH:/mnt/c/Program Files/Oracle/VirtualBox"
export PATH="$PATH:/mnt/c/Windows/System32/"
export PATH="$PATH:/mnt/c/Windows/System32/WindowsPowerShell/v1.0/"
```

### Vagrant initとVagrantfile 作成

Vagrant用dir 作成後 vagrant init を実行します。

```
mkdir /mnt/c/vagrant
cd /mnt/c/vagrant
vagrant init
```

VagrantFile  を以下のようにする。
IP等は任意です。

vi Vagrantfile

```bash
Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"
  config.vm.network "private_network", ip: "192.168.33.10"
  #config.vm.synced_folder ".", "/vagrant",disabled: true
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.customize [ "modifyvm", :id, "--uartmode1", "disconnected" ]
  end
end
```

vagrant up を実行しマシンが起動することを確認します。

```
vagrant up
```


```
There are errors in the configuration of this machine. Please fix
the following errors and try again:

vm:
* The host path of the shared folder is not supported from WSL. Host
path of the shared folder must be located on a file system with
DrvFs type. Host path: .
```

上記のエラーが出る場合は以下の設定を有効化し再度実行してください。
VagrantFile 

```
config.vm.synced_folder ".", "/vagrant",disabled: true
```

共有フォルダ(/vagrant)は使えませんが、マシンは起動します。

```
The private key to connect to this box via SSH has invalid permissions
set on it. The permissions of the private key should be set to 0600, otherwise SSH will
ignore the key. Vagrant tried to do this automatically for you but failed. 
```

ssh key権限エラーメッセージが発生する場合
keyの置き場所がWindows上で600にできないっぽい。
VagrantFileがあるDirに以下のshellを置いて
new_key_set.sh

```bash
#!/bin/bash
SCRIPT_DIR=$(cd $(dirname $0);pwd)
prefix=$(echo ${SCRIPT_DIR}|grep -o -E "[^\/]*$")
mv ${SCRIPT_DIR}/.vagrant/machines/default/virtualbox/private_key /mnt/private_key_${prefix}
cd ${SCRIPT_DIR}/.vagrant/machines/default/virtualbox/
ln -s /mnt/private_key_${prefix} private_key
chmod 600 private_key
```

```bash
bash new_key_set.sh
vagarnt reload 
```

で問題なくなるはず。
対応としては/mnt/下にprivate_keyを置いて600にしシンボリックリンクで見るようにしただけです。
##### 参考
* [Vagrant up (2.2.2) not working in WSL] (https://github.com/hashicorp/vagrant/issues/10576)

* ['Windows Subsystem for Linux' でVagrantを操作する方法](http://blog.ishimotty.com/entry/2017/12/03/032232)
iOSネイティブでHLS or mp4などの配信される360度動画をサクッと再生する件

### まずはじめに
今回の記事では、配信HLSやローカルmp4の360度動画をiOSネイティブでお手軽に再生してしまおうという解説記事を提供します。

### 使うライブラリについて
今回の実装では、iOS SDK標準以外のSDKについてはつかっていません、使うのは、AVFoundation、SceneKitおよびSpriteKitを使用しています。他のSDKなどの使用および、解説などもしません。

### 動画読み込みおよび再生
動画の読み込みおよび再生は、AVFoundtionとSpriteKitの２つを使って実装します。動画を読み込みには、まず、AVFoundtionのAVPlayerメソッドを使います。
urlは、動画のアドレスまたは、ローカルのビデオパスを指定します。

```swift
let player = AVPlayer(url: url as URL)
```

そして全天球用のテクスチャとして貼るためにSpriteKitをつかって、スプライト化します。SKVideoNodeは、SceneKitでも使えるNodeとして動作します。ビデオの再生をするために、playメソッドを呼びます。SKSceneとして、sceneを作り、videoNodeを追加しておきます。

```swift
videoNode = SKVideoNode(avPlayer: player)
if let videoNode = videoNode {
            let size = CGSize(width: 1280,height: 720)
            videoNode.size = size
            videoNode.position = CGPoint(x: size.width/2.0,y: size.height/2.0)
            let spriteScene = SKScene(size: size)
}
spriteScene.addChild(videoNode)
videoNode?.play()

```
### 全天球モデルの生成

次に全天球用の球を作るメソッドを作成しました。

```swift
func createSphereNode(material: AnyObject?) -> SCNNode {
        let sphere = SCNSphere(radius: 20.0)
        sphere.firstMaterial!.isDoubleSided = true
        sphere.firstMaterial!.diffuse.contents = material
        let sphereNode = SCNNode(geometry: sphere)
        sphereNode.position = SCNVector3Make(0,0,0)
        return sphereNode
    }
```

`sphere.firstMaterial!.diffuse.contents`にはさまざまな、オブジェクトを設定でき、このあたりは,contentsの定義をみてみると、ドキュメントにはありませんが、その説明がコメントしてソースに書いてありました。SKSceneも設定でき、先程のSKVideoから作成したsceneをmaterialに設定します。

###その他:端末のモーションセンサーを使った画面の回転
Facebookの360度動画などでもある、端末を回転すると360度動画のほうも回転する機能を次のように定義してみました。

```swift
func startCameraTracking() {
        motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
        motionManager.startDeviceMotionUpdates(to: OperationQueue.main) { [weak self] (data: CMDeviceMotion?,error: Error?) in
            guard let data = data else { return }
            let attitude: CMAttitude = data.attitude
            self?.cameraNode.eulerAngles = SCNVector3Make(Float(attitude.roll + Double.pi/2.0), -Float(attitude.yaw), -Float(attitude.pitch))
        };
    }
```

###まとめ
HLSの再生mp4動画の再生および360度に展開する部分のコードを提示した、また再生された動画を全天球のモデルを生成した上で、そのモデルに展開する方法をしめした。

###ソースコード
2019/4/22の最新環境でビルド可能なソースコード
https://github.com/tarotaro/360Video
Dropboxからファイルを直接Googleドライブにダウンロードする (Colaboratory使用)

#Dropboxからファイルを直接Googleドライブにダウンロードする

##はじめに
####クラウド間でデータをやり取りするときローカル経由だと少々面倒です。
  *(例) Dropbox → ローカル → Google Drive*
####今回は、Colaboratory を用いてDropbox から Google Drive に直接ファイルをダウンロードする方法を紹介します。    

##処理のフロー
今回は、圧縮ファイル(.tar.gz) を例にダウンロードの方法を紹介します。

処理の流れは

1. ColabでGoogle driveをマウントし、作業フォルダにする
2. urllib を使ってURLからファイルをダウンロードする準備
3. Drive上のファイルに書き込み

となります。
では、実際のコードを見てみます。

##コード
###1. ColabでGoogle driveをマウントし、作業フォルダにする
```python
from google.colab import drive
drive.mount('/content/drive')
%cd "drive/My Drive"
```
ColabでDriveを使う時におなじみのやり方です。

###2. urllib を使ってURLからファイルをダウンロードする準備
```python
import urllib.request
import os

# 対象のURL (末尾を "?dl=1" にする必要があります)
DROPBOX_URL = "https://www.dropbox.com/s/2qasmb81c1y3lud/ruby-2.6.3.tar.gz?dl=1"

# 保存ファイルの名前 (ここではダウンロード元と同じにしている)
filename=DROPBOX_URL[:-5].split('/')[5]

# 保存場所 = ドライブのtmpフォルダ以下
directory="tmp/"
```
URLの末尾がポイントです。普通は ?dl=0 になっていますので ?dl=1 に変えましょう。
また、今回は共有リンクで作成したURLのみが対象です。非公開のフォルダからダウンロードするためには別途Dropbox APIを使います。  
関連リンク : [Downloading a file using the Dropbox Python library](https://riptutorial.com/dropbox-api/example/1350/downloading-a-file-using-the-dropbox-python-library)

###3. Drive上のファイルに書き込み
```python
# 大きなデータは256kb毎に細切りにして読み込む
chunk_size = 1024 * 256

with urllib.request.urlopen(DROPBOX_URL) as resp:
  if not os.path.exists(directory):
    os.makedirs(directory)
  with open(os.path.join(directory, filename), 'wb') as f:
     while 1:
        chunk = resp.read(chunk_size)
        if not chunk:
            break
        else : 
          f.write(chunk)
          f.flush()
          os.fsync(f.fileno())  
```
データを区切って読み込むことで、大きなデータにも対応できます。
###結果

```python

ls tmp/  # --> ruby-2.6.3.tar.gz
```
ちゃんと保存できました。
##終わりに
今回はDropboxのファイルをローカルを経由せずにGoogle Drive に落とす工程を紹介しました。
容量に余裕があるならばローカル経由でやる方が素直で分かりやすいですが、こんな方法もあるということで。

*追記*
dropboxはwgetでダウンロードできるので、urllibではなく、

```python
！wget -O tmp/FILENAME "対象URL(末尾？dl=1)"
```
とした方が簡単です。
データの可視化シリーズ 第4弾 - 「表計算の割合」を使って可視化する

# データの可視化シリーズ 第4弾 - 「表計算の割合」を使って可視化する


こんにちは

Exploratoryの[白戸](https://exploratory.io/author/GMq1Qom5tS/notes)です。

[前回](https://qiita.com/takatoshiroto/items/f3ef6d2c18ebeb11cf67)は、色(グループ化)と繰り返しを使用して国ごとのOSのユーザー数を見ていきましたが、今回は**表計算**を使用して各国のOSの割合を見ていきたいと思います。

# データの可視化の目的

**目的**

各国のOSの割合を知りたい

**使用機能**

* バーチャート
* 色(グループ化)
* 表計算(割合)
* 値の表示

それでは、実際にデータの可視化をしてみましょう！

# 可視化

前回と同様に、チャートはバーチャートを選択して、X軸にCountry、Y軸にuseridを選び、集計関数は「一位の数(UNQ)」を選びます。

さらに、「OS」列を「色」に割り当て、それぞれのバーをOSごとに分割していきます。

※Otherはフィルタ機能を使用して非表示にします。

“国の数がたくさんあるので前回最も多い方から10個だけ残してそれ以外はOtherというグループにまとめました。（詳しくはこちらを見てください。）今回はOther以外に注目したいので、チャートのフィルター機能でOtherというグループを除外します。”


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/4ad786e5-cbfc-86d5-ee2f-75ea2fc16ed8.png)


割合をみていきたいので、Y軸の横にあるメニューボタンをクリックし、**表計算**を選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/8c34b1e4-ffba-1a06-b65e-3e7ca64ee3ea.png)


表計算の中にはいくつもの項目がありますが、今回は **割合 (% of)** を選択します。

もしご興味があれば、他の項目も試してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/996efd07-9c8f-053c-e336-13935b10f4ba.png)


それぞれの国ごとに使用OSの割合が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/bb5c9706-349c-e6dc-b9ff-e6463ae951a5.png)


Y軸のスケールは割合なので、100%が上限となっていて、そのなかでOSごとに割合が算出されています。
このチャートをみると、やはり各国の使用OSには差がありますね。

もう少し詳しく見ていきたいので、チャート上に％を表示させてみましょう。


左上にある、プロパティをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/11d2a72e-9ffb-0d11-b145-7472fe9b3904.png)


次に、値をプロット上に表示という項目をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/624e7f47-5a51-8f7c-f60a-efef1c56c6d9.png)


値の表示場所は下を選択しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/8a98cdbb-7d48-c668-329a-4ef9e42e322b.png)


下記のチャートのように、値が表示されているかとおもいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/5550f4b6-4398-96b9-eb89-ff4ba09746de.png)


ブラジルではMacが少なくWindowsとLinuxが多いことがわかりました。UKではLinuxが少ないが、MacもWindowsの割合に大きな差はなさそうです。


# まとめ

今回は表計算の割合という機能を使用して、バーチャート上にOSごとの割合を国ごとにみていきました。

これまで３回ともバーチャートを使用してきました。このようなシンプルなバーチャートでも、比べたり、分割したり、スケールを変えたり(割合のパーセント)することで、様々な角度からデータを簡単に理解していくことができます。


次回は**ラインチャートを使用して、時系列のトレンド**をみていきたいと思います。

* [データの可視化シリーズ 第5弾 - ラインチャートを使って「時系列のトレンド」を可視化する](https://qiita.com/takatoshiroto/items/9e76ca4527509852fd06)

-----

# Exploratoryデータ・アカデミー

データの可視化、またはデータ分析に関してもっと知りたい、学びたいという方は、私達が提供しているトレーニングやセミナーに参加してみてください。

[こちら](https://ja.exploratory.io/data-academy-jp?utm_campaign=chart_intro_4&utm_medium=blog&utm_source=qiita)のExploratoryデータ・アカデミーのページに詳細情報があります。

データを使ってより良い意思決定を行っていきたいと言う方は、ぜひこの機会に参加をご検討ください！
[Rust][未解決] Selfに対するトレイト境界に関する疑問

以下は[Actix](https://github.com/actix/actix)のコードを切り貼りして作ったもの

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ce2e866fdbd1a94464cd1993daad3e92

最後の行がどうしてもコンパイル通すことができない。

そもそも`Actor::start()`での`Self`に対するトレイト境界は`myactor2.start()`のようなものををコンパイルエラーにするのが役割なのだろうか？

以下こちらにもコードを貼っておく。

```rust
use std::marker::PhantomData;

struct Context<A>
where
    A: Actor<Context = Context<A>>,
{
    _phantom_data: PhantomData<A>,
}

trait ActorContext: Sized {}

impl<A> ActorContext for Context<A>
where
    A: Actor<Context = Self>,
{
}

impl<A> Context<A>
where
    A: Actor<Context = Self>,
{
    fn new() -> Self {
        Context { _phantom_data: PhantomData }
    }
}

trait Actor: Sized {
    type Context: ActorContext;

    fn start(&self)
    where
        Self: Actor<Context = Context<Self>>,
    {
        Context::<Self>::new();
    }
}

struct MyActor;
struct MyActor2;

impl Actor for MyActor {
    type Context = Context<Self>;
}

impl Actor for MyActor2 {
    type Context = SyncContext;
}

struct SyncContext;

impl ActorContext for SyncContext {}

fn main() {
    let myactor = MyActor {};
    myactor.start();

    let myactor2 = MyActor2 {};
    // myactor2.start(); // コンパイルエラー
}
```
データの可視化シリーズ 第3弾 - 「色」と「繰り返し」を使ってバーチャートを「分割」する

# データの可視化シリーズ 第3弾 - 「色」と「繰り返し」を使ってバーチャートを「分割」する

こんにちは

Exploratoryの[白戸](https://exploratory.io/author/GMq1Qom5tS/notes)です。

[前回](https://qiita.com/takatoshiroto/items/a9db605ff3ce18982a55)は、バーチャートを使って国ごとのアクセス数を比べてみましたが、今回は色(グループ化)と繰り返しを使用して国ごとのOSのユーザー数を見ていきたいと思います。

# データの可視化の目的

**目的**

各国のOS別の使用者数を知りたい

**使用機能**

* バーチャート
* 色(グループ化)
* 繰り返し

それでは、実際にデータの可視化をしてみましょう！

# 可視化

前回と同様に、チャートはバーチャートを選択して、X軸にCountry、Y軸にuseridを選び、集計関数は「一位の数(UNQ)」を選びます。

※Otherはフィルタ機能を使用して非表示にします。

“国の数がたくさんあるので前回最も多い方から10個だけ残してそれ以外はOtherというグループにまとめました。（詳しくは[こちら](https://ja.exploratory.io/note/GMq1Qom5tS/Data-Viz-duD3HnH9pE)を見てください。）今回はOther以外に注目したいので、チャートのフィルター機能でOtherというグループを除外します。”


ちなみに、チャート横のマークをクリックして、複製を押すことで同様のチャートを作ることができます。
フィルタ機能なども引き継いているので便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/347e9b63-6bc9-190f-bc7a-49fac603284b.png)


ここから、各国のユーザーのOS使用数を見ていきたいので、色(グループ化)を使用していきます。
色(グループ化)をクリックして、OSを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/0b91fcac-428e-e136-8965-4d62402d4f49.png)


すると、各国の値にOS別の色がつきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/ed5b3f39-5f6e-f265-add7-3619225681de.png)


MacとWindows比率がどの国でも高いことがわかります。しかし、USの値が大きいせいで他の国の値が見辛くなっています。

前回はフィルタ機能を使用しましたが、今回はズーム機能を使用してみましょう。

Japanの上からクリックしてAustraliaの下までドラッグします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/820eab70-065b-e238-56b0-4cdab33ef3c0.png)


選択した範囲のみを拡大して表示してくれました。
もとに戻したいときは、チャート内をダブルクリックでもとに戻せます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/01bf4e61-1689-b49c-76b8-7324407c71e9.png)


それぞれの国ごとに比率の差はありそうですが、MacとWindowsが多く、Linuxが少ないことはどの国にも当てはまりそうです。

次は、繰り返しで見ていきます。
色(グループ化)をクリックし、Noneを選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/900cc9e3-1c78-da6d-7242-7458e2b171da.png)



これで、色分けを解除しました。

次に、繰り返しをクリックし、OSを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/fb2ff87d-b972-3a32-2cdc-fc31f7861e59.png)


そうすることで、OS別にチャートがそれぞれ作られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/c84ef863-30e7-f6f2-46b5-ed1d922c92c3.png)


OSごとにソートしてくれているので、OS内での国の順序を知ることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192148/7a56c687-fe89-eefb-03b4-df6ca54f6d60.png)


LinuxではBrazilが多く、MacではCanadaが中間層にいますね。FranceはどのOSでも中間層にいるようです。
繰り返しにすることで、それぞれの国ごとのOS別の使用者数が違うことがわかりました。


# まとめ

今回はバーチャートと色(グループ化)、繰り返しを使って、ユーザーの使用しているOSを国別にみていきました。

観察できたこととして、当たり前かもしれませんがそれぞれの国ごとに使用されるOSの数に違いがあることがわかりました。


分割してみて、各国のOS別ユーザー数はわかりましたが、割合はどうなのか気になりました。
そのため、次回は色と表計算を使用して、OS別の割合を可視化していきたいと思います。

最後まで読んでいただきありがとうございました。

* [データの可視化シリーズ 第4弾 - 「表計算の割合」を使って可視化する](https://qiita.com/takatoshiroto/items/9c9a3ed3de673ed0a6d4)


ぜひ次も読んでください！

-----

# Exploratoryデータ・アカデミー

データの可視化、またはデータ分析に関してもっと知りたい、学びたいという方は、私達が提供しているトレーニングやセミナーに参加してみてください。

[こちら](https://ja.exploratory.io/data-academy-jp?utm_campaign=chart_intro_3&utm_medium=blog&utm_source=qiita)のExploratoryデータ・アカデミーのページに詳細情報があります。

データを使ってより良い意思決定を行っていきたいと言う方は、ぜひこの機会に参加をご検討ください！
jacoco導入

jacocoを導入して、TestNG実行時のカバレッジを取得します。

# カバレッジ取得の仕組み

jacocoとCoberturaしか触ったことがありませんが、どちらも以下のような流れとなります。詳しくは知りません。

* instrumentというプログラムでクラスファイルを書き換え、実行時に通った行番号がファイル出力されるようにする
* ファイル出力された行番号をもとにカバレッジを計算

なので、instrumentで書き換えたクラスファイルをもとにアーカイブを作ってしまったりすると非常に残念なことになります。ご注意ください。

# 準備

Mavenがラクです。
実行時に計測（on-the-fly instrumentation）することもできますが、PowerMock使用時にカバレッジが0%になってしまうものがいくつかありました。なので、事前にクラスファイルに手を入れておく方法（offline instrumentation）を採用しています。

今回はNetBeans IDE 8.2を使用していますが、IDE側の不具合で結果レポートが正しく表示されなかったため、あえて旧バージョンの0.8.1を導入しています。

```xml:pom.xml(dependencies)
<dependency>
    <!-- これがないとOffline Instrumentが動かない -->
    <groupId>org.jacoco</groupId>
    <artifactId>org.jacoco.agent</artifactId>
    <version>0.8.1</version>
    <scope>test</scope>
    <classifier>runtime</classifier>
</dependency>
```

```xml:pom.xml(build/plugins)
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M3</version>
    <configuration>
        <systemPropertyVariables>
            <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile>
        </systemPropertyVariables>
        <!-- ↓これがないとスタックトレースが出ない -->
        <trimStackTrace>false</trimStackTrace>
    </configuration>
</plugin>
<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <!-- 0.8.2 @NetBeans IDE 8.2だと「コード・カバレージ」が記録されない -->
    <version>0.8.1</version>
    <executions>
        <execution>
            <id>default-instrument</id>
            <goals>
                <goal>instrument</goal>
            </goals>
        </execution>
        <execution>
            <id>default-restore-instrumented-classes</id>
            <goals>
                <goal>restore-instrumented-classes</goal>
            </goals>
        </execution>
        <execution>
            <id>default-report</id>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>
```

# テスト実行

Mavenでテスト実行し、終わったらコード・カバレージの「レポートを表示」してください。
自分の記事の中でも古い情報になったもの

[Node.jsでwkhtmltoimageを使ってWebサイトのキャプチャ画像を取得](https://qiita.com/_takwat/items/3a07b9cf11ba95bcbd2a)
[Node.jsでWebサイトのスクリーンショットを保存 その2](https://qiita.com/_takwat/items/c6a017fd5bc9b50fba5b)

今どきはHeadless Chromeと[Puppeteer](https://github.com/GoogleChrome/puppeteer)でいけますね

```js:puppeteer.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();
```

async/awaitも使えばこんなに簡単
というわけでPromise関連のインターフェースが用意されてないモジュールを使わない限りはこれもObsoleteでしょう

[コールバック地獄とasync.js](https://qiita.com/_takwat/items/ce6a566ddfc546828acf)