OmniAICreator/Qiita-1.07M huggingface dataset:
shellをfishに変えて快適なターミナル環境を

##背景
自分は普段bashを使っていましたが、最近になってfishに変えました。
なかなかによかったので備忘録としても公開したいと思います。
ターミナルはitem2を使っています。

iterm2: https://www.iterm2.com/
fish: https://fishshell.com/

##fishとは
`Friendly Interactive SHell`の略。

- デフォルトでいい感じの見た目つけてくれる
- 過去に打ったコマンドから入力の補完してくれる
- 打てないコマンドだったら色で示してくれる
- ディレクトリ移動にも補完つけてくれる
etc..

**最後の方に移行後の画像載せてます。。。**

bashよりは見た目も良くなりますし(デフォルトで)、補完も効いてくれるので使いやすいです。

##導入
Homebrewでインストールします。
homebrew: https://brew.sh/index_ja

```terminal
brew install fish
```

##デフォルトのシェルをfishに

```terminal
sudo -s 

echo /usr/local/bin/fish >> /etc/shells

exit

chsh -s /usr/local/bin/fish
```
以上のコマンドを打つことによってシェルファイルにfishの情報を書き込み、ターミナルを開いた時のシェルをfishにしています。

導入は以上で終わりです。思ったよりも簡単です。

##ちょっとオシャレにする
デフォルトで使用してもいいのですが、少しオシャレにしようと思います。

`fisher`というプラグインをインストールします。

```terminal
curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
```
今回はbobthefishというテーマをfisherを使って適用してみます。

```terminal
fisher add oh-my-fish/theme-bobthefish
```
文字化けっぽくなっていると思うので、フォントのインストールも必要になります。

どこでもいいですが

```terminal
git clone https://github.com/powerline/fonts.git
```
fontsというディレクトリができるので

```terminal
cd fonts
./install.sh
```
ターミナルの環境設定からフォントをいじったり色を変えてみたりしましょう。
自分はフォントは`Meslo LG L DZ for powerline`みたいなやつを使っています。

##移行後
適当にコマンド打っています。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286470/f487d46b-3c2e-1936-6c06-2374ff2716bd.png)


なかなかオシャレになって満足してます。補完も効いて最高です。

##最後に
`zsh`とかも気になっているので比べたりしてみたいなあ。。。
当分はfishを使い続けるだろうと思っています。
(メモ) AWSのRHEL7.6でDocker CEを入れた。

### はじめに

これは、検証環境で一時的にDocker CEを使う必要があった際に対応した内容を、備忘録兼ねてメモしたものです。
ご自身の環境でDockerをインストールする場合は、ご自身の責任において情報を調査し対応を決める必要があります。（サポートが必要？Docker EEを導入する？導入方法は？等。）

### 状況
RHEL7.6で導入できるDockerのバージョンが古すぎる。デフォルトのyumだと入れられない。

```cmd:
$ sudo yum repolist all | greop etrasxtras
[2019-07-24 11:43:48.460] rhui-REGION-rhel-server-debug-extras/7Server/x86_64         Red  disabled
[2019-07-24 11:43:48.469] rhui-REGION-rhel-server-extras/7Server/x86_64               Red  enabled
[2019-07-24 11:43:48.469] rhui-REGION-rhel-server-source-extras/7Server/x86_64        Red  disabled
```
```cmd:
$ sudo yum info docker-ce
[2019-07-24 11:54:15.874] Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
[2019-07-24 11:54:16.229] Available Packages
[2019-07-24 11:54:16.229] Name        : docker
[2019-07-24 11:54:16.229] Arch        : x86_64
[2019-07-24 11:54:16.229] Epoch       : 2
[2019-07-24 11:54:16.229] Version     : 1.13.1
[2019-07-24 11:54:16.229] Release     : 96.gitb2f74b2.el7
[2019-07-24 11:54:16.229] Size        : 18 M
[2019-07-24 11:54:16.240] Repo        : rhui-REGION-rhel-server-extras/7Server/x86_64
[2019-07-24 11:54:16.240] Summary     : Automates deployment of containerized applications
[2019-07-24 11:54:16.240] URL         : https://github.com/docker/docker
[2019-07-24 11:54:16.240] License     : ASL 2.0
```

### インターネット接続できる場合

```cmd:
$ sudo yum-config-manager \
   --add-repo \
   https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce docker-ce-cli containerd.io
```

### インターネット接続ができない場合
#### rpmパッケージの入手
下記から入手。
https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

実際にダウンロードしたのは以下。
・containerd.io.x86_64 0:1.2.6-3.3.el7
・docker-ce.x86_64 3:18.09.7-3.el7
・docker-ce-cli.x86_64

#### extra repoの有効化、前提パッケージのインストール
コマンドだけ。。

```cmd:
$ sudo yum repolist all | grep extras
$ sudo yum-config-manager --enable rhui-REGION-rhel-server-extras
$ sudo yum repolist all | grep extras
$ sudo yum info container-selinux
$ sudo yum install container-selinux
$ sudo yum-config-manager --disable rhui-REGION-rhel-server-extras
```

#### docker インストール
書くまでもない。。

```cmd:
$ sudo yum install *.rpm
```
mavenって何だ？


こんにちは、ぽんぽこです。
アプリを自作しようと色々調べて「Maven」を使おう！と思い作業、、、
環境構築だけでめちゃめちゃ時間がかかったのでメモ。

不備等がございましたらご指摘お願い致します。

#Mavenを使っていく中で直面した問題点
- 環境構築にめちゃめちゃ時間が掛かった。
- Antでいろいろなタスクを使おうと思ったけど、面倒でやめてしまった。

主にこの２つでイライラしておりました。


#Mavenとは？

Mavenとは「専門家、達人」という意味です。

Javaのビルドツールの代表格「Apache Maven」の略です。
Mavenはオープンソースのビルドツールであり、多くのJava開発ツールで使われています。
特に複雑なプロジェクト構築でJavaフレームワークを使用すときなどに多く使用されていると思います。

Mavenは、Antの基本的な考え方を受け継ぎ開発されたビルドツールです。
違う点は、処理に必要な情報をXML形式で記述しソース、ライブラリ、プラグイン、プロキシを経由するのか？といった、プログラム全体を処理するための記述を行います。
ビルドするために処理の内容を細かく指定していく必要はありません。


#Mavenで出来ることって？


###Mavenの主な機能
- ビルドツールとして
    - 拡張タスクとして提供されていた様々な機能を、Mavenではプラグインという形で利用することができます。
    - プロパティファイルを設定するだけでよく、専用のXMLの記述は必要ありません。またプラグイン自体もコマンド１つでインストールすることができる。
    - プロパティファイルに設定したプロジェクト固有の値を動的にXMLに埋め込んでAntを実行させることで、利用者が余計なXMLを記述せずとも、拡張タスクの恩恵を受けることができるようになっています。




- プロジェクトサイトジェネレータとして
    - MavenはPOMに定義されている情報にアクセスして、HTMLとしてプロジェクトサイトを生成することができる。
    - Antで使用するようなXMLの記述なしに、プロパティファイルの設定だけで生成することができます。



- ライブラリ自動インストーラとして

    - MavenはPOMのdependenciesで定義している依存関係のあるartifactをリモートリポジトリより自動取得して、ローカルリポジトリにインストールする機能があります。
    - 自前のリポジトリを設定することで、同じ様に自動でインストールすることができる為、プロジェクト毎にライブラリを自前でインストールしたり、ライブラリ自体をCVSに格納せずともライブラリが利用できます。

今回は、Mavenとは何かについて記載させていただきました。

次回で、環境構築について説明していこうと思います。

では、次回。
Mavenの環境構築ってめんどくさい！！！

こんにちは、ぽんぽこです！

先日、Mavenについて軽くご説明させていただきました。
今回はmacへのMavenの環境構築について書かせていただきます。

不備等あればご指摘ください！

では、説明に入ります！！

#環境構築に必要なもの
・mac

・Eclipse

・JDK 1.8

・Apache Tomcat

#手順
###1.MacにMavenをインストールする
1-1. インストール可能なMavenを確認する
```brew search maven```

結果
```==> Formulae
maven                maven-completion                maven-shell
maven@3.2            maven@3.3                       maven@3.5
==> Casks
mavensmate           homebrew/cask-fonts/font-maven-pro```

1-2. 最新のMavenをインストールする
`brew install maven@3.5`

1-3. PATHに追加する(~/.bash_profileを編集して実行)
`~/.bash_profile
MAVEN_HOME=/usr/local/opt/maven@3.5
export PATH=$MAVEN_HOME/bin:$PATH`

```source ~/.bash_profile```

1-4. バージョン確認
```mvn --version```


結果
```Updating Homebrew...
(中略)
==> Downloading https://www.apache.org/dyn/closer.cgi?path=maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
==> Downloading from http://ftp.riken.jp/net/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃＃100.0%
==> Caveats
maven@3.5 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.
If you need to have maven@3.5 first in your PATH run:
  echo 'export PATH="/usr/local/opt/maven@3.5/bin:$PATH"' >> ~/.bash_profile
==> Summary
🍺  /usr/local/Cellar/maven@3.5/3.5.4: 104 files, 10.2MB, built in 9 seconds```



###2.EclipseにMavenを設定する
2-1. [環境設定] > [Maven] > [インストール] > [追加] で 
[新規 Maven ランタイム ] ダイアログを開く

2-2. インストール・ホーム : 1.の「$ mvn — version」で表示された「Maven home」のパスを設定する

2-3. インストール・ホーム: 手頃に分かる名前を設定する

2-4. [完了]ボタンを押下する

###3.Mavenのプロジェクトを作成する
3-1. [ パッケージ エクスプローラ] > [新規]] > [Maven プロジェクト] > [次へ]

3-2. [ デフォルト・ワークスペース・ロケーションを使用 ] にチェックを入れる、
[シンプルなプロジェクトの作成] にチェックを入れる > [次へ]

3-3. 下記を入力して[Finish]
GroupId : プロジェクトのルートパッケージ名
ArtifactId : プロジェクト名
Version : プロジェクトのバージョン (今回はデフォルトのまんま)


以上のように非常にシンプル！
GitHub Actions + Selenium でスクレイピングを定期実行

GitHub Actions と docker-selenium を使って定期的にスクレイピングを実行する方法を紹介します。

[サンプルリポジトリ](https://github.com/otuhs-r/home_observation) ― 日電のお客様ページから電力使用量をスクレイピングしています。

ここでは詳しく触れませんが、

- GAS で Nature Remo API を叩いて室温/湿度/照度を取得
- 電力使用量をスクレイピング
- Google Spread Sheet にそれぞれ記録
- Google Data Portal で可視化

して遊んでみました。

![スクリーンショット 2019-09-30 23.05.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222294/410e6f6a-715a-212a-686b-a78d3f14ba48.png)

# GitHub Actions

具体的には以下のような YAML ファイルを用意します。

```yaml:.github/workflows/actions.yml
on:
  schedule:
  - cron: 0 0 * * *
jobs:
  scraping:
    runs-on: ubuntu-latest
    services:
      selenium:
        image: selenium/standalone-chrome:3.141.59-vanadium
        ports:
          - 4444:4444
        volumes:
          - /dev/shm:/dev/shm
    steps:
    - uses: actions/checkout@v1
    - name: execute
      run: ...
```

## 説明

```yaml
- on:
  schedule:
  - cron: 0 0 * * *
```

`on` でワークフローを起動するイベントを指定します。定期実行させたいので、 `schedule` として cron 形式で起動時刻を指定します。タイムゾーンは UTC のようですので注意が必要です。

```yaml
runs-on: ubuntu-latest
```

`runs-on` でジョブを実行する仮想マシンの種類を指定します。 Docker コンテナを使用する場合は Linux でなければならないようです。

```yaml
services:
  selenium:
   image: selenium/standalone-chrome:3.141.59-vanadium
   ports:
     - 4444:4444
   volumes:
     - /dev/shm:/dev/shm
```

`services` でサービスをホストするコンテナを定義できます。ここでは、Selenium を実行するために `selenium/standalone-chrome` をサービスとして定義しています。

ポートとボリュームの設定は、`selenium/standalone-chrome` の [デフォルトの起動方法](https://github.com/SeleniumHQ/docker-selenium#running-the-images) をそのまま使用しています。

```yaml
steps:
  - uses: actions/checkout@v1
  - name: execute
    run: ...
```

`steps` に実際に実行したいスクリプトたちを定義していきます。 `uses: actions/checkout@v1` はパブリックなアクションで、ソースコードをワークフローにコピーしてきてくれます。

`run: ...` でスクレイピングするプログラムを起動します。 具体的には `run: ruby main.rb` など。

> このファイルを用意しておいてあげるだけであとは勝手に定期実行してくれるのですが、テストで実行する方法が見当たりませんでした。。仕方なく cron で直近の時刻を指定して動作確認しました。

## Badges

README に貼るバッジもあります。

```
[![Actions Status](https://github.com/{owner}/{repo}/workflows/{workflow_name}/badge.svg)](https://github.com/{owner}/{repo}/actions)
```

`workflow_name` はファイル名ではなく、ワークフローにつけた名前です。(上の説明では省略していますが、サンプルリポジトリにあるファイルでいうと 1 行目の `name: scraping electric power consumption` です。スペースは `%20` にする必要あり。)


# スクレイピングするプログラム

サービスとして立ち上げた `selenium/standalone-chrome` 上で Selenium を動かすので、 driver の生成方法がローカルで動かす場合と異なります。

具体的には( Ruby の場合) 以下のように `Selenium::WebDriver.for` の引数に `:remote` と `desired_capabilities: :chrome` を与える必要があります。

```ruby
driver = Selenium::WebDriver.for :remote, desired_capabilities: :chrome
```

# おわりに

自分で手を動かして触ってみたことで、「ぎっとはぶあくしょんず完全に理解した」状態になれました。

普段は GitLab CI を触っているので、明示的に checkout しなきゃいけないところとかはちょっと面倒くさく感じてしまいました。

GitHub Actions の今後に期待。

# 参考

- [GitHub Help](https://help.github.com/ja/articles/configuring-a-workflow)
Codebuildでs3のsyncコマンドを使うときの注意点

# ステータス失敗
CodeBuildでエラー
s3のsyncコマンドの戻り値が2！

```
[Container] 2019/09/24 08:16:28 Running command aws s3 sync public/ s3://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
warning: Skipping file 'layout - \xe3\x82\xb3\xe3\x83\x94\xe3\x83\xbc.css'. There was an error trying to decode the the file 'layout - 
・
・
・
[Container] 2019/09/24 08:16:29 Command did not exit successfully aws s3 sync public/ s3://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX exit status 2 
[Container] 2019/09/24 08:16:29 Phase complete: BUILD State: FAILED 
[Container] 2019/09/24 08:16:29 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: aws s3 sync public/ s3://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. Reason: exit status 2 
```

# 原因
ファイル名にバックアップで、日本語のファイル名があったことが原因
「layout.css」というファイルをコピーして一旦、「layout - コピー.css」というファイルが存在しました。
そのファイルを削除することでエラーが発生せずに正常終了しました。

# 終わりに
2バイト文字があるとs3のsyncコマンドの戻り値は0じゃなく2になるんですね。
こういうのはやってみないと分からないですね。
logrotate で起動しっぱなしのプロセスが吐くログをローテ―トできない

タイトルの通りの初歩的な備忘です。環境は CentOS 7 です。

起動し続けている python のプロセス `sample.py` が吐く `sample.log` について、下記のように設定してましたが、

```sh
/var/log/sample.log {
  daily
  notifempty
  missingok
  rotate 2
}
```

`sample.log` がローテ―トして `sample.log.1` が作られたものの、 `sample.py` は `sample.log.1` の方にログを吐き続けたのでした。
logrotate を使う場合、`postrotate` でプロセスを再起動させる必要があるようです。

ただ、python の場合は、 `TimedRotatingFileHandler` を使ってローテ―トさせることができたので、そちらを使うことにしました。

漠然と、logrotate 使えば何でもログローテーションしてくれるのでは？と思ってましたが、Rails にしろ python にしろ docker にしろ、独自にローテ―トする仕組みを持ってるのはそういうことなんですね。

以上です。
Windows上に設置したTomcatのリバースプロキシとしてNginxを使うには？

# 前提

Windowsテスト環境にて、TomcatとNginxを配置して開発環境を整えるためのメモです。
Linuxの人も読み替えで大体行けると思います。

# 構造

英語で表現すると「Tomcat and Nginx Reverse Proxy on Windows」という構造です。
Tomcat上にJavaのアプリケーションが、Nginx上にSSL証明書があります。
外部からアクセスされるときにはNginxがTomcatのプロキシとなり、HTTPSで受け付けます。
この時、TomcatはHTTPで動作しています。

# Tomcatを起動

Tomcatはデフォルトで8080ポートです。
http://localhost:8080/
localhost=127.0.0.1=0.0.0.0の対応関係については
「ローカルループバックアドレス」で検索してください。

※おそらく「なぜ8080なのか」が重要。
リバースプロキシを設置する前提が暗黙ルールになっていると推察できる。

# Nginxを配置

[公式](https://nginx.org/en/download.html)から`C:\nginx\nginx-x.xx.x\`にStable versionをダウンロードして配置します。

## Nginxのconfファイルを設定

`C:\nginx\nginx-x.xx.x\conf`にて、
念のため、`nginx.conf`を`nginx backup.conf`にコピーしてから編集します。

```nginx.conf
server {
  listen 80;
  server_name localhost;#domain.sample.com

  root /home/web/tomcat;

  access_log /var/log/nginx/tomcat_access.log;
  error_log /var/log/nginx/tomcat_error.log;

  location / {
    proxy_pass http://localhost:8080/;
  }

}
```

# NginxのPathを通す

`nginx.exe`のあるディレクトリをシステム環境変数のPATHへ追加して
コマンド`nginx`として使えるようにしておきましょう。

## Nginxを起動

cmdまたはpwshを起動して、以下を実行します。

```bash
start nginx
```

<http://127.0.0.1>にアクセスするとTomcatの画面が表示されます。
初回起動時にポップアップウィンドウが表示されますので、
ファイアウォールでHTTP=80ポートを開けるのを忘れないようにしましょう。
「なんで80なの？」って人は「ウェルノウンポート」で検索しましょう。
Windowsサービス化するには[ここ](https://github.com/kohsuke/winsw)を参照

# Nginxを終了

cmdまたはpwshを起動して、以下を実行します。

```bash
nginx -s stop
```

# 2023年7月追記

筆者としては現在のところ、Windowsで開発を行なう場合、dockerでTomcatとNginxを動かすことを推奨します。
また、本番環境ではLinuxで動かすことを推奨します。

**Excelsior!**
openam build


#JDKインストール

```
yum install -y java-1.8.0-openjdk.x86_64 java-1.8.0-openjdk-devel.x86_64
```

JAVA_HOME環境変数を登録する

```
vi /etc/profile.d/xxxx.sh
+ export JAVA_HOME=/usr/lib/jvm/java
```

#ミドルウェアインストール（git,npm,maven）

```
yum install -y epel-release
yum install -y git npm

curl -OL https://repos.fedorapeople.org/repos/dchen/apache-maven/epel-7/x86_64/apache-maven-3.5.2-1.el7.noarch.rpm
※RHEL7系の場合

rpm -ivh apache-maven-3.5.2-1.el7.noarch.rpm

```
vagrantでローカル開発環境を作る

# ローカル開発環境を作りたい

自社FWで開発環境はあるのだけども、将来に向けた開発環境を試す必要があるのでゼロから検証できる環境を作る
とりあえずteratermでログインするところまで。

## 前提

* VirtualBoxインストール済
* Vagrant インストール済

## Vagrant + VirtualBox

Docker使いたいけど、開発はVirtualBox。
Hyper-V関係の挙動で共存ができないので、Vagrant + VirtualBoxはそのまま使う


# とりあえずcentOS7環境を準備する

## vagrant初期設定
https://app.vagrantup.com/centos/boxes/7

## boxを作成する
### ディレクトリが無かったので作成
```
mkdir vagrant
cd vagrant
```
### initしたら怒られた
```
C:\Users\xxx\vagrant>vagrant init centos/7
==> vagrant: A new version of Vagrant is available: 2.2.5 (installed version: 2.2.4)!
==> vagrant: To upgrade visit: https://www.vagrantup.com/downloads.html

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
The machine index which stores all required information about
running Vagrant environments has become corrupt. This is usually
caused by external tampering of the Vagrant data folder.

Vagrant cannot manage any Vagrant environments if the index is
corrupt. Please attempt to manually correct it. If you are unable
to manually correct it, then remove the data file at the path below.
This will leave all existing Vagrant environments "orphaned" and
they'll have to be destroyed manually.

Path: C:/Users/xxx/.vagrant.d/data/machine-index/index
```
machine-indexが壊れてるから手動でナオシテ。的な。
対象ファイルをbkupして空にしてやりなおし

### vagrant upする
勝手にインストールしてくれる（便利）

```
C:\Users\xxxx\vagrant>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'centos/7' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'centos/7'
...
```

自動的にVirtualBoxに登録された
![20190930_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54063/831559eb-e104-ced6-c18f-2f73b8f72859.png)


## 登録状態を確認
vagrant box listで登録されたBOXを確認できる

```
C:\Users\xxxx\vagrant>vagrant box list
centos/7    (virtualbox, 1905.1)
localXXXX (virtualbox, 0)
localXXXX2 (virtualbox, 0)
```

## ssh接続してみる
```
C:\Users\xxxx\vagrant>vagrant ssh
Last login: Mon Sep 30 13:07:50 2019 from 10.0.2.2
[vagrant@localhost ~]$ cd /var/
[vagrant@localhost var]$ dir
adm  cache  db  empty  games  gopher  kerberos  lib  local  lock  log  mail  nis  opt  preserve  run  spool  tmp  yp
```

## teratermから接続できるようにしたい
### IPやマシン名を変える
/vagrant/Vagrantfileを編集する

```
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  #config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.network "private_network", ip: "192.168.33.11"
```

### centOS上でパスワード認証を許可する
```
[root@cent7 ~]# su - //passはvagrant
[root@cent7 ~]# vi /etc/ssh/sshd_config
```

#### sshd_config
```
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes
```

### teratermからログインしてみる
ID:root pass:vagrant

```
Last login: Mon Sep 30 13:35:22 2019
[root@cent7 ~]#
```

無事にログインできた。
Angular Materialの<mat-icon>で複数のアイコンを表示させたい。

Angularのmat-iconの使用方法については以下の記事で非常に詳しく解説されています。

[Angular Materialで<mat-iconを使う](https://qiita.com/blajir/items/9540556d7467044ef751)

この記事ではアイコンを複数使用する場合について紹介します。

該当のソースコード。

```:app.component.ts

private icons = {
    'home': 'assets/icons/home.svg',
  }

constructor(
    private domSanitizer: DomSanitizer,
    private matIconRegistry: MatIconRegistry,
  ) {

    Object.entries(this.icons).forEach( ([name, file]) => {

      this.addIcons(name, file);
    });
  }


  /**
   * icon と そのパスを登録する
   */
  private addIcons(name, file) {
    this.matIconRegistry.addSvgIcon(
      name,
      this.domSanitizer.bypassSecurityTrustResourceUrl(file),
    );
  }
```

iconsの中に登録するアイコン名と保存されているパスを対応させて登録しています。

あとはここに随時追加していくだけで使用できます。
Ubuntu 18.04 で日本語とvimを使う環境を整える

仮想環境でUbuntuを使おうとしたのですが、日本語化やvimのインストールで躓いたので、一連の流れを備忘録として整理しておきます。

使用したソフトウェア等はVirtual Box と Ubuntu18.04です。OSはMacを使用していますが、Mac特有の設定は無かったと思うので、Windowsでも普通に動作すると思います。

#1. Virtual BoxとUbuntu18.04の準備
Virtual Boxの公式サイトからOSに合わせてダウンロードします。
インストールは適当に進めておけば大丈夫です。
https://www.virtualbox.org/

Ubuntuの公式サイトから18.04.3 LTSをダウンロードします。
入手したisoファイルはわかりやすいフォルダに保存しておきます。
https://jp.ubuntu.com/download

#2. Virtual BoxでUbuntuの仮想サーバー作成
これもVirtual Boxの画面に出てくる選択肢を適当に選択していけば順調に進んでいきます。
言語は日本語を選択して、進めてください。
フォルダの名称やTerminalでの言語に悩んで英語にしたくなるかもしれませんが、あとで英語にする方法を紹介します。

詳細を知りたければ検索するか、次のサイトを参照したら大丈夫です。
https://www.sejuku.net/blog/82291#i

#3 ホストPCとUbuntuのクリップボードを共有
この手順を踏むことで、後々の環境設定が簡単になる（コピペできる）ので、サクッと設定しておきましょう。
次のサイトが非常にわかりやすいので、こちらを参照して進めてください。
https://onoredekaiketsu.com/copy-and-paste-with-virtualbox/

#4 キーボードで日本語と英語を切り替える設定
Macのキーボードにある「かな」や「英数」のボタンでは言語が切り替わらないので、「Control + Space」で切り替えられるように設定します。
次のサイトを参照して進めてください。
https://do-you-linux.com/blog/2018/05/03/ubuntu18-04-ltsで「日本語入力」する方法-日英キーボード対/

ただ、このサイトの記載内容だけでは、英語→日本語の切り替え(IMEの有効化)だけしかできないので、Mozcキー設定画面でIMEの無効化の所にも「Control + Soace」を追加してください。
これで双方向の切り替えができるようになります。

#5 システムの言語とフォルダの名称を英語化
こちらの設定をすることで、Terminalで処理したときに表示されるゲットの文言をGetに変えることができるので、普段使っているエラーの表示になります。日本語でのデバッグはちょっとやりにくかった（検索してもヒットしない...）。

Ubuntuの設定画面を開き、地域と言語のページにします。
そこで下記のように変更します。
LanguageをEnglish(United States)に、
FormatsをJapaneseに、
Input SourcesをJapanese (Mozc)だけにします。

もしシステム言語は日本語のままにして、フォルダの名称を英語にするだけで良いという時は、下記のサイトを参考にして設定してください。
https://qiita.com/taiko19xx/items/d1a001bfc25245b91354

#6 apt-getの環境を整理
Ubuntu18.04は特に設定を変更しない限りはTerminalで```$ apt-get update```を入力しても404 errorが返ってきてしまいます。参照しているリポジトリを変更する必要があります。
```/etc/apt/sources.list```を修正することで解決できます。

1. 保険のために安全な場所へ移動しておきます。
```$ sudo mv /etc/apt/sources.list ~/```
2. 新しくsources.listを作成します。
```$ sudo touch /etc/apt/sources.list```
3. Souftware Sourcesの画面を表示します。
```$ software-properties-gtk```
4. 表示された画面(Ubuntu Softwareのタブ)で次のように設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384346/9fa05bb0-310a-c3c7-ec7a-6a208423a3a3.png)
5. Updatesタブへ移動して、次のように設定します。Updateの自動確認等は好みで設定してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384346/580ca3bb-0f83-4c5a-b78b-8498b932f2f9.png)
6. おそらく正常に設定できているので、保険を削除しておきます。心配な人は残しておいてください。

```$ sudo rm ~/sources.list```

これで、apt-getが有効になります。
こちらのサイトを参考にして日本語の手順にしました。
https://askubuntu.com/questions/124017/how-do-i-restore-the-default-repositories

#7 vimのインストール
apt-getが使えるようになったので、アップデートしてvimをインストールします。
```$ sudo apt-get update```
```$ sudo apt-get upgrade```
```$ sudo apt-get install vim```
これでvimが使用できるようになりました。

#8 vimを使いやすく変更する
色をつけたり、インデントを調整したり、色々と設定することで便利になりますよね。
難しい設定は省いて簡単に設定しておきましょう。
こちらのサイトにしたがって、コピペしたらいい感じに仕上げてくれます。
https://qiita.com/iwaseasahi/items/0b2da68269397906c14c

これに加えて、括弧を自動で閉じるようにするために次のサイトのように編集するのもおすすめです。
https://qiita.com/shingargle/items/dd1b5510a0685837504a

#完了
上記の手順に従って、Ubuntuの仮想環境で、日本語と英語での入力が可能となり、綺麗なvimで文字入力ができるようになりました。
これで十分使いやすい環境になったのではないでしょうか。
もう仮想環境の構築で悩むことはない。
初めの一歩

**HTMLを学ぶ**

###とにかく実践
###分からないけどやってみる

まだこんだけ。

＜ｍｅｔａ　ｃｈａｒｓｅｔ＝”ｕｔｆ－８”＞ってなんでしょう？

適切なタグってなんですか？

3か月後には理解できてるといいな。

以上。
※接続中のSSDが急に「不正な取り出し」のアラートが出て、Finderのデバイス欄から消えてしまった！時に対処したこと

# Unityとかで重い処理とかしていたら、急に接続中のSSDが「不正な取り出し」となって、Finderのデバイス欄から消えてしまった時の対処法です。同じ現象で焦った方がおられましたらぜひお試しください。

![スクリーンショット 2019-09-30 18.14.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/140c8aad-ed03-4097-6297-4369e3c9eefb.png)

## 環境
PC: MacBook Air
SSD: My Passport Go 500GB

## 参考
[外付けHDDのアクセス権修復](https://discussionsjapan.apple.com/thread/110191072)
[【完全保存版】Macで外付けHDDが認識しない！復旧業者に出す前に確認すべきこと](https://secondnotes.net/hdd-check/)

---

:robot:以下詳細:robot:

### 現象について
・SSDを接続している状態で、UnityでOculusにビルドしていて、少し席を外して戻ってきたら、
右上に「不正な取り出し」とアラートが出ていて、Finderを確認したらデバイス欄からSSDが消えていた
→接触不良かと、SSDをいったん取り外し、再度接続したがFinderに出てこなかった
→右側のUSBポートがいけないのかと、左側のUSBポートに接続してみたが同じくFinderに出てこない
（もちろんデスクトップにも表示されてないです）

・そこで、[Finder]→[移動]→[ユーティリティ]で ディスクユーティリティ.app を起動したところ、　外部　の部分に、薄いグレーにはなっているけど、My Passport とSSDデバイスが一応表示されている
（ただし、マウントポイントの項目が「マウントされていません」と表示されていて情報が全体容量以外何も表示されない）
→認識はされているので、一応USBポートに問題があるわけではなさそうということがわかった

・Macをいったんシステム終了し、再度電源を入れて、SSDを接続したが、それでもFinderで認識できなかった

・[Finder]→[環境設定]で出てくるデバイス項目の 外部ディスク にチェックは入っている

・他のPCに接続してみたら、通常通り読み込まれてデータもちゃんとある

### 解決した方法

```
1. いったんSSDを外す
2. [Finder]→[環境設定]でデバイス項目の 外部ディスク に入っているチェックを外して、環境設定を閉じる
3. 再び[Finder]→[環境設定]を開き、デバイス項目の 外部ディスク にチェック入れ、環境設定を閉じる
4. SSDを再度接続する
```

![スクリーンショット 2019-09-30 21.21.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/526342c6-2d5e-60fb-f13e-a1bc95402941.png)

すでに入っているチェックをいったん外して、また入れ直しただけなのですが、なぜかFinderに表示されるようになりました:older_man_tone2:


---

:alien:振り返り:alien:

急にSSDが使えなくなってしまい、データが丸っと消えたりしてしまったのかとだいぶ焦りました。締め切りが近いものがあったので、修理とか出したりするの、時間もお金もだいぶかかっちゃう〜〜〜przと。でも、他のPCでは今まで通り使えたので、もしかしたらPC側の何かかな、とGoogle先生に聞いて頑張ってみました。無事治ってよかったです。

なぜ今回のことになってしまったのか、思いつく理由は、
・UnityでだいぶPCが暑くなっていた
・前日にWindowsに繋げて使っていた（デスクトップなので、ブラブラとSSDが宙づりになっていた）
です。

My Passport Go は軽くて、コスパも良くて耐久性もあるのですが、
USB接続コードが本体にくっついているタイプで１０cmもない感じの長さなので、
使用状況によっては宙ぶらりんになってしまい、接続コードを悪くしちゃったりするんじゃないかと心配になってしまうところだけが残園かな。。という感じですprz

今回の解決方法はたまたま治っただけなのかもしれないのですが、もし同じ状況で困った方がいたら参考になるかもと思い記事にしてみました。

以上！
[Rails]検索機能の実装

#はじめに
個人アプリの開発でこのような動画のタイトルで検索出来る機能を実装をしたのでその方法について説明します。
![23f2fb50ef8888f5d38b40a5b7d85a00](https://user-images.githubusercontent.com/52347821/65877265-2973de80-e3c6-11e9-82df-9487288eadec.gif)
###環境
Rails 5.2.3
Ruby  2.5.1
Bootstrap3使用

#導入方法

####モデル内
投稿用のモデルやコントローラーの作成などの説明は省略します。

始めに投稿用のモデルに以下の記述を追加します。
`self.search`でクラスメソッドを定義し、if文内では`Where LIKE`を使用し、あいまい検索をしています。
`where LIKE`分の中に検索したいカラム名(今回の場合は`name`)を記述します。

```ruby:video.rb
 def self.search(search)
    if search
       where(['name LIKE ?', "%#{search}%"])
    else
       all
    end
 end
```

####コントローラー内
次に投稿用のコントローラーに`search`メソッドを使用して、ビューに検索結果を表示させるように記述します。

```ruby:videos_controller.rb
 def index
    @videos = Video.order("created_at DESC").page(params[:page]).per(5).search(params[:search])
 end
```
####ビューファイル内

最後にビューファイルに検索フォームと検索ボタンを表示します。
`form_with`を使用して以下のように記述する事でビューに検索結果を表示させる事が出来るようになります。
注意点はsubmitの所の検索したいカラム名に`カラム名:nil`と記述するのを忘れないようにします。
ボタンは`Bootstrap3`を使用してます。
後はCSSを調整したら上手くいくかと思います。

```ruby:index.html.haml
.search
  = form_with url: videos_path, method: :get, local: true do |f|
    = f.text_field :search, class: "search-field", placeholder: "タイトルを入力して下さい。"
      = f.submit '検索', name: nil, class: "btn btn-default"
```

#最後に
簡単な検索機能だと`Gem ransack`など必要なく`search`メソッドを使用して実装出来ました。
複雑な検索機能に関しては以下が参考になるかと思います。
####参考資料
https://qiita.com/nishina555/items/2c1f8bae980e426519bc
【備忘録】Anacondaの仮想環境を削除しようとして、エラーが出た場合

# はじめに

conda remove --name 環境名 --allで、既存の環境を削除しようとしたら、以下のエラー発生。

````
$ conda remove --name 環境名 --all
・
・
・
Preparing transaction: done
Verifying transaction: done
Executing transaction: - WARNING conda.core.link:run_script(1098): pre-unlink script failed for package defaults::qt-5.9.5-h02808f3_0
consider notifying the package maintainer
failed
ERROR conda.core.link:_execute(568): An error occurred while uninstalling package 'defaults::qt-5.9.5-h02808f3_0'.
PermissionError(1, 'Operation not permitted')
Attempting to roll back.

Rolling back transaction: done

[Errno 1] Operation not permitted: '/Users/xxxx/anaconda3/envs/環境名/bin/qdbusviewer.app/Contents/PkgInfo' -> '/Users/xxxx/anaconda3/envs/環境名/bin/qdbusviewer.app/Contents/PkgInfo.c~
````

なぜか環境を削除できず・・・(なぜこのような状況になったのかは不明)
少しはまってしまったので、その時の対処法をメモとして残しておこうと思います。

# Anacondaの仮想環境があるフォルダに行って削除！

とりあえず、Anacondaの仮想環境があるディレクトリのbinまで行く

````
$ cd ~/anaconda3/envs/環境名/bin
````

そのディレクトリにて、.appを全て消してしまうコマンドを実行
　-r: ディレクトリ内を再帰的に削除する
　-f: 警告メッセージを表示しない

````
$ rm -rf *.app
````

ここまでで準備完了。
そのあと、先ほどのAnacondaの仮想環境を削除するコマンドを実行。

````
$ conda remove --name 環境名 --all
・
・
・
Proceed ([y]/n)? y

Preparing transaction: done
Verifying transaction: done
Executing transaction: - WARNING conda.core.link:run_script(1098): pre-unlink script failed for package defaults::qt-5.9.5-h02808f3_0
consider notifying the package maintainer
done
````

WARNINGが出ているけどちゃんと消えたっぽい・・・?
一応以下のコマンドで、環境があるかどうか確認してみます。

````
$ conda info -e
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
````
どうやら、すでにカレントディレクトリが存在しないため、コマンドが実行できない、というエラーのよう。

先ほど、~/anaconda3/envs/環境名/bin に移動して、Anacondaの仮想環境を削除してしまったため、
ここではcondaコマンドが使えなくなっているということだと思います。

ルートディレクトリに戻って、同じコマンドを実行すると、きちんと環境削除が完了したことの確認ができました。
conda remove --name 環境名 --all コマンドでなぜ環境が削除できなくなった不明ですが、
最終手段として試してもいいかもしれないです。
Java scriptでリストに格納されたJSONの更新



Java Scriptでリストに格納されたJSONの特定の項目を更新する方法。
例として、特定セクションのメンバーIDだけ変更する。

```js
var members = [
{"sectionCode":"section01", "memberId":"member01"}, 
{"sectionCode":"section02", "memberId":"member02"}
];

//sectionCodeが section02 の場合に memberIdを更新する
members.find(member => {
  if ( member.sectionCode ==  "section02"){
    member.memberId = "memberhoge"
  };
});

//JSONに変換してコンソール出力
console.log(JSON.stringify(members));
```

コンソール出力結果

```js
[{"sectionCode":"section01","memberId":"member01"},{"sectionCode":"section02","memberId":"memberhoge"}]
```

## 余談
### JSONに変換しない場合の出力結果
オブジェクト（連想配列）になっている。

```js

[ { sectionCode: 'section01', memberId: 'member01' },
  { sectionCode: 'section02', memberId: 'memberhoge' } ]
```

## 参考
[Array\.prototype\.find\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
[JSON\.stringify\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
Vue.js で email のドメインを補完するやつ

# つくりたいもの

- フォーム入力で、email の「@」以降の文字を打つと、ドメインがサジェストされる機能
- 以下の画像のようなイメージ

<img width="531" alt="スクリーンショット 2019-09-30 21.22.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45822/1cc8c758-14aa-ba68-235b-5316b3b164f2.png">

# ソースコード

- 以下のように `datalist` を使っています。
- option の `:value` にメソッドを渡しているのですが、これで動くということを初めて知りました。

```html:html
<input type="text" placeholder="hoge@example.com"
       list="suggestions" v-model="emailValue">
<datalist id="suggestions">
  <option v-for="domain in domains" :value="getSuggest(domain)"></option>
</datalist>
```

- 「@」が一つだけのときに、サジェストが発動するように `length === 1` をチェックしています。

```js:JavaScript
{
  data() {
    return {
      emailValue: '',
      domains: [ 
        "@gmail.com",
        "@yahoo.co.jp",
        "@au.com",
        "@yahoo.com"
      ]
    }
  },
  methods: {
    getSuggest: function (domain) {
      if ((this.emailValue.match(/@/g) || []).length === 1) {
        const emailUserName = this.emailValue.split('@')[0]
        return emailUserName + domain
      } else {
        return null
      }
    }
  }
}
```

以上です。 :lemon:
CloudWatch Logsの保持期間を自動設定するLambda(terraform構築)

CloudWatch Logsのログで保持期間設定を設定し忘れると、
少しずつログが溜まっていき、微小ながらコストが発生していきます。
ということで、保持期間の設定忘れがないように自動で設定をしましょう。

大体の料金は以下参照。（圧縮されたデータで 3,4円/GB）
[Amazon CloudWatch - 料金](https://aws.amazon.com/jp/cloudwatch/pricing/)
（一度ご利用している環境のLog一覧を見ることをオススメします。）

## 説明

タイトルにもある通り今回は、
CloudWatch Logsの保持期間を自動設定するLambda を作成しました。

注意点です。
※保持期間を設定しているLogは対象外です。設定漏れのみに保持期間を設定します。
※IAMを作成する必要があります。

ソースコードとLambda関数のテストコードはgithubで公開しています。

## 使用方法

githubよりcloneしてください。
https://github.com/Sunochi/set_cloudwatch_logs_expire

READMEにデプロイまでの詳細手順を載せてありますが、
以下にも日本語で手順を書きますので、参考にしてください。

### Terraformのインストール

hashicorp社が提供しているインフラストラクチャ定義ツールです。
[install guide](https://learn.hashicorp.com/terraform/getting-started/install.html)

バージョンは`0.12.5`以上でお願いします。
`0.11.x`以下ではおそらく動作しません。

### python(pip)の使用準備

pipを使用するため必要になります。
環境ごとにインストール方法が大きく異なるので、申し訳無いですが、割愛します。

### 環境変数の設定

Terraformを使う環境にて、下記の環境変数を設定してください。

```
TF_VAR_lambda_function_name: Lambdaの関数名
AWS_REGION: デプロイ先(`ap-northeast-1`など)
```

以下は1か2のどちらかのみ設定してください。

```
1.
AWS_SDK_LOAD_CONFIG: 1
AWS_PROFILE: ~/.aws/credentialsに設定しているprofile名

2.
export AWS_ACCESS_KEY_ID=<access key>
export AWS_SECRET_ACCESS_KEY=<secret access key>
```

設定例

```
$ export TF_VAR_lambda_function_name=set_cloudwatch_expire
$ export AWS_REGION=ap-northeast-1
$ export AWS_SDK_LOAD_CONFIG=1
$ export AWS_PROFILE=test_account
```

### デプロイ

デプロイはディレクトリごとになります。
順番がありますので、必ず守ってください

```
## IAM
$ cd IAM/
$ terraform init
$ terraform plan
$ terraform apply
## 表示内容に問題なければ　yes と入力

## Lambda.
$ cd Lambda/
$ ./lambda_build.sh
$ terraform init
$ terraform plan
$ terraform apply
## 表示内容に問題なければ　yes と入力
```

定期実行する場合は下記のCloudWatch Eventのルールもデプロイして下さい。
デフォルトの設定では毎月1日に実行されます。

```
$ cd CloudWatch/
$ terraform init
$ terraform plan
$ terraform apply
## 表示内容に問題なければ　yes と入力
```

## おわりに

最近はコストを削減するためにAWS環境の整備を行なっています。
今回は見落としがちなログの保持期間の自動設定を紹介しましたが、
まだまだコスト削減につながる自動設定はあります。

手軽に利用できる分、毎月コストが容易に発生するので、皆さんも簡単なところからコストを削減しましょう！
ONNXで fuse_consecutive_reduce_unsqueeze 最適化

ONNXがサポートしている最適化 fuse_consecutive_reduce_unsqueeze を調べてみました。

最適化をしているところはここ。
https://github.com/onnx/onnx/blob/master/onnx/optimizer/passes/fuse_consecutive_reduce_unsqueeze.h

```c++
bool patternMatchPredicate(Node* node) override {
    // check that the current node is of type Unsqueeze and has defined axes
    bool cur_node_check =
        node->kind() == kUnsqueeze && node->hasAttribute(kaxes);
    if (cur_node_check) {
      Node* prev_node = node->input()->node();
      // check that the previous node a reduction operator and has defined
      // axes/keepdims
      bool reduction_node_check = reduction_operators.find(prev_node->kind()) !=
              reduction_operators.end() &&
          prev_node->hasAttribute(kaxes) && prev_node->hasAttribute(kkeepdims);
      if (reduction_node_check) {
        // insure that keepdims is set to false currently
        return prev_node->i(kkeepdims) == 0 && node->is(kaxes) == prev_node->is(kaxes);
      }
    }
    return false;
  }
```

最適化できるかどうかの判断が ちょっと難しい

- Reduction -> Unsqueezeの並びであること
- ReductionのoperatorでaxisとkeepdimsのAttributeを持っている事
- Reductionのkeepdimsが0で、Reductionのaxisとsqueezeのaxesが同じこと

その条件を満たすグラフを作りました。

![fuse_consecutive_reduce_unsqueeze.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/16b241e3-28c2-d3a2-d208-3e16b6b8f1f2.png)


passにfuse_consecutive_reduce_unsqueezeを指定して、optimizer.optimizeを呼び出します。

```python
passes = ['fuse_consecutive_reduce_unsqueeze']

optimized_model = optimizer.optimize(model_def, passes)
```

最適化後のグラフ

![fuse_consecutive_reduce_unsqueeze_optimized.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/445e6ad0-1bfc-aa76-2793-6d9254e34297.png)


上手く消えてますね。

全ソース

```python
import onnx
from onnx import helper
from onnx import TensorProto
from onnx import optimizer

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 4])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 4])

reducemax = helper.make_node(
    'ReduceMax',
    keepdims = 0,
    axes = [1],
    inputs = ['X'],
    outputs = ['reducemax_out'],
)


unsqueeze = helper.make_node(
    'Unsqueeze',
    axes = [1],
    inputs = ['reducemax_out'],
    outputs = ['Y'],
)


graph_def = helper.make_graph(
    [reducemax, unsqueeze],
    'test-model',
    [X],
    [Y]
)

model_def = helper.make_model(
    graph_def,
    producer_name='onnx_example'
)

onnx.save(model_def, 'onnx/fuse_consecutive_reduce_unsqueeze.onnx')

onnx.checker.check_model(model_def)

# 最適化パスを指定
passes = ['fuse_consecutive_reduce_unsqueeze']

optimized_model = optimizer.optimize(model_def, passes)
onnx.save(optimized_model, 'onnx/fuse_consecutive_reduce_unsqueeze_optimized.onnx')

```
CAKEPHP3　遷移時のURLに意図しない「webroot」が付与されてしまう

cakephp3フレームワークを使ってウェブサービスを構築中です。

server requestによる遷移処理について原因がわからず困っています。

.htaccessなども怪しいと思ったんですが、これまで遷移できてたのが、できなくなっていたので、とても不思議に思っています。
以下のコントローラ側のリンクをトップページに設置しています。
app/naha
　　・
　　・
　　・
app/uruma

上記リンクの中で何故か、app/nahaの方だけ遷移できません。
serverRequestオブジェクト内のUrlには、「werbroot」が付与されています。
結果このようなエラーが出ます。
「The requested address 'app/webroot/naha/' was not found on this server.」

nahaControllerのindexアクションに遷移するはずなんですが…。

以下、「webroot」配下の「.htaccess」になります。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

以下「webroot」 配下のディレクトリになります。

 |-backup
 |-bin
 |-config
 | |-api_config
 | |-schema
 |-logs
 |-plugins
 |-src
 | |-Console
 | |-Controller
 | | |-areaController
 | | |-GinowanController
 | | |-IshigakijimaController
 | | |-MiyakojimaController
 | | |-NagoController
 | | |-NahaController
 | | |-NanjoController
 | | |-OkinawashiController
 | | |-TomigusukuController
 | | |-UrasoeController
 | | |-UrumaController
 | |-Util
 | |-View
 |-tests
 |-tmp
 | |-bake
 | |-cache
 |-vendor
 |-webroot
 | |-bk
 | |-cache
 | |-css
 | |-img
 | | |-cast
 | | |-ginowan
 | | |-miyako
 | | |-naha
 | | |-owner
 | | |-urasoe
 | |-js
 | |-lib
 | |-module
 | |-tmp

どうか、お助け願えないでしょうか。
よろしくお願いいたします。
GCEの仮想マシンにSSHコマンドで直接接続する

`gcloud`コマンドを使って仮想マシンに接続するには通常 `gcloud compute ssh`を用います：

```
gcloud compute ssh --project [PROJECT_ID] --zone [ZONE] [INSTANCE_NAME]
```

https://cloud.google.com/compute/docs/instances/connecting-to-instance?hl=ja

このコマンドは追加でSSHのオプションを後につけることが出来ます

```
gcloud compute ssh [USER@]INSTANCE
 [--command=COMMAND]
 [--container=CONTAINER]
 [--dry-run]
 [--force-key-file-overwrite]
 [--plain]
 [--ssh-flag=SSH_FLAG]
 [--ssh-key-file=SSH_KEY_FILE]
 [--strict-host-key-checking=STRICT_HOST_KEY_CHECKING]
 [--zone=ZONE]
 [--internal-ip     | --tunnel-through-iap]
 [--ssh-key-expiration=SSH_KEY_EXPIRATION     | --ssh-key-expire-after=SSH_KEY_EXPIRE_AFTER]
 [GCLOUD_WIDE_FLAG …]
 [-- SSH_ARGS …]
```

https://cloud.google.com/sdk/gcloud/reference/compute/ssh?hl=ja

これ使って例えば`8080`ポートを転送する場合は

```
gcloud compute ssh vm_name -- -L 8080:localhost:8080
```

のようにすることが出来ます。これでVM上でHTTPサーバー等を立ててもSSHトンネル経由で安全に見ることが出来ます。しかしこのオプションを毎回記述するのは面倒ですね。

そこで`gcloud compute config-ssh`というコマンドを使います。これは`gcloud compute ssh`で使っている設定を`.ssh/config`に書き出すコマンドです。


```:.ssh/config
# Google Compute Engine Section
#                                                                                                                                                   # The following has been auto-generated by "gcloud compute config-ssh"
# to make accessing your Google Compute Engine virtual machines easier.
#
# To remove this blob, run:
#
#   gcloud compute config-ssh --remove
#
# You can also manually remove this blob by deleting everything from
# here until the comment that contains the string "End of Google Compute
# Engine Section".
#
# You should not hand-edit this section, unless you are deleting it.
#
Host vm_name.region_name.project_name                                                                                                              HostName 12.34.56.78                                                                                                                              IdentityFile /home/myname/.ssh/google_compute_engine
    UserKnownHostsFile=/home/myname/.ssh/google_compute_known_hosts
    HostKeyAlias=compute.123456789
    IdentitiesOnly=yes
    CheckHostIP=no

# End of Google Compute Engine Section
```

こんな感じのが出力されます。これで

```
ssh vm_name.region_name.project_name
```

のように通常のSSHでアクセスすることが出来ます。この設定は（多分）VMの起動時に変化するのでこれを書き換えるのはダメで、追加で設定する場合は

```:.ssh/config
Host vm_name.region_name.project_name
  LocalForward 8080 localhost:8080
```

のように同じ名前でもう一つセクションを追記します。もちろんワイルドカード`*`を使う事も可能です。
ONNXで fuse_consecutive_log_softmax 最適化

ONNXがサポートしている最適化 fuse_consecutive_log_softmax を調べてみました。

最適化をしている箇所はここ。log -> softmaxではなく、softmax -> logの並びの時に最適化が有効。

https://github.com/onnx/onnx/blob/master/onnx/optimizer/passes/fuse_consecutive_log_softmax.h

最適化前のグラフ

![fuse_consecutive_log_softmax.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/6ea723a3-feb8-c32f-e860-d1d19798f49b.png)


passにfuse_consecutive_log_softmaxを指定して、optimizer.optimizeを呼び出します。

```python
passes = ['fuse_consecutive_log_softmax']

optimized_model = optimizer.optimize(model_def, passes)
```

最適化後のグラフ

![fuse_consecutive_log_softmax_optimized.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/f236c303-3f68-dbc8-23fe-c7b232de71ae.png)


上手くLogSoftmaxに置き換わっています。

全ソース。

```python

import onnx
from onnx import helper
from onnx import TensorProto
from onnx import optimizer

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 4])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 4])

softmax = helper.make_node(
    'Softmax',
    axis = 1,
    inputs = ['X'],
    outputs = ['softmax_out'],
)


log = helper.make_node(
    'Log',
    inputs = ['softmax_out'],
    outputs = ['Y'],
)


graph_def = helper.make_graph(
    [softmax, log],
    'test-model',
    [X],
    [Y]
)

model_def = helper.make_model(
    graph_def,
    producer_name='onnx_example'
)

onnx.save(model_def, 'onnx/fuse_consecutive_log_softmax.onnx')

onnx.checker.check_model(model_def)

# 最適化パスを指定
passes = ['fuse_consecutive_log_softmax']

optimized_model = optimizer.optimize(model_def, passes)
onnx.save(optimized_model, 'onnx/fuse_consecutive_log_softmax_optimized.onnx')

```
Azure Speech to Text REST API をやーる（Python 3.6.9）

AzureのCognitiveServicesを用いて、音声からテキスト変換をやってみました。

# はじめに
Azure Portalにログインして、リソースの作成から「音声」を検索し作成してください。
subscription keyを用いるのでコピペしてください。

# サンプルコード

STTのエンドポイントは[こちら](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/rest-speech-to-text#regions-and-endpoints)にあるので作成したリソースと同じリージョンのエンドポイントを選んでください。

音声ファイル（konnichiwa.wav）は[こちら](https://github.com/SatoshiRobatoFujimoto/AzureCognitiveServices/blob/master/konnichiwa.wav)からダウンロードしてください。

~~~python
import requests

endpoint = "https://westus.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=ja-JP&format=detailed"
headers = {
    "Content-Type" : "audio/wav",
    "Ocp-Apim-Subscription-Key": "<your subscription key>",
}
response = requests.post(endpoint, headers=headers, data=open("konnichiwa.wav", "rb"))
print(response.text)
~~~

# 結果
下記のように表示されれば成功です。

~~~
(py36) D:\User\s-fujimoto\sts>python stt.py
{"RecognitionStatus":"Success","Offset":1400000,"Duration":48400000,"NBest":[{"Confidence":1.0,"Lexical":"/こんにちは/こんにちは/コンニチハ","ITN":"こんにちは","MaskedITN":"こんにちは","Display":"こんにちは。"}]}
~~~

#参考文献 

[Speech to Text REST API](https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/rest-speech-to-text)
ONNXで fuse_consecutive_concats 最適化

ONNXがサポートしている最適化 fuse_consecutive_concats を調べてみました。

連続するconcatを一つにまとめてくれます。

最適化前のグラフ

![fuse_consecutive_concats.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/80055735-d13c-d22a-a44c-6d459e8c750f.png)

passにfuse_consecutive_concatsを指定して、optimizer.optimizeを呼び出します。

```python
passes = ['fuse_consecutive_concats']

optimized_model = optimizer.optimize(model_def, passes)
```

最適化後のグラフ

![fuse_consecutive_concats_optimized.onnx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327/6c4d7020-60d8-614f-1e9f-0b7d7b5a7239.png)


上手く行ってますね。

全ソース

```python


import onnx
from onnx import helper
from onnx import TensorProto
from onnx import optimizer

X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 2])
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 6])


dropout0 = helper.make_node(
    'Dropout',
    inputs = ['X'],
    outputs = ['dropout0_out'],
)

dropout1 = helper.make_node(
    'Dropout',
    inputs = ['X'],
    outputs = ['dropout1_out'],
)

dropout2 = helper.make_node(
    'Dropout',
    inputs = ['X'],
    outputs = ['dropout2_out'],
)

concat0 = helper.make_node(
    'Concat',
    axis = -1,
    inputs = ['dropout0_out', 'dropout1_out'],
    outputs = ['concat0_out']
)

concat1 = helper.make_node(
    'Concat',
    axis = -1,
    inputs = ['concat0_out', 'dropout2_out'],
    outputs = ['Y']
)


graph_def = helper.make_graph(
    [dropout0, dropout1, dropout2, concat0, concat1],
    'test-model',
    [X],
    [Y]
)

model_def = helper.make_model(
    graph_def,
    producer_name='onnx_example'
)

onnx.save(model_def, 'onnx/fuse_consecutive_concats.onnx')

onnx.checker.check_model(model_def)

# 最適化パスを指定
passes = ['fuse_consecutive_concats']

optimized_model = optimizer.optimize(model_def, passes)
onnx.save(optimized_model, 'onnx/fuse_consecutive_concats_optimized.onnx')

```
Kotlinで自作のクラスでもfor in ループを回したい

自作で作成したクラスでもfor in でループを回したいときがあると思うので、その方法を調べてみました！


公式ドキュメントより引用
https://kotlinlang.org/docs/reference/control-flow.html#for-loops


> メンバ関数もしくは拡張関数である itrator() を持っていること。 そしてそれが返す型が
> メンバ関数もしくは拡張関数である next() を持っており、
> メンバ関数もしくは拡張関数であり、Boolean を返す hasNext() を持っていること。
> 
> それら3つの関数全てが operator としてマークされていること。

@sdkei さんのコメントを引用


要するに３つのメンバ、関数を実装すればいいってことですね。


繰り返されるクラスに直接Iterableを実装(従来のJavaとほぼ同じ)

```kotlin
class Hoges : Iterable<String> {
    override fun iterator(): Iterator<String> {
        return object : Iterator<String> {
            override fun hasNext(): Boolean {
                return true
            }

            override fun next(): String {
                return "hoge"
            }
        }
    }
}
```

Iteratorインスタンスを返す拡張関数を定義

```kotlin
class Hoges {
}

operator fun Hoges.iterator(): Iterator<String> {
    return object : Iterator<String> {
        override fun hasNext(): Boolean {
            return true
        }

        override fun next(): String {
            return "hoge"
        }
    }
}
```


hasNext、nextをプロパティとして定義

```kotlin
class Hoges {
}

operator fun Hoges.iterator() = this

operator fun Hoges.hasNext(): Boolean {
    return true
}

operator fun Hoges.next(): String {
    return "hoge"
}
```

メンバとして定義するのでも良いと公式ドキュメントに記載があったもののそれはどうやればいいのかわかりませんでした。。。

従来のJavaのようにIterableを実装するだけでなく、拡張関数としても定義しても良いというのがKotlinらしいですし、
拡張関数ならばライブラリとして提供されていて自分でIterableを実装できないクラスでもfor inに対応できます！

ですが、従来式のIteratorを実装するほうがIntelljIDEAのサジェストで何を実装すればいいのかわかりやすいため個人的にはそちらの方がおすすめです。


参考
https://kotlinlang.org/docs/reference/control-flow.html#for-loops
Unity2018で、Standard AssetsのBloom.csやBloomAndFlares等でビルドエラーなる場合

Unity2017で動いてプロジェクトを2018に移行したところ、
Androidのビルド時に下記エラーに遭遇。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37406/427de0e1-08cd-725b-d785-0180244dc56a.png)

```
Assets/Editor/ImageEffects/BloomAndFlaresEditor.cs(80,64): error CS1061: Type `Camera' does not contain a definition for `hdr' and no extension method `hdr' of type `Camera' could be found (are you missing a using directive or an assembly reference?)
```

Cameraの```hdr```プロパティがおかしいらしい。

対象のソースの

```csharp:BloomAndFlares.cs

            // screen blend is not supported when HDR is enabled (will cap values)

            doHdr = false;
            if (hdr == HDRBloomMode.Auto)
                // doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().hdr;
                doHdr = source.format == RenderTextureFormat.ARGBHalf && GetComponent<Camera>().allowHDR;
            else
            {
                doHdr = hdr == HDRBloomMode.On;
            }
```

```GetComponent<Camera>().hdr``` → ```GetComponent<Camera>().allowHDR```
に変えたら無事ビルドできました。。

他の```Bloom.cs```や、```SunShafts.cs```等も同様に変更してなんとか移行完了。


> 参考にさせて頂いたサイト
https://forum.unity.com/threads/imageeffects-error-hdr.312009/?_ga=2.39111978.860709088.1569829102-810443181.1569281518
gpsの研究　その55

#概要

gpsを理解したかった。
2行軌道要素を調査してみた。

#例


```
1 37158U 10045A  11015.18584668 -.00000050  00000-0  10000-3 0   607
2 37158 040.9221 193.2641 0749201 270.0188 212.6145 01.00271298  1281
```

#書式

```
1 a2 a3 a4 a5 a6 a7 a8 a9
2 b2 b3 b4 b5 b6 b7 b8 b9
```

#a2

衛星カタログ番号（Satellite number）
37158
軍事機密種別（Classification）
U

#a3

国際識別符号（International Designator）
10045A

#a4

元期（Epoch）
11015.18584668
基準となる日付「2011年15.18584668日目」

#a5

平均運動の1次/2次微分値 （First/ Second Time Derivative of the Mean Motion）
-.00000050

#a6

平均運動の1次/2次微分値 （First/ Second Time Derivative of the Mean Motion）
00000-0

#a7

B STAR（B*）抗力項（BSTAR drag term）
10000-3

#a8

軌道モデル（Ephemeris Type)
0

#a9

通番（Element set number）
60
チェックサム（Checksum）
7

#b2

軌道傾斜角(Inclination)
37158 

#b3

衛星カタログ番号（Satellite number）
040.9221 

#b4

昇交点赤径 (Right Ascension of Ascending Node)
193.2641

#b5

離心率（Eccentricity）
0749201 

#b6

近地点離角（Argument of Perigee）
270.0188 


#b7

平均近点角（Mean Anomaly）
212.6145 

#b8

平均運動（Mean Motion）
01.00271298
衛星が1日に軌道を何周するか

#b9

通算周回数（Revolution number at epoch）
128
チェックサム（Checksum）
1

#写真
![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/i/9/c/i9cs.jpg?t=1490085129)



以上。
laravelで自作ライブラリをgithubからインストールする

# composer.json編集
インストールする側のcomposer.jsonを編集します。

```
"require": {
     "php": "^7.1.3",
     "hoge/test": "dev-master"
 },
"repositories": [
  {
    "type": "vcs",
    "url": "https://github.com/hoge/test.git"
  }
],
```

# composer update実行
composer update hoge/test.git
をすると、githubのaccesstokenエラーが最初に出ると思うので、以下記事を参考にして設定してみてください。
https://qiita.com/ma_me/items/7d1823c27d6ef45cdf9f

他にも自分は以下エラーが出たのですが、ライブラリ側のcompser.jsonのnameが設定されていないことが原因でした。

```
Problem 1
    - The requested package hoge/test could not be found in any version, there may be a typo in the package name.
```

```
"name": "hoge/test",
```
nameを設定してあげたら上手く行きました。
Python: WebCrawling

## SAMPLE
https://qiita.com/kinoshita_yuri

F12 デベロッパーツール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51324/517dfa80-38e2-5196-f8c8-f70fc21c764e.png)

この画面から、
・ユーザー名
・記事タイトル（複数）
・記事タイトル（文字列"T-SQL"がタイトルに含まれているもののみ）
・利用規約（Terms）のリンク先URL
・Itemsの数
をそれぞれ取得する。

取得したいノードを
右クリック=>Copy=>CopyElement
でxpathをコピーできる。ただしその際は複雑なことはできない。

## REFERENCE
[クローラ作成に必須！XPATHの記法まとめ](https://qiita.com/rllllho/items/cb1187cec0fb17fc650a)

## PYTHON
```python
import requests
import lxml.html

url = 'https://qiita.com/kinoshita_yuri'

response_page = requests.get(url)
html_page = lxml.html.fromstring(response_page.content)

## user name
xpath_name = 'string(//*[@class="col-md-3 col-sm-3 col-xs-12 newUserPageProfile"]/div[@class="newUserPageProfile_header"]/h3/span)'
html_name = html_page.xpath(xpath_name)

## article title
xpath_title = '//*[@id="main"]/div/div/div[@class="col-md-9 col-sm-9 col-xs-12"]/div[@class="tableList"]/article[position()]/div/div[@class="ItemLink__title"]/a/text()'
html_title = html_page.xpath(xpath_title)

## article title (only T-SQL)
xpath_title = '//*[@id="main"]/div/div/div[@class="col-md-9 col-sm-9 col-xs-12"]/div[@class="tableList"]/article[position()]/div/div[@class="ItemLink__title"]/a[contains(text(),"T-SQL")]/text()'
html_title = html_page.xpath(xpath_title)

## terms link（文字列"Terms"を検索した後、親ノードのhrefを取得する）
xpath_terms = '//*[@class="footer_container"]/ul[@class="footer_links-left"]/li/a/text()[.="Terms"]/parent::node()/@href'
html_terms = html_page.xpath(xpath_terms)

## Items（文字列"Itemsを検索した後、親ノードの兄ノードに含まれるTextを取得"）
xpath_area = '//*[@id="main"]/div/div/div[2]/div[1]/div[2]/a[@class="col-xs-4 userActivityChart_stat active"]/span[@class="userActivityChart_statUnit"]/text()[.="Items"]/parent::node()/preceding-sibling::span/text()'
html_area = html_page.xpath(xpath_area)
```

## 各ノードとツリー上の位置関係
|名前|説明|
|---|---|
|self|ノード自身を表す|
|child|ノードの子ノードの集合|
|parent|ノードの親ノードの集合|
|ancestor|ノードから祖先ノードの集合(親も含む)|
|descendant|ノードから子孫ノード集合|
|following|ノードの後に出てくるノードの集合|
|preceding|ノードの前に出てくるノードの集合|
|following-sibling|ノードと同じ階層にあり、かつ後に出てくる兄弟ノードの集合|
|preceding-sibling|ノードと同じ階層にあり、かつ前に出てくる兄弟ノードの集合|