OmniAICreator/Qiita-1.07M huggingface dataset:
常時実行プロセスを実行しているときのメモリ状況を監視する

# はじめに
freeコマンドを毎度叩くのだるいので、watchコマンドと組み合わせて、何秒おきかに実行させてみたメモ。

割と簡単で何をいまさらという感じだと思いますが、常時実行しているプロセスを感じするときに、そういえば毎度freeコマンド叩いていたな・・・と思い、watchコマンドと組み合わせました。

# 内容
まあ、watchの復習みたいな感じになってしまうのですが、watchに以下のように組み合わせれば、定期実行してくれるよねっということで

```
watch -n 秒間隔 繰り返したいコマンド
```

以下のように監視しました。

```
watch -n 60 -d free -m
```


ちなみに・・・

「-d」は変更された箇所だけを表示してくれるやつです。

# 参考
https://joppot.info/2017/03/13/3508
そういえばvagrantのsshってなんだろう

#SSHとは

> SSHとは、SSHとは、Secure Shell（セキュアシェル）の略称で、リモートコンピュータと通信するためのプロトコルです。
認証部分を含めネットワーク上の通信がすべて暗号化されるため、安全に通信することができます。

って書いてあったけど正直何言ってるかわからない。
リモートコンピュータもプロトコルもわからない


######リモートコンピュータとは
インターネットで繋がっている自分以外のコンピュータ

######プロトコルとは
https://wa3.i-3-i.info/word11.html
これ見たらわかった

#つまり

vagrantで仮想環境が作られたので、それに安全に接続する方法(プロトコル？)がいつもやってるvagrant sshなのかな〜ふーん
Nuxt.jsでFontAwesomeを使う方法。必要なアイコンだけインポートする！

# font awesome は非常に重たい！使うアイコンだけインポートする！

Font Awesomeは便利なのでよく使うのですが、そのまま読み込むと非常に重たくなってしまいます。
![fa.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173978/7fd63527-5bb5-d1f4-ef1f-e7151c9941f7.jpeg)


パッケージは
`nuxt-fontawesome` というモジュールを使用

Nuxt FontAwesome5
https://www.npmjs.com/package/nuxt-fontawesome

```
yarn add nuxt-fontawesome @fortawesome/free-solid-svg-icons @fortawesome/fontawesome-svg-core @fortawesome/vue-fontawesome
```

`nuxt.config.js` で `modules` に読み込み

```nuxt.config.js
modules: [
  'nuxt-fontawesome',
],

/*
 ** FontAwesome
 */
 fontawesome: {
  component: 'fa'
},
```

そこで、軽くするため、必要なアイコンのみ読み込むようにします。

コンポーネントで読み込み

```
import { faMapMarkerAlt } from ‘@fortawesome/free-solid-svg-icons’
```

ちなみにこれは `fontawesome` ではなく、なぜか「 `fortawesome` 」なのでスペル注意！！

```*.vue
<script>
 export default {
  computed: {
    faMapMarkerAlt() {
      return faMapMarkerAlt
    }
  }
</script>
```

テンプレートで使用するときのタグ

```
<fa :icon=“faMapMarkerAlt” />
```

以上です。

![fa-after.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173978/14a61499-0ec2-5416-d671-a3f1a70a71c4.jpeg)


同じプロジェクトでもFontAwesomeを最適化することで、かなり圧縮できました。
jest-circus と jest.retryTimes(n) で成功するまでリトライする

jest のオプション見てたら retryTimes というのがあった。
https://jestjs.io/docs/ja/jest-object#jestretrytimes

しかし普通に書いただけだと動かない。https://github.com/facebook/jest/tree/master/packages/jest-circus と一緒に使えとのこと。 The next-gen test runner for Jest


※ jest のセットアップは省略

```
yarn add jest-circus -D
```

30% で成功するテストを 3回繰り返す。

```js
import assert from "assert";

jest.retryTimes(3);
it("retry", () => {
  console.log("xxx", Date.now());
  assert.ok(Math.random() > 0.3);
});
```

```
❯ yarn jest --testRunner='jest-circus/runner' src
yarn run v1.17.3
 PASS  src/__tests__/retrySpecCheck.test.ts
  ● Console

    console.log src/__tests__/retrySpecCheck.test.ts:5
      xxx 1568271139936
    console.log src/__tests__/retrySpecCheck.test.ts:5
      xxx 1568271139949
    console.log src/__tests__/retrySpecCheck.test.ts:5
      xxx 1568271139951
```

flaky test 周りで便利
input type="email" の値の書式

フォームの入力欄で `type="email"` を使うと、入力値がメールアドレスとして正しいかどうかをブラウザーに判別してもらうことができます。

```html
<input type="email" name="email">
```

そのメールアドレスの書式は具体的にどんなものかというと、HTML5の仕様書に正規表現で提示されています。

https://html.spec.whatwg.org/#e-mail-state-(type=email)

> The following JavaScript- and Perl-compatible regular expression is an implementation of the above definition.

```
/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
```

この正規表現には1つ問題がありまして、それは `taro@hogehoge` のように `.` を含まないドメイン名のアドレスはアリであることです。`hogehoge` はドメイン名の書式としてアリなので、そりゃそうです。

といっても、普通は `taro@hogehoge` は禁止したいですよね。それには、次の正規表現を使います。最後の `*` を`+` に変えるだけ。

```
/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/
```

これを `input` の `pattern`属性に指定すると、`taro@hogehoge` が送信できないようにできます。

```html
<input type="email" name="email"
  pattern="^[a-zA-Z0-9.!#$&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$" >
```
VirtualBoxでUbunts上のnginxでリバースプロキシしてHTMLを書き換えてHello WorldをCrazy Worldにする

# はじめに
[VirtualBoxでCentOS上のApacheでリバースプロキシしてHTMLを書き換えてHello WorldをCrazy Worldにする](https://qiita.com/the1031hiroto/items/5b0b69801c30a17c9800)のNginxバージョンです。
# やったこと
nginxで立ち上げた[http://localhost](http://localhost)にnodeで立ち上げた[http://localhost:3000/](http://localhost:3000/)のHTMLを書き換えて表示させる
![Screenshot from 2019-08-23 11-30-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/101625c0-8e71-b755-853e-1aad3bc688ad.png)
# nginxの設定
sub_filter '置き換え元文字' "置き換え後文字" ;

```nginx:nginx.conf
location / {
            # root   html;
            # index  index.html index.htm;
            sub_filter_once off;
            sub_filter 'Hello' 'Crazy' ;
            sub_filter '</head>' "<script>alert('Crazy World')</script></head>" ;
            sub_filter 'nginx' 'Crazy' ;
            proxy_pass   http://127.0.0.1:3000;
        }
```

```nginx:/etc/nginx/sites-available/default
location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            # try_files $uri $uri/ =404;
            sub_filter_once off;
            sub_filter 'Hello' 'Crazy' ;
            sub_filter '</head>' "<script>alert('Crazy World')</script></head>" ;
            sub_filter 'nginx' 'Crazy' ;
            proxy_pass   http://127.0.0.1:3000;
        }
```
# nodeで立ち上げるHTMLを準備

```html:hello.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World</title>
    </head>
    <body>
        <h1>Hello World</h1>
    </body>
</html>
```


```javascript:hello.js
const http = require('http');
const fs = require('fs');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  // res.setHeader('Content-Type', 'text/plain');
  // res.end('Hello World!\n');
  fs.readFile('hello.html','UTF-8',
  (error, data)=>{
    res.writeHead(200,{'Content-Type':'text/html'});
    res.write(data);
    res.end();
  });
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});
```
# nodeで立ち上げてアクセス[http://localhost:3000/](http://localhost:3000/)
```
aoui@aoui-VirtualBox:/media/sf_reverse_proxy_nginx/nginx/public$ node hello.js
Server running at http://127.0.0.1:3000/
```
![Screenshot from 2019-08-23 11-13-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/e82dd9b0-396b-35e4-8890-3e4112fd77d6.png)
# [http://localhost](http://localhost)にアクセスしたらHello WorldがCrazy Worldになって表示できた
![Screenshot from 2019-08-23 11-14-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268079/56a4cfdb-2445-78cd-9e10-0ceab0aa81cf.png)

# ポートが使えない時
[他のプロセスがポートを占有してnginxを再起動できない](https://qiita.com/Yu-s/items/64c54def20e5fa64edd1)

# Dockerでやりたい
[docker-composeで立ち上げて、nginxでリバースプロキシしてHTMLを書き換えてHello WorldをCrazy Worldにする](https://qiita.com/the1031hiroto/items/4cb014a605ed0a4f62ad)
PHP入門　クラスの継承をまとめてみた

①クラスの継承とは..あるクラスを基に新しいクラスを作成する。具体的にはクラスの共通部分を別クラスにしてまとめる仕組みを指す。
既存のクラス(スーパークラス)から新しく作ったクラスにメソッドや変数を引き継ぐ。この際新しいクラスをサブクラスと呼ぶ。引き継ぐキーワードは"extends"。



例

```

<?php

class Human {
  public $name;
  public function __construct($name){
    $this->name =$name;
  }
  public function sayHi(){
    echo "hi, i am $this->name!";
  }
}
//ここまでがスーパークラス

//下記がサブクラス
class subHuman extends Human {
  //subHumanクラスが上の$nameプロパディとsayHiメソッドを使える様になる。
  
public function sayHello() {
  //追加でメソッドを記述することができる
  }
}
  $Hahakigi = new Human("hahakigi");
  $Ai = new subHuman("ai");

  echo  $Ai ->name;
  $Ai->sayHi();
  $Ai->sayHello();
 ?>
```

②オーバーライト..スーパークラスで定義したメソッドをサブクラスで再定義し、処理の上書きをすること。



③継承クラスを使う理由...プログラムが大規模になった際に、コードの見づらさを解消したりや重複したコードを書かない様にする為に使う。重複したコードを書くことによってエラーやトラブルを招いてしまう.



ここに関しては実際に複数人で行う開発プロジェクトに携わっていないと実感できなさそう。
データマイニングとは？その５つの特徴を知りましょう！

![01-データマイニングとその特徴とは.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/8a47da7b-260f-e973-ec76-b570582447cb.png)


 

データマイニングとは、DM(Data mining)の省略で、統計学、パターン認識、人工知能などのデータを解析する技法を使って、情報管理システムなどに蓄積された膨大なデータの中から、パターンや相関関係などを見出し、マーケティングや営業などに活用するテクノロジーです。

データマイニングにとってデータを分析した結果では「おむつとビール」がその中の逸話として、よく知られていると思うが、興味のある方は[データマイニングに関する面白い記事10選](https://www.octoparse.jp/blog/data-mining-explained-with-10-interesting-stories/)を読んでもらいます。

そして、今回では我々がよく言っているそのデータマニングに関する５つの特徴を解説してみます。


#**1、膨大なデータに基づく**

 実際、ほとんどのデータマイニングアルゴリズムは小さなデータボリュームで実行でき、結果を取得できます。ただし、量がすくないデータの場合は、完全に手動分析で要約できる一方で、少量のデータは実際の世界の普遍的な特性を反映できないことがよくあります。ですので、データマイニングで正確的な結果を出すにはまず、膨大なデータを取得しかできます。[Ocotparse](https://www.octoparse.jp/)という[無料スクレイピングツール](https://www.octoparse.jp/)を利用すれば、何百万件のデータを正確的に収集してくれます。

 

#**2、高い信憑性を持つ**


いわゆる信憑性とは「信用できる、または信頼できる度合い」を意味します。マイニングされたデータは事実に基づいて高い信憑性を持たなければならないです。単にその分野において地位や権力が高いオーラに左右されて、その人が言っていることが本当なのかを判断できず、真実から離れて行くことになるかもしれません。ですので、確実なデータに基づいて出た結論の方が信憑性があります。

 

#**3、データの裏側を見抜く**

データマイニングとは、データから直接に伝われてくる知識ではなく、人が工夫してその中に隠されているものを発見することです。例えば、TableauやRAWGraphsなどの一般的なBIツールを使用するしか発見できない情報がたくさんあります。

 

#**4、未知性に富む**

マイニングされた知識は、今まで誰も発見できない未知なものであるべきです。そうでなければ、単に専門家の言っていることを検証しただけです。新しい知識がどんどん発見されて、それを新しい技術に変えれば、世界を変えることになるかもしれません。

 

#**5、価値を持つ**

マイニングの結果は、企業に直接的または間接的な利益をもたらさなければなりません。データマイニングはとても高級的に見えますが、実は役に立っていないという人もいます。これは単なる誤解です。一部のデータマイニングプロジェクトでは、明確なビジネス目標の欠如、データ品質の不十分、またはデータマイニング職員の経験不足などの原因で、データの最大価値を活かすことができません。しかし、データマイニングそのものの価値を最大限にすれば、成功したケースの多くは、データマイニングが実際に効率を改善するツールになり得ることも証明しています。

 

以上はデータマニングに関する５つの特徴でした。いかがでしょう。

今後のマーケティング活動において、大きなサポートになれるようなデータマイニングを導入する際には以上の５つの特徴をチェックしてから判断しましょう。きっとお役に立てると思います！
cakephp配列操作

配列操作

Cake\Utility\Hashを使うと配列の中から特定の値を抽出や挿入・削除
差分取得など色々便利です。

```php
// Hash::extractを使い配列から特定のデータを取得する
$users = [
    ['id' => 1, 'name' => 'mark'],
    ['id' => 2, 'name' => 'jane'],
    ['id' => 3, 'name' => 'sally'],
    ['id' => 4, 'name' => 'jose'],
];
$results = Hash::extract($users, '{n}.id');
// $results は以下のとおり:
// [1,2,3,4];
```

```php

// 配列に配列を挿入する
$a = [
    'pages' => ['name' => 'page']
];
$result = Hash::insert($a, 'files', ['name' => 'files']);
// $result は以下のようになります:
[
    [pages] => [
        [name] => page
    ]
    [files] => [
        [name] => files
    ]
]
```

[cakephp ドキュメント](https://book.cakephp.org/3.0/ja/core-libraries/hash.html)
作成したLightning ComponentがLightning Application Builderが表示されない

作成したlightning componentがlightning applicationが表示されない
![qitta.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/490d165e-566b-d09a-3f8a-e9fce397b723.png)
カスタムコンポーネントの中に新規作成のコンポーネントが表示されなかった。
![qitta2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/3a7263e6-8449-875c-917e-8cb3089ea0ea.png)


☆原因はソースの中に公開してない
![qitta3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/28bcb4c1-2b58-a8e2-2af1-8c81887c293e.png)

正常に表示されました。
![qitta4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442974/9944ef2a-bc74-8d93-3cb3-9678d2b2ef0d.png)
Swift　if文の中にアラートを入れる方法

自分用のメモです。

ネットで多く用いられている方法を使うとif文の中にアラートを入れられないのですが、以下のコードで試したところうまく行きました。



```ViewVontroller.swift
//if分の中に挿入しても問題なく出せる。
let alert = UIAlertView()
alert.title = "Title"
alert.message = "My message"
alert.addButton(withTitle: "Ok")
alert.show()
```
docker-composeを用いた複数コンテナのapi(Golang)にgo modulesを導入する

# 概要
`docker-compose`を用いた複数コンテナを利用していました。
このうちの１つがgolangで作成したapiだったのですが、このapiに`go modules`を導入しようとして少しハマったので解決策を共有します。

# そもそもgo moduleとは
一応前提の話をしますと、`go modules`を使うことによって`$GOPATH`を気にすることなくpackageをimportすることができるようになります。
`package main`だけで完結している軽いアプリケーションなら不要ですが、packageを分割したい際には`go module`を導入するといいかもしれません。

# スタック
##フォルダ構成
```
article
  ├ client
  ├ api
  │  ├ main.go
  │  ├ // 省略
  │  ├ go.mod 
  │  ├ go.sum
  │  └ Dockerfile
  ├ nginx
  └ docker-compose.yml
```
```go.mod
module article/api
```
 - apiディレクトリ上で`go mod init article/api`を叩いて`go.mod`を作成しています。

## Dockerfile
apiディレクトリ以下のDocekrfileは以下のようになります

```dockerfile:Dockerfile
FROM golang:latest
ENV GO111MODULE=on
WORKDIR /app
COPY go.mod .
COPY go.sum .
RUN go mod download
COPY . .
RUN go build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
ENTRYPOINT ["/app/api"]
```

## docker-compose.yml
最後にdocker-compose.ymlは以下のようになります

```yml:docker-compose.yml
version: '3'
services:
  api:
    build:
      dockerfile: Dockerfile
      context: ./api
    volumes:
      - ./api:/go/src/github.com/jpskgc/article/app
    depends_on:
      - db
    tty: true
    environment:
      - AWS_ACCESS_KEY_ID
      - AWS_SECRET_ACCESS_KEY
      - MYSQL_USER
      - MYSQL_PASSWORD
      - MYSQL_HOST
      - GO111MODULE

  //他コンテナの記述は省略
```

---
`Docekrfile`と`docker-compose.yml`の設定がうまくいかなくて悪戦苦闘していた記憶があります。
一応このサンプルの全ソースコードは以下にあります
https://github.com/jpskgc/article

何か参考になりましたら幸いです。
VirtualBox VM　デフォルトの起動モード（ヘッドレス/デタッチ/通常起動）を設定する

# VirtualBox デフォルトの起動モード（通常起動）について
VirtualBox ではデフォルトでの起動モードは画面（X Window)とシステムが一体になった状態でVMがスタートするが、
このモードだと画面を閉じるとVM本体も停止しなくてはならない。

通常使用なら問題ないが、サーバー的な用途で画面を閉じてもVMは起動したままで保持したい場合にはヘッドレスかデタッチモードで起動する必要があるが、起動モードの切り替えには一度VMのシャットダウンが必要。

VM起動時に他のモードも選択することはできるが、UIの選択ボタンが小さいので押し間違えやすい:cold_sweat:

ということで、デフォルトの起動モードを変更することにする。
この変更は **UIからは不可** で、代わりにCUIのVBoxManage コマンドで設定できる。

# コマンド
```sh
$ VBoxManage modifyvm <name> --defaultfrontend <mode>
```

- name: VM名
- mode: 
    - gui ... デフォルトの通常起動
    - headless ... ヘッドレス起動
    - separate ... 　デタッチモード起動（ヘッドレス＋デタッチ可能なディスプレイ表示）
PHPのunserializeでクラスプロパティに変更があった場合

何となく気軽にセッションにオブジェクトを保存していて、クラスに変更があった場合にどうなるのか気になったので動かしてみた。
PHP 7.2

```php:Foo.php
<?php
class Foo
{
    private $id;
    protected $name;
    public $attributes = [];

    public function __construct(int $id, string $name, array $attrs)
    {
        $this->id = $id;
        $this->name = $name;
        $this->attributes = $attrs;
    }
}
```

```php:serialize.php
<?php
require_once 'Foo.php';
$foo = new Foo(3, 'foo', ['bar' => 'baz', 7]);
echo serialize($foo);
```

```php:unserialize.php
<?php
error_reporting(-1);
require_once 'Foo.php';
$data = stream_get_contents(STDIN);
var_dump(unserialize($data));
```

普通にserialize => unserialize を実行するとこうなる。

```
$ php serialize.php | php unserialize.php
/tmp/php/unserialize.php:5:
class Foo#1 (3) {
  private $id =>
  int(3)
  protected $name =>
  string(3) "foo"
  public $attributes =>
  array(2) {
    'bar' =>
    string(3) "baz"
    [0] =>
    int(7)
  }
}
```



プロパティが増えた場合。

```php:Foo1.php
<?php
class Foo
{
    private $id;
    protected $name;
    public $attributes = [];
    public $opt;
    public function __construct(int $id, string $name, array $attrs, ?string $opt)
    {
        $this->id = $id;
        $this->name = $name;
        $this->attributes = $attrs;
        $this->opt = $opt;
    }
}
```

```
$ php serialize.php | php unserialize1.php
/tmp/php/unserialize1.php:8:
class Foo#1 (4) {
  private $id =>
  int(3)
  protected $name =>
  string(3) "foo"
  public $attributes =>
  array(2) {
    'bar' =>
    string(3) "baz"
    [0] =>
    int(7)
  }
  public $opt =>
  NULL
}
```

増えたプロパティが単に`null`になる模様。特にエラー等は無い。

プロパティが減った場合、アクセス修飾子が変わった場合は？

```php:Foo2.php
<?php
class Foo
{
    protected $id;
    public function __construct(int $id)
    {
        $this->id = $id;
    }
}
```

```
$ php serialize.php | php unserialize2.php
/tmp/php/unserialize2.php:8:
class Foo#1 (3) {
  protected $id =>
  int(3)
  protected $name =>
  string(3) "foo"
  public $attributes =>
  array(2) {
    'bar' =>
    string(3) "baz"
    [0] =>
    int(7)
  }
}
```

`protected` に変更した`$id` は `protected`に変更された。プロパティごと削除したものは`protected`、`public`を維持して復活した。

まあそうなるよねって感じなんだけど、`protected`を維持して復活したのが少し意外だった。PHP的には未定義プロパティへの代入と見なして`public`に変わってもおかしくないような。

この動作はどこかに書いてるんだろうか？
https://php.net/unserialize
https://php.net/oop5.serialization
見つけられなかった。
訓練されたPHPerなら良い感じに復元してくれることを想定してるでしょってことか。

`E_NOTICE`が出る可能性もあるかなと思ったけど、そもそも復元失敗した場合が`E_NOTICE`だからプロパティが違ったぐらいじゃエラーにならないか。
AzureでSendGridを利用してメール送信 (5分で)

　AzureのMarketplaceにて、メール配信サービスのSendGridが利用できます。
今回SendGridアカウントの作成から、簡単なPowershellでのメール送信を試すところまで実践してみます。

正直かなり簡単にメール送信できます。

## AzureでSendGridアカウント作成
Azureコンソール左上「リソースの作成」より"SendGrid"と検索します。
<img width="251" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/e19e6c76-cccc-554c-fe25-693134f3fae7.png">
「作成」をクリックします。
<img width="311" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/14304574-f3f2-6d1a-14da-ba18208f7542.png">

こちらでアカウントの作成です。
<img width="202" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/a2b42723-0303-9833-88d6-a4db5fc9d6a2.png">
Name：任意
Password：任意
Resourcce group任意
Pricing tier：今回freeでやります(無料で月25,000通メール送信可能なようです)。
その他条項など同意し「作成」をクリックします。  

作成されたらSettings > ConfigurationsよりUsernameとSMTP serverを控えておきます。
<img width="464" alt="キャプチャ4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/cf69b53e-1357-61d2-b952-0dd3ea35193d.png">

## Powershellでメール送信確認
Powershellを立ち上げ、以下実行します。

```
Send-MailMessage -From <任意の送信元メールアドレス> -To <送信先メールアドレス> -Subject "<件名>" -Body "<メール本文>" -SmtpServer <先程コピーしたSMTP server> -Port 587 -Credential <先程コピーしたUsername>
```

資格情報を要求されるのでSendGridアカウント作成時に設定したパスワードを入力します。
<img width="157" alt="キャプチャ5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/cbbb68c4-4050-dc7a-43a8-475250cf32fb.png">

するとメールが送信されていると思います。

以上になります。
イーロン・マスクとジャック・マーがAIについて語ったら


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124978/2712419a-1b6a-6555-b0d4-72380f747095.png)


# イーロン・マスクとジャック・マーの対談 - AIは脅威なのか

ちょっと前にアメリカのイーロン・マスク（Tesla、SpaceX、Boring、Neural Link)と中国のジャック・マー（アリババ）の二人による対談があり、その様子を収めた[ビデオ](https://www.youtube.com/watch?v=f3lUEnMaiAU)がアップされていました。


その中でAIに関する議論があったのですが、結構興味深かったです。

マスクはAIは人間にとって脅威であるという立場の人で、ジャック・マーは脅威にはならないと言う立場の人です。

マスクは自分が関わっているTesla、SpaceX、Neural Linkといった会社でも最先端のAIを研究し実際に使っている「現場」の人ですし、さらにこれまでも誰もが無理だと思うような大風呂敷を広げてはそれをやり遂げてきたスーパー・ヒューマンなので、彼が「AIは人間にとって脅威となりうる」と言うときには、真剣に耳を傾けるべきだと思います。

そこで、AIに関する議論の部分だけをハイライトとして紹介したいと思います。

以下、訳。

---

マスク：多くの人はAIにできることというのを少なめに見ている。彼らはAIをスマートな人間だと思っている。しかし、AIは私達が知りうるどんなスマートな人間よりもさらにはるかにスマートになるだろう。

マー：私が生きている限り人間がコンピューターにコントロールされることになるとは思わない。それは不可能なことだ。人間が人間よりスマートなものを作れるわけがない。

マスク：それには全くの反対意見だ。多くの人が犯してしまう最も大きな間違えとは、自分がスマートだと思ってしまうことだ。

マー：コンピューターはより賢い（clever）かもしれないが、人間はよりスマートだ。

マスク：あー、それは完全に違う。

マー：私は楽観的だ。AIが驚異となることはない。AIはそんなにひどいものにはならない。人間は十分にスマートなのでそのことを学ぶことになる。私達のような人間は、ストリート上がりのスマートなので、そんなものを恐れるわけがないんだ。

マスク：おれはそうは思わない。そういうのを「死ぬ前に言った有名な最後の言葉」っていうんだ。今から40年、50年前にPongっていう卓球のビデオゲームがあったけど、あれは2つの長方形と一つの正方形があるだけだった。それが今や、40の仮想現実のリアルタイムのシミュレーションがあってそこでは何百万人って人たちが同時にゲームを行っているんだ。どれくらいの率かはさておき、とにかくさらにどんどんよくなっていくんだと仮定すると、こうしたゲームはそのうち現実世界との区別がつかなくなるだろう。2つの世界の違いは誰にも区別がつかなくなるんだ。それをよしとするか、そうでなければ文明は終わる。

マー：賢い（Clever）は知識ドリブン、スマートは経験ドリブンだ。コンピューターは人間が作り出した一つの賢いツールだ。コンピューターは賢い、しかしこれから人間によって作り出されるコンピューターよりももっと賢こいツールがもっとたくさんでてくるだろう。

マスク：AIはいずれ人間を完全に再現することになるだろう。そしてそれは多くの人をいっぺんに再現するということだ。実際、すでに私達はコンピューターによって作られたシミュレーションの中で生きていると強く主張するものもいる。

---

以上、訳終わり。

私もAIが近いうちに私達人間にとっての脅威とはならないと思う立場ですが、それにしてもマスクの言うことには説得力があります。

そして、最後の部分なのですが、実は私達はすでにコンピューターによってシミュレートされた世界に生きているのではないかというのには、ちょっと考えさせられてしまいます。

私達が想像しているのとは違う形で、AIが私達をコントロールし始めるというのはひょっとしたら思ったよりも早く起きることになるのかもしれません。

AIの進化に関してはこれからも注意が必要だというのは間違いないですね。

---

# データサイエンス・ブートキャンプ、11月開催！

次回の[データサイエンス・ブートキャンプ](https://ja.exploratory.io/training-jp?utm_campaign=elon_vs_jack&utm_medium=blog&utm_source=qiita)は11月です！

データサイエンス、データ分析の手法を１から、体系的に学び、現場で使える知識とスキルを身につけていただくためのトレーニングです。

データを使ってビジネスを成長させたい、または問題を解決したいという方は、ぜひこの機会に参加をご検討ください！

詳細は[こちらのページ](https://ja.exploratory.io/training-jp?utm_campaign= elon_vs_jack&utm_medium=blog&utm_source=qiita)にあります。
【初心者が】APIとはなんなのか【調べてみた】

#はじめに
はじめまして。IT企業に勤めている者です。
企画寄りの業務に携わっていますが、技術に関しての知識の乏しさを痛感しています。
というわわけで「聞いたことはあるけど理解しきれていない、周りで気になる単語」
について自分なりに調べていこうと思います。

今回は`API`についてです。
いまのほぼノー知識な状態だと「あー…なんか、提供元の情報簡単に使えるようになりますよみたいな……？」
とぼんやりした感覚しかないのでこれを機に調べてみることにしました。

いつの時代の話をしているんだという感じですが
いつも調べっぱなしで後に何度も同じことを調べてしまうので自分用のメモも兼ねてまとめます。

##そもそもAPIとは？
「Application Programming Interface」の略。
英文をそのまま受け止めると「アプリケーションをプログラミングするインターフェース」？
ちょっとよくわからないです。

##Wikipediaに聞いてみた
>
「OSやミドルウェアやWebサービス等サービスを利用するアプリケーション(Application)を作成する(Programming)ためのインターフェース(Interface)である。」
引用元：「アプリケーションプログラミングインタフェース」（2019年3月11日 (月) 21:55　UTC）『ウィキペディア日本語版』
https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9

……うーんなるほどよくわからん。
※余談ですがWikipedia自体にもAPIが用意されているみたいです。どう使うんだろう。

##APIとはソフトウェアの機能やデータを提供するもの
いろいろ調べた結果、↑という解釈に落ち着きました。イメージは以下の通り。
データ提供：あるキー項目に該当する値を応答
<img width="70%" alt="01" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482205/52a310f5-e275-e609-01fc-507c1d84fc54.png">
↓
<img width="70%" alt="01" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482205/c5a0d7d1-4e7a-435c-0c13-5147d50c653e.png">
↓
<img width="97%" alt="01" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482205/8b4c1c36-3bd6-e342-f235-993b372327a8.png">

上記の図はあくまで「キー項目をもとに」「特定のデータ項目を取得する」
という単純な構図ですが実際には機能提供／利用もできます。

わかりやすい例でいうと
facebookの認証機能の利用してinstagramの認証を行うとか、
アプリ間の認証共有などがあるようです。

※余談ですが「Instagram API」は2020年初めまでに廃止されるそうです。へぇ……
　その代わり？に「Instagram Graph API」が提供されているそうです。へぇ～～
　参考ページ：
　「Instagram API、一部機能の提供終了。その理由と今後の対応策とは？」
　https://gaiax-socialmedialab.jp/post-58019/
　「「Instagram API」が廃止に！代替の「Instagram Graph API」に移行しよう！」
　https://web.analogstd.com/tips/posts/api/instagram-grapgh-api-facebook.php

まだフワっとした理解なのでもうちょっと深めていきたいです。

##これからについて
なんとなく概要は理解したものの、やはり実際に手を動かさないと身につかない気がします。
というわけで、９月いっぱいを目標に簡単なAPIを作ってみたいと思います。
※イメージとしては
　「用意したリストに対してキーが入力されたらそれに対応するデータを応答する」
　くらいのレベルのものを想定しています

##参考ページ
「WebAPIについての説明」
https://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47
⇒一番はじめに参考にさせていただいたページ。
　新人向けの説明と銘打っているだけあって初心者にも理解しやすいページで大変助かりました。

「今さら聞けないIT用語：やたらと耳にするけど「API」って何？」（データのじかん）
https://data.wingarc.com/what-is-api-16084
⇒大変参考になりました。

#おわりに
最近 
社内ニート
 案件の谷間で時間ができたのでいまのうちに勉強しようと思っています。
漫然と調べものをしても見につかなさそうなのでちょこちょこアウトプットもしていきたいです。
おすすめの書籍なんかありましたら教えていただけると喜びます。
GAEにDatadog APMを導入する

## 概要
Datadog版のAPMです。
[Datadog APM](https://www.datadoghq.com/apm/)を導入すると、APMとして機能はもちろんですが、
機械学習をベースとした[Watchdog](https://docs.datadoghq.com/ja/watchdog/)という機能でアプリケーションレイヤとインフラレイヤのメトリクスを学習し、異常を自動検出してくれる機能も利用できるそうです。便利ですね。

ただし、GAEにDatadog APMを導入しようと思い、オフィシャルの手順を見ると情報がこれしかありません。。
<img width="1330" alt="スクリーンショット 2019-09-12 14.30.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/b839bae9-8d6f-369a-c325-bab06ad24155.png">

これだけだと具体的に何をどう設定すれば良いか分からないため、導入した時の手順を残します。

## 流れ
* GCEにDatadog Agentをインストール
* datadog.yamlの設定変更
* Firewallの設定
* Trace送信先の設定

## 手順
### 1. GCEにDatadog Agentをインストール
説明にもあったようにGAE単体ではAPMの導入ができず、GCE等にDatadog Agentをインストールし、
そこのホストにトレースデータを送信するようにしないといけません。
流れとしては、GAE -> GCE(Datadog Agent) -> Datadog APM といったイメージでしょうか。

Agentのインストール方法は、Datadogのアカウントをお持ちの方であれば、
[こちら](https://app.datadoghq.com/account/settings#agent)の手順を参考にしてください。
OSごとにインストール方法が別れています。
<img width="1044" alt="スクリーンショット 2019-09-12 14.48.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/fec9c984-878a-2675-0c6b-d21ca9fa5c2c.png">

### 2. datadog.yamlの設定変更
次に`/etc/datadog/datadog.yaml`を以下のように修正し、Datadog Agentを再起動します。
コメントアウトを外すだけです。

```yaml

apm_config:
  enable: true
  receiver_port: 8126
  apm_non_local_traffic: true
```

他プラットホームのトレースデータを受ける場合は、`apm_non_local_traffic: true`を設定します。
これは通常の構成ではローカルからtracerを受信するのに対して、
エージェントから見ると外部の環境からのtracerを受信する事になるためです。

### 3. Firewallの設定
さきほどの設定で8126ポートをレシーバーポートとして設定しました。
GCEの場合はFirewall設定で8126ポートへのアクセスを許可してあげる必要があります。
`ネットワークタグ`を使って8126ポートを許可してあげると良いと思います。

### 4. Trace送信先の設定
次にTrace送信先を設定します。
Rubyを例にすると、Datadog Agentが起動しているGCEのIPアドレスとポート(8126)を設定します。
以下のサンプルコードの5行目で、環境変数から取得したホスト名をtraceの送信先として設定してます。
https://github.com/DataDog/trace-examples/blob/master/ruby/rails/config/initializers/datadog.rb#L5

詳細は、[こちら](https://docs.datadoghq.com/tracing/setup/ruby/#advanced-configuration)のオフィシャルドキュメントを参考にしてください。
他の言語については、[こちら](https://docs.datadoghq.com/ja/tracing/setup/)を参照してください。


それでは良いDatadog Lifeを。
Amazonの検索結果から怪しい商品を消す

# 何これ
Amazonでメーカー不詳の怪しい商品が多くて検索ノイズがひどいので作った。

怪しい商品は商品タイトルが妙に長ったらしい(単語数が多い)のでそれに着目。

Amazonのページがリニューアルされたりすると使えなくなるかも。

あと怪しくない商品でもタイトルに単語並べまくられてると誤判別する。

※言うまでもなく無保証・自己責任

```javascript:ブックマークレット
javascript:(()=>{var texts = document.getElementsByClassName("a-size-base-plus a-color-base a-text-normal");var filt = Array.prototype.slice.call(texts).filter((item, index, all)=>{ return item.innerHTML.split(/\+|\/|\s|[（）、]/).filter(a => a).length < 15 ? false : true;  });for (var i = 0; i < filt.length; i++) {filt[i].closest(".s-result-item").style.opacity = "0.3";}})();
```

↓実行すると怪しい商品と判定された商品は薄い色で表示される


**※業者に何か言われないようにモザイクをかけている**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28988/5e934462-e54c-e85d-2415-be24bbf69e9d.png)

# どう使う

1. ブラウザブックマークに登録
1. Amazonの検索結果ページで実行

# 何やってる

怪しい商品は商品タイトルに単語数が多いのでそれを使い判別。

1. Amazonの検索結果の商品タイトルをスペースや/などで区切って単語を得る
1. 空の単語を除去
1. 単語数が15以上になってる商品は要素を見えにくくする

「Bluetooth イヤホン」の検索結果だと割と普通の有名メーカーのみに絞れたが、
「USB-C ケーブル」の検索結果とかだとAnkerとかAmazonのケーブルが怪しい商品判定されてしまっていた。

15としている値は適宜変更すると良いかも。

検索結果で毎回押さないといけないのでChrome拡張とかにすると便利かもしれない。（誰かやってほしい）
ディープラーニングで使う活性化関数を可視化してみた

自分用のメモ

なんか調べたら同じような記事があったけど気にしない。
[同じ本](https://www.oreilly.co.jp/books/9784873117584/)を参考にしたから仕方ない

# ステップ関数
閾値より小さかったら0、大きかったら1を返す（今回の例では0を閾値とする）

```math
h(x)=\begin{cases}
  0\quad(x \leqq 0) \\
  1\quad(x > 0)
\end{cases}
```

```python
def step_function(x):
    return np.array(x > 0, dtype = np.int)

x = np.arange(-5.0, 5.0, 0.1)
y = step_function(x)

plt.plot(x, y)
plt.show()
```
![ステップ関数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/230d8d7a-9ad6-338e-6b73-0db3e9fb8c6c.png)

# シグモイド関数

ステップ関数の上位互換
値を0~1にスケールする

```math
h(x) = \frac{1}{1 + e^{-x}}
```

```python
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)

plt.plot(x, y)
plt.show()
```
![シグモイド関数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/946ee30c-7888-50b8-a8c4-c6f377e71258.png)


# tanh関数

シグモイド関数の上位互換。
勾配消失問題が起こりにくいように線形変換させたけどやっぱり勾配消失問題が起こることもあるらしい

```math
h(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}
```

![tanh関数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/048b3cf4-8c63-5dda-227c-1e8d1cfdf103.png)
# ReLU関数

tanh関数の上位互換。
0以下だったら0、0より大きかったら入力した値をそのまま返す

```math
h(x)=\begin{cases}
  0\quad(x \leqq 0) \\
  x\quad(x > 0)
\end{cases}
```

```python
def relu(x):
    return np.maximum(0, x)

x = np.arange(-5.0, 5.0, 0.1)
y = relu(x)

plt.plot(x, y)
plt.show()
```

![ReLU.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/453b52ef-1bb0-2f43-a2eb-58157be6647e.png)


# ソフトマックス関数

0~1で総和が1になるように返してくれるやつ。確率っぽく扱えるようになるから出力層で使われがち。大小関係が変わらないから使う必要はないって言ってる人もいる

```math
y_k = \frac{e^{a_k}}{\sum_{i=1}^ne^{a_i}}
```

```python
def softmax(a):
  exp_a = np.exp(a)
  sum_exp_a = np.sum(exp_a)
  y = exp_a / sum_exp_a
  return y

x = np.arange(-5, 5, 0.1)
y = softmax(x)
plt.plot(x, y)
plt.show()
```

![ソフトマックス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/81b80341-c0ab-b546-1124-e47ebd876b6c.png)

# 恒等関数

入力された値をそのまま返すやつ。趣深い。いとをかし。

```math
h(x)=x
```
```python
def identity_function(x):
    return x
x = np.arange(-5, 5, 0.1)
y = identity_function(x)
plt.plot(x, y)
plt.show()
```

![恒等関数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492154/5fe22af2-11fe-1a62-497c-04af223d05dd.png)
PHPUnitを動かすと「No application encryption key has been specified.」で怒られた話

# はじめに
題名の通り、PHPUnitを動かした際に `No application encryption key has been specified.` でほとんどのテストがエラー落ちしていました。

しかしながら暗号キーは設定済みです。envにもちゃんと記載されていました。
原因が何か理解するまでに結構時間を取られてしまったので、備忘録として残しておきます。

因みにLaravelは5.5を使用しています。

# エラーの内容
まず、テストがエラー落ちしている原因ですが、題名にもあるように `No application encryption key has been specified.` というExceptionが発生しているからです。

このExceptionはenvファイルのAPP_KEYの値が適切でない場合は起こります。
.env.exampleをコピーしてそのまま使っていたーっていう場合に良く起きます。

この時はプロジェクトルートで `php artisan key:generate`を打つことで自動で.envの中のAPP_KEYに暗号キーを設定してくれます。

# 今回のケース
今回も同じExceptionが発生しているのですが、暗号キーが設定されていないわけではありません。
localhostで稼働しているシステムにアクセスすれば普通にページが見れていました。
PHPUnitを走らせたときにだけ発生してます。

> テスト実行前には、config:clear Artisanコマンドを実行し、設定キャッシュをクリアするのを忘れないでください。

[公式ドキュメント](https://readouble.com/laravel/5.5/ja/testing.html)を見ると上記のように書いているので `php artisan config:clear` を叩いて設定キャッシュをクリアしましたがそれでもダメでした。

# 解決策
解決する方法ですが、`config:clear` だけでは不十分だったようです。
一度設定キャッシュをクリアし、最新の設定情報を再度キャッシュさせる必要がありました。

```
$ php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!
```

`php artisan config:cache` を叩くと、クリアとキャッシュの両方を行ってくれます。
こうして、最新の設定情報をキャッシュさせた状態でPHPUnitを動かすと、先ほどのExceptionは発生しなくなりました。

# まとめ
キャッシュのクリア後には、再度キャッシュするのを忘れないこと！
Mind for Android の64bit対応

　Mind for Androidのパッケージローダの一部であるサービスのモジュール（MindPkgService）が、使用中に落ちてしまうことがあり長い間調べていた。
　当初はプログラムのミスかと思ってたが、結局「Androidのサービスとは元々そういうもの」ということが分かった。Windowsのサービスのような感覚で作ってはいけないらしい。
　もちろん回避方法はあり、私が知らなかっただけなのだが、Android 8 以降でその手続きが変更になったこともあり結構手がかかった。もちろんこれはランタイムライブラリ内部の改修なのでMind利用者から見れば従来通りの使い方で良い。
　
　それで１ヶ月ほどかかって改修が終ったのでいざ新版をGoogle Playに登録しようとしたら別件で登録がハネられた(^^;。
　Google Playは8月から64bit対応でないコードを含むアプリを登録（アップデート含む）できなくなっていた。（実は64bit対応必須になることは去年の段階から知っていたのだが11月からと思い込んでいた）
　
　64bit対応とは具体的にはMindのC記述部（カーネル）を改造することである。分量が多いので64bit化をどうするかこれから悩まないといけない。
　当然だがMindコンパイラ自体は64bit対応の必要はない（Androidのアプリのパッケージにコンパイラが含まれるわけではないから）。そもそもコンパイラが64bitになったからといって嬉しいことは何もない。だからランタイムライブラリの64bit化の話になる。
　そもそも、JNIの仕組みは（たぶん）「どうしてもという部分のみスポット的にCで書く」ことを想定しているだろうから、Mindのカーネルのように結構な規模のコードを書くのは異端ではある。
elasticbeanstalkでGPG keyを追加

### 要約

- aws elasticbeanstalkでデプロイ中に以下のようなエラーが出る
The GPG keys listed for the "xxx" repository are already installed but they are not correct for this package
- 手動で追加したリポジトリのGPG keyをインポートできてなかった
- .ebextensionsにインポートコマンドを追加して解決

### エラー
```bash
The GPG keys listed for the "xxx" repository are already installed but they are not correct for this package
```
GPG keyとは
yumやapt-getでインストールするパッケージの検証用鍵
https://tech.nikkeibp.co.jp/it/article/Keyword/20091204/341579/

あるパッケージのgpg keyをimportできてなかったのでeb deploy中にエラーになっていた

### 解決法

```shell
commands:
    import-gpg-key:
        command: rpm --import https://path-to-gpg-key
        command: rpm --import https://path-to-gpg-key
```
GitLab CIでGitのブランチを自動生成

# はじめに
どうも！生産技術部のエンジニアです。GitLab CIを使って、masterブランチにpushが行われた際にブランチを自動生成するスクリプトを作成しましたので、紹介します。

GitLabサーバを一から構築される方は、以下からご覧ください。
[「proxy環境下でDocker Composeを用いてCentOS7上にGitLab Dockerを作成」](https://qiita.com/TomoyukiSugiyama/items/ba7ef0ebab8242dbacb0)

# 環境
* CentOS : 7.6.18.10
* Docker-CE : 19.03.1
* Docker Compose : 1.25.0-rc2
* GitLab-CE Docker : 12.2.0-ce.0
* GitLab Runner Docker: 12.2.0


# 前提条件
GitLab、GitLab Runnerの導入が実施済みであること。


[「proxy環境下でDocker Composeを用いてCentOS7上にGitLab Dockerを作成」](https://qiita.com/TomoyukiSugiyama/items/ba7ef0ebab8242dbacb0)
[「Docker Composeを用いてCentOS7上でGitLab Runner Dockerを作成」](https://qiita.com/TomoyukiSugiyama/items/b17800d4e142e3dc549b)
を参考に導入してください。

# サービス用のアカウント作成
シェルスクリプトからgitコマンドを実施する際に、リポジトリに対するアクセス権がないユーザから`git push`を実施しようとするとエラーが発生し、失敗します。そこでスクリプトからコマンドが使えるように、サービス用のアカウントを作成します。サービス用のアカウントから、全てのリポジトリにアクセスできるように`Admin Area`->`Overview`->`Users`からAdmin権限を付与しておきます。

今回作成するアカウントは、
User Name : GitlabRunner
Password : gitlabrunner
Email Address : gitlab@service.example.com
とします。これは一例です。

# Gitのブランチを自動生成するスクリプト
`gitlab-ci.yml`は[GitLab公式ドキュメント][link-yml]を参考に作成し、pre-releaseステージで本題のブランチ自動生成を行なっていきます。`pre-release.sh`が実行できるように、`chmod`を用いて実行権限を付与します。

```yaml:gitlab-ci.yml
stages:
  - build
  - test
  - pre-release
  - deploy

job 1:
  stage: build
  script: echo "build"

job 2:
  stage: test
  script: echo "test"

job 3:
  stage: pre-release
  script: 
    - chmod u+x pre-release.sh
    - ./pre-release.sh
  only:
    master

job 4:
  stage: deploy
  script: echo "deploy"
```
`pre-release.sh`で`git push`が正常で行えるように`user.name`、`user.email`を設定します。ログイン時のユーザ確認、パスワード入力を不要にするため、`set-url`にユーザ名、パスワードを設定します。CI_REPOSITORY_URLを使用する事で、リポジトリのURLを省略出来ます。

```bash:pre-release.sh
#!/bin/bash
git config --global user.name "GitlabRunner"
git config --global user.email gitlab@service.example.com
git remote set-url origin http://GitlabRunner:gitlabrunner@${CI_REPOSITORY_URL#*@}
git branch -d pre-release
git checkout -b pre-release
git push -u origin pre-release
```

[link-yml]:https://docs.gitlab.com/ce/ci/yaml/README.html#stage

# 最後に
ブランチを生成するスクリプトを作成しました。Gitサーバの運用に関して、まだまだ準備が必要そうなので、徐々に整えていこうと思います。

# ご参考
* [GitLab CI/CD Pipeline Configuration Reference](https://docs.gitlab.com/ce/ci/yaml/README.html)
エイリアスを設定して楽にimportできるようにする

Reactを書いていると、コンポーネントやReduxのstoreなど様々な単位でディレクトリを分けることになる。
分けることで、ファイル自体のコード量が少なくなったり、責務が明確になってメリットが多い。

しかし、ディレクトリをバンバン切っていくと、import時に`'../../../../../Header'`のような「.」地獄が発生する。
正直、相対パスでたどるのが難易度が高い。
エディタのパス補完があっても、ときどき..が多くなったり、少なくなったりして「見つからないよ」とエラーが出る。

もうたくさんなので、エイリアスを設定して楽にimportできるようにした。

## Webpack
まずは、Webpackに設定する。
このように記述することで、`import Something from "@/hoge/fuga/Piyo"`でインポートできるようになる。
@はsrcディレクトリの同義なので、上記のimportは`src/hoge/fuga`ディレクトリにあるPiyoというファイル内でexport defaultされたものをインポートしていることになる。

```js:webpack.config.js
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "src")
    }
  },
```

## Jest
次にテストでおなじみのJestに対する設定を行う。
テストファイルで、先程のように`import Something from "@/hoge/fuga/Piyo"`と書いても該当のファイルが見つからないとなる。
Jestがテストを実行しているときに、webpackを介していないのでエイリアスを認識できていないからだと思われる。

そこで、設定ファイルにエイリアス`@`が何を示しているのかを記述する。

```js:jest.config.js
  moduleNameMapper: {
    "^@/(.*)$": "<rootDir>/src/$1"
  },
```

## TypeScript
これがないと、VS Codeで警告が出てしまった。

```json:tsconfig.json
{
  "compilerOptions": {
    "paths": { "@/*": ["src/*"] },
  }
}
```
jsonからcsvに変換してみる

2019-09-13 追記: 逆バージョンもやってみた。

----

久々に再帰とか使った。

```ruby

def json_to_csv(src_json_path, out_csv_path)
  data = JSON.parse(IO.read(src_json_path))
  @result = {}
  recursive_parse('', data)

  header = @result.keys.join(",")
  body = @result.values.join(",")

  open(out_csv_path,'w') do |f|
    f.puts(header)
    # 改行を空白に置換
    f.puts(body.gsub("\n", " "))
  end
end

def recursive_parse(chain_key, obj)
  if obj.class == Hash
    obj.each { |k,v| recursive_parse(chain_key + "|" + k.to_s , v )}
  elsif obj.class == Array
    obj.each_with_index { |v, idx| recursive_parse(chain_key + "|[" + idx.to_s + "]", v)}
  else
    @result[chain_key] = obj
  end
end

json_to_csv('./tmp/test_data.json', './tmp/out.csv')

```

戻す方はなんか長くなったのでクラスにしてしまった。

```ruby
# frozen_string_literal: true

# reCreate json from csv
class CsvToJson
  require 'json'

  EMPTY_VAR_NAME = '@empty_json_hash'
  COPIED_VAR_NAME = '@copied_json_hash'

  def csv_to_json(src_csv_path, out_json_path)
    @empty_json_hash = {}

    File.open(src_csv_path, 'r') do |f|
      @header = f.gets.chomp
      @bodies = f.each_line.inject([]) { |res, line| res << line.chomp }
    end
    header_to_json_object(@header)

    @bodies.each_with_index do |body, idx|
      @copied_json_hash = @empty_json_hash.dup
      values_into_json_object(@header, body)

      File.open(renamed_path(out_json_path, idx), 'w') do |f|
        f.puts JSON.pretty_generate(@copied_json_hash)
      end
    end
  end

  private

  def renamed_path(path, idx)
    File.dirname(path) + "/#{idx}_" + File.basename(path)
  end

  def header_to_json_object(line)
    object_define_list = line.split(',')
    object_define_list.each { |item| recursive_parse_define_string(item, 0) }
  end

  def make_tree(items, var_name)
    items.inject(var_name) { |res, i| res + (/\[|\]/ =~ i ? i : "[\"#{i}\"]") }
  end

  def suffix(target)
    /\[|\]/ =~ target ? ' = []' : ' = {}'
  end

  def recursive_parse_define_string(item, depth)
    buffer = item.split('|').reject(&:empty?)
    current = make_tree(buffer[0..depth], EMPTY_VAR_NAME)
    next_index = depth + 1

    # element at bottom. so exit this method
    return eval(current + " = ''") if next_index == buffer.length

    eval(current + suffix(buffer[next_index])) unless eval(current)

    recursive_parse_define_string(item, next_index)
  end

  def values_into_json_object(header, body)
    headers = header.split(',')
    bodies = body.split(',')

    headers.each_with_index do |item, idx|
      buffer = item.split('|').reject(&:empty?)
      eval(make_tree(buffer, COPIED_VAR_NAME) + ' = ' + "\"#{bodies[idx]}\"")
    end
  end
end

CsvToJson.new.csv_to_json('./tmp/out.csv', './tmp/out.json')

```
"xxxxx_development" is being accessed by other users

##"xxxxx_development" is being accessed by other usersエラー

```ruby
bin/rails db:migrate:reset
PG::ObjectInUse: ERROR:  database "xxxxx_development" is being accessed by other users
DETAIL:  There are 2 other sessions using the database.
: DROP DATABASE IF EXISTS "xxxxx_development"
Couldn't drop database 'xxxxx_development'
```


```ruby

psql -l //データベース名を確認
psql postgres //postgreSQLにログイン
\du //ユーザーと権限を確認

#この場合、接続中のユーザセッションを強制的に切断後に再実行します。
#まずは、接続中のユーザのpidを以下のコマンドで求めます。
postgres=# SELECT pid FROM pg_stat_activity where pid <> pg_backend_pid();
  pid  
-------
 82450
 82454
 21658
(3 rows)

＃接続中のユーザセッションを強制的に切断する
postgres=# SELECT pg_terminate_backend(82450);
 pg_terminate_backend 
----------------------
 t
(1 row)

postgres=# SELECT pg_terminate_backend(82454);
 pg_terminate_backend 
----------------------
 t
(1 row)

postgres=# SELECT pg_terminate_backend(21658);
 pg_terminate_backend 
----------------------
 t
(1 row)

#抜ける
postgres=# \q

```

正常に動いた！

参考
http://kzdev.hatenablog.com/entry/2017/09/21/125839
deviseでユーザー名からログインできるようにする

##はじめに
deviseはデフォルトでemailとpasswordで新規登録、ログインする仕様になっているため、ユーザー名から登録、ログインできるようにする方法について投稿します。

##deviseとは
ユーザーの新規登録、ログイン、ログアウトなど、認証に必要な機能を追加することができるgemです。

##deviseの導入方法について
【参照】
https://qiita.com/cocoa-engineer/items/625da569fcac1ad2db1f

##Userモデルにusernameカラムを追加する
まず、マイグレーションファイルを作成します。
※Userモデルの作成は、上記「deviseの導入方法について」参照。

```ruby
$ rails g migration add_username_to_users username:string
```
作成されたマイグレーションファイルを実行する。

```ruby
$ rails db:migrate
```

##Strong Parameterの設定
usernameを登録できるように、application_controller.rbにStrong Parameterを設定します。

```application_controller.rb
class ApplicationController < ActionController::Base
 before_action :configure_permitted_parameters, if: :devise_controller?

 protected

 def configure_permitted_parameters
   devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
   devise_parameter_sanitizer.permit(:sign_in, keys: [:username])
   devise_parameter_sanitizer.permit(:account_update, keys: [:username])
 end
end
```

##登録時にemailを不要にする

登録時にemailを不要にしたい場合、user.rbに以下を追記します。


```user.rb
class User < ApplicationRecord
 #usernameを必須・一意とする
 validates :username,uniqueness: true
 devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable

 #登録時にemailを不要にする
 def email_required?
   false
 end

 def email_changed?
   false
 end
end
```

##devise設定ファイルの編集

devise.rbに以下を追記します。

```devise.rb
config.authentication_keys = [:username]
```

##Viewの変更

Viewにusernameの項目を追記します。

```views/registrations/new.html.erb
<h2>Sign up</h2>
    <%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
     <%= devise_error_messages! %>
         <div><%= f.label :username %><br />
             <%= f.text_field :username %></div>

         <div><%= f.label :password %><br />
             <%= f.password_field :password %></div>

         <div><%= f.label :password_confirmation %><br />
             <%= f.password_field :password_confirmation %></div>

         <div><%= f.submit "Sign up" %></div>
    <% end %>
```
edit.html.erbについても同様に、usernameの項目を追記したら完了です。

##参考サイト
https://qiita.com/dayone80/items/ce04b21690f5f50a5cfa
Auth0の機能まとめ


auth0の機能（メニューレベル）をまとめてみました。
何ができるんだっけ？って思った人はとうぞ


| 機能名         | 概要 |
| ------------ | ---- |
| tenant       |auth0上で複数のサービスを展開したい場合に利用する機能<br>UserDB/Rule/Hooksなどの機能全判を分離して扱うことが可能になる|
| applications |認証につなぐアプリケーション単位にアプリケーションを定義する機能<br>認証後のコールバック画面などを個別に定義可能となる|
| APIs         |認証後に認可させるAPIの定義機能|
| SSO          |アプリケーション間でログインを共有する機能|
|Connections-Database|認証情報・ユーザ情報を管理|
|Connections-Social|ソーシャル連携機能<br>トグルボタンのオンオフでログイン画面に連携ボタンが出てくる|
|Connections-Enterprise|LDAP/AD/SAMLなどのエンタープライズ認証連携機能|
|Connections-Passwordless|SMSログイン、メールログインなどのパスワードレス接続を設定する機能|
|Universal Login|Auth0の組み込み画面（ログイン/パスワードリセット..etc）のデザインを変更できる機能|
|Rules|認証のパイプラインファンクションを追加できる機能<br>ログイン後にユーザ属性追加するなど、認証後のカスタマイズできる|
|Hooks(BETA)|認証・ユーザ登録・ユーザ登録前にフック処理を追加できる機能|
|Multi-factor Authentication|多要素認証を追加できる機能<br>プッシュ/ワンタイムパスワード/SMS/メールなどで実現可能|
|Emails|Auth0の組み込まれているメール文章の変更機能<br>ウェルカムメール、パスワードリセット、アカウント検証メールなどの文章を変更できる|
|Logs|loggingの定義機能|
|Anomaly Detection|不正登録・アクセスからの保護機能<br>Brute-force Protection/Breached-password Detection|
|Extensions|サードパーティー制のアドオンを追加できる機能<br>github・ユーザのインポート/エクスポート等との連携ができる<br>つなげるサービスとの契約は個別に必要|
|custom domein|独自のドメインを設定できる機能<br>ドメインの契約は自分でやる必要がある|
CATS + material combinerで出るエラーの対応

みなさん、バ美肉してますか？

VRMからVRChatのデータを作るときに、
BlenderにCATSとmaterial combinerを使っている人は多いと思います。

さて、マテリアルを結合する際にこんなエラーが出ることがあります。

![error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985/194dc56c-444f-3314-db4f-8cbed34f85af.png)

combiner_ops.py 
Key Error:bpy_prop_collection[key] "Princpled BSDF" not found.

結論から言うと、Blenderを日本語化しているのが原因です。
エラーをでなくするにはBlenderのLanguageをEnglishにしましょう。

多分、日本語化したことで、"Princpled BSDF"が"プリンシプル BSDF"という名前になってしまい、
"Princpled BSDF"で探したときにnot found. になってしまうのが原因です。

それでは良いVRChat生活を！
JIRA 課題タイプ別の起票時メール通知設定使い分け

##JIRAの課題起票時のメール通知設定

プロジェクト全体に設定する場合は、管理画面の課題の通知スキームにて該当するプロジェクト用のスキームを作成し、その中の「課題が作成されました(システム)」に通知先の設定を行う。

課題タイプ別に設定する場合は、その課題タイプが使用するワークフローのトランジション「create」の事後処理で、Send an emailを追加して送付先、本文等を設定する。

##メール通知設定使い分け（非通知設定）

課題タイプ別にメール通知設定を使い分けする場合、ワークフローのトランジション「create」の事後処理でSend an emailを使うが、5つの課題タイプの内、１つだけメール通知したくない、あとは同じメール本文で構わないというケースでは面倒。
その場合は、通知スキーム中に任意カスタムイベント（非通知用として使う）を作成し、それをメール通知したくない課題タイプに対してセットすればよい。
　例：通知したくない課題タイプがサブタスクの場合
　　　①サブタスク用のワークフローを用意する。
　　　にそのトランジション「create」の事後処理にある
　　　「リスナーが処理できる 課題が作成されました イベントを発生させます。」を編集する。
　　　③編集画面にてイベントに非通知用として作成したカスタムイベントを設定する。
　　　④ワークフローを有効にする。


*JIRA Softwareバージョンは7.12.1*
【Unity】コンポーネントの有効化/無効化をボタン押下で切り替える

※ 初心者向け記事です。

# はじめに

ホラーゲームで、暗い部屋で懐中電灯つけたり、スイッチ押したら電球がついたりするギミックがよくあると思います。
それをどうやって実装するのか調べただけの記事です。

本記事では、懐中電灯を実装する例で進めます。

# 動作確認環境

- Windows 10
- Unity 2018.2.21f Personal

# 事前準備

3Dで新規プロジェクトを作成します。
次に、[Hospital Horror Pack](https://assetstore.unity.com/packages/3d/environments/hospital-horror-pack-44045) をアセットストアからImportします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/024a2bf8-8023-9dbd-6b3b-635dfdd2aead.png)

このAssetに含まれているDemoSceneに懐中電灯を追加してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/914e601f-74a4-454f-48b8-c62b5df7d06b.png)

### エラー解消したい場合

Importすると、下記のようなエラーが発生している状態になりました。

```
Assets/Editor/CrossPlatformInput/CrossPlatformInputInitialize.cs(91,34): error CS0619: `UnityEditor.BuildTargetGroup.WebPlayer' is obsolete: `WebPlayer was removed in 5.4, consider using WebGL'
```

91行目は、コメントアウトでOKです。（たぶん）

# 実装方法


## Lightを追加

はじめに懐中電灯のコンポーネントを追加します。
Hospital Horror PackのSceneでは、Cameraは「FPSController」→「FirstPersonCharacter」に含まれています。
Add Componentボタンを押下して、Lightを追加します。

TypeはSpot、
RangeとSpot Angleは、50とします。
もちろん絶対に50にしろということではなく、Sceneに合わせて値を調整してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/a799e52b-344c-bcec-3405-cd073e757b50.png)

## Buttonを追加

つぎにButtonを追加します。
Hierarchyタブで右クリックして、「UI」→「Button」を押下します。
そうすると、CanvasとButtonが追加されると思います。
Gameタブを見ながら、ボタンを配置を変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/b6798424-50a2-a3eb-70c4-fe430490f638.png)

## Scriptを追加

つきはScriptを用意します。
パスはどこでもいいです。
筆者はScriptsフォルダを新規作成して、そこに作成したcsファイルを配置しています。

命名以外は、ほぼUnity公式のコピペです。

公式では ```Update()``` 内に実装しています。
今回はボタンを押下をトリガーにするため、 ```OnClickXXX()``` を作成、実装します。

```csharp:SpotLightController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SpotLightController : MonoBehaviour {

    private Light spotLight;  // ON/OFFするライト

    // Use this for initialization
    void Start ()
    {
        spotLight = GetComponent<Light>();
    }
    
    // Update is called once per frame
    void Update ()
    {

    }

    public void OnClickLightButton()
    {
        spotLight.enabled = !spotLight.enabled;
    }
}
```

## Scriptをアタッチ/イベントを設定

FirstPersonCharacterに、さきほど作成したScriptをアタッチします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/1691714f-29de-6b00-b8fd-a4790ea068f6.png)

最後に、Buttonの ```On Click()``` 項目を設定します。
スクショの通りに設定すればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233011/984ee858-e766-7bbb-f781-1aea700cae5b.png)

これでボタンを押下して、懐中電灯のLightがON/OFFできればOKです。


# 参考文献

[コンポーネントの有効化と無効化 - Unity](https://unity3d.com/jp/learn/tutorials/topics/scripting/enabling-and-disabling-components)
yumでAzure CLIをインストールして実行

　タイトル通りyumでAzure CLIをインストールして、アカウントサインイン、Azure CLI実行までをやってみます。結構簡単です。

※CentOS7、rootユーザで実行しています。

## Azure CLIインストール、実行
まずCentOS上で以下コマンドを実行しインストールします。

```
# Microsoft リポジトリ キーをインポート
rpm --import https://packages.microsoft.com/keys/microsoft.asc

# azure-cli リポジトリ情報を作成
sh -c 'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/azure-cli.repo'

# インストール
yum install azure-cli
```

そしてloginコマンドを実行します。

```
az login
```

すると以下のように出力されます。

```
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXXX to authenticate.
```
指示通り、 https://microsoft.com/devicelogin をブラウザで表示させます。
<img width="351" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/a714a704-2997-d70d-1db2-fa68ea4d6e7f.png">
XXXXXXXX の部分を入力し「次へ」をクリックします。
サインイン画面になるので自分のアカウント情報でサインインしてください。

CentOSのほうを見ると以下のように出力されています。

```
[
  {
    "cloudName": "AzureCloud",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "isDefault": true,
    "name": "?????",
    "state": "Enabled",
    "tenantId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "user": {
      "name": "サインインアカウント名",
      "type": "user"
    }
  }
]
```

ここまできたらもうAzure CLIが使えるようになっています。

```
# VMのリストを出力するコマンド
az vm list
```
その他以下リンクより各リソースに対してCLI操作が可能です。
[・Azure CLI Reference](https://docs.microsoft.com/ja-jp/cli/azure/reference-index?view=azure-cli-latest)

## 参考
[・yumでのAzure CLIのインストール](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-yum?view=azure-cli-latest)
Linuxコマンド

## コマンドをメモがてらシェア
+ シンボリックリンク張替

~~~
ln -nfs /aaa/bbb AAA
~~~

+ ファイル存在監視

~~~
watch -n 5 -d ls -l
- -n:間隔（秒）デフォは２秒
- -d:変更箇所がハイライトされる
- ls -l:発行するコマンド。監視するっていうか指定間隔で指定コマンドを発行するだけ。
~~~

+ telnetなどでタイプミスした場合

~~~
Ctrl + Uでクリアされる
~~~
selectのvalueが取得できなかった原因

# 何がしたいか
selectフォームの値をデフォルト値の空文字で受け取りたい。

# 問題のコード
```html
<select name="dayOfWeeks">
  <option value="" selected disabled>選択</option>
  <option value="月">月曜日</option>
  <option value="火">火曜日</option>
  <option value="水">水曜日</option>
  <option value="木">木曜日</option>
  <option value="金">金曜日</option>
  <option value="土">土曜日</option>
  <option value="日">日曜日</option>
</select>
```

# 原因
disabledを指定しているとvalueが取れない！！
disabledで無効化しているので、言われてみれば納得です。
でもそんなの知らなかったです。勉強になりました。