OmniAICreator/Qiita-1.07M huggingface dataset:
DV証明書/OV証明書/EV証明書の確認方法

#1. はじめに

違いについては以下のサイトがよくまとまっています。That's allと言いたいところですが、簡単にこの記事で確認方法についてまとめてみたいと思います。
https://www.geotrust.co.jp/ssl_guideline/compare/ovdv.html

#2. ドメイン認証証明書(DV証明書）

- DV=Domain Validation
- 個人でも簡単に取得できてしまう。
- ドメイン名を所有していれば、機械的な発行処理によって、誰でもSSLサーバ証明書の取得が可能であるため、基本的に暗号化通信のみが必要とされるウェブサイトに使うべき。逆に、DV証明書が使われているということは、暗号化通信のみが保証されていると考え、その実在性については（非常に著名なサイトや既知のサイトを除き）まずはいったん疑ってかかるべき。こういうサイトでクレジットカードとか機密情報は原則利用するべきではない。
- 以下は[qiita](https://qiita.com/)のサイトでのFirefoxでの表示例。見た目だけでは、OV証明書と区別がつかない。<br><img width="191" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/d9fc9f2f-6bd5-f748-0cca-0e01fd8807b8.png">
- 組織情報や部門情報がなく、CNしか表示されていない（こうした情報があるなら、OV証明書のはず）。<br> <img width="614" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/937f62be-e051-d4a7-5e61-77a73d0ebc0e.png">
- Subject FieldにCN(Common Name)情報しかない。<img width="617" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/5ace4f9e-358d-2596-44be-9d1376c0cbbd.png">
- SAN (Subject Alternative Name) 拡張領域。<br><img width="616" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/004b108b-196a-3e8c-13fa-1e04487733c3.png">


#3. 企業認証証明書(OV証明書）

- OV=Organization Validation
- 証明書発行時に企業・組織の実在性が何らかの形で確認されている。よって、DV証明書と違って、実在性に関する信頼性がある。
- 以下は[Yahoo! Japan](https://www.yahoo.co.jp/)のサイトでのFirefoxでの表示例。見た目だけでは、DV証明書と区別がつかない。<br><img width="226" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ae4bd4b8-d30f-42b5-fc8f-62c01c4ec120.png">
- 組織情報/部門情報が表記されている（どちらかしか表記がない場合もある）<br><img width="615" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/5cbc7eef-abe0-a562-01cd-4dec8373aa87.png">
- Subject FieldにCN(Common Name)以外のWebサイトの運営者に関する情報がある。
<br><img width="617" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/a316d239-95bb-e367-8a7a-72e48d3c30ae.png">
- SAN (Subject Alternative Name) 拡張領域。<br><img width="616" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9353c682-c23b-ef6b-d87f-8a2ee630fad0.png">

#4.EV証明書

- EV=Extended Validation
- ワイルドカードは使えない
- 以下は冒頭で紹介した[GeoTrustの紹介ページ](https://www.geotrust.co.jp/ssl_guideline/compare/ovdv.html)。緑のアドレスバーにサイト運営会社名を表示されている。ここが決定的にDV証明書やOV証明書とは異なるところ。<br><img width="557" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/1fde2141-df61-255a-a0ab-452a5960a392.png">
- 組織情報/部門情報が表記されている。<img width="615" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/797108ad-795e-38f2-000d-23c6ea9f544a.png">
- Subject FieldにCN以外の情報がある。<img width="616" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/43dbc73b-24b6-928a-9caa-b7409a8d4947.png">
- SAN (Subject Alternative Name) 拡張領域。<br><img width="618" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e73fb8cf-8717-8ddf-30bb-1e21eb7c1556.png">
Vaporのboot.swiftって何書くの

#Application boot

[Docs](https://docs.vapor.codes/3.0/getting-started/application/)のApplicationの説明にboot.swiftは「アプリケーションにアクセスする最適な場所」と書いてありますが、「your code here」の部分には何を書くのでしょう？

```swift
import Vapor

public func boot(_ app: Application) throws {
    // your code here
}
```

#考察
まったくわかりませんので、Web検索してみました。

###検索結果１.「未処理のオーダーをループしてすべて処理する」
オーダーを処理するシステムで、起動時に溜まっているオーダーを処理してから始めるのに、ここで処理するらしい。

```
app.make(_:)
```

※「_:」は外部名なしで1つのパラメーターを取るということらしい。

###検索結果２．「リピートのタイマーを起動する」
常に起動しているタイマーをここで起動している。

```
app.eventLoop.scheduleTask
```

###検索結果３．「外部のAPIへPOSTする」
外部へ何かを通知している。

```
app.client()
```

###注意
Vaporはアプリケーションへの静的アクセスをサポートしない。

#結論
bootは、アプリケーションを起動するたびに実行するコードを書くところということで、サーバーの状態を確認するコードを追加するのが良さそう。
あまり思い浮かびませんが、以下のような事を実装するかなと思います。

- サーバーのバージョン確認
    - 新しいバージョンがリリースされているかを確認して通知する
- ライセンス確認
    - サーバーがライセンス下で動作している場合にライセンスの状態を確認する
- サーバーの状態確認
    - 前回終了時の内容
    - DBなどの外部データへの接続可否

以上
lolcatのオプションまとめ

- [何がしたいのか](#何がしたいのか)
- [インストール](#インストール)
- [基本文法](#基本文法)
- [バージョン, ヘルプ表示](#バージョン-ヘルプ表示)
  - -v, -h 
- [行番号, 出力](#行番号-出力)
  - -f, -n(<Ver. 99.9.9), -t
- [色の調整](#色の調整)
  - -p, -F, -S, -i
- [アニメーション](#アニメーション)
  - -a, -d, -s 
- [まとめ](#まとめ)

# 何がしたいのか
- 文字を虹色に着色するFunnyなRuby製CLIツール[busyloop/lolcat](https://github.com/busyloop/lolcat)
- オプションを毎回調べるのがめんどくさいのでまとめておく

# インストール
```bash:Terminal
$ gem install lolcat
# or...
$ brew install lolcat
```

# 基本文法
  - `lolcat [オプション]... [ファイル]...`
  -  `cat <ファイル> | lolcat ...`

![normal](https://i.imgur.com/TbiAVoM.png)

# バージョン, ヘルプ表示
## `-v, --version`
- バージョンを表示して終了

![-v](https://i.imgur.com/lWk0Qc0.png)
## `-h, --help`
- ヘルプを表示

![-h](https://i.imgur.com/liK04bn.png)

# 行番号, 出力
## `-f, --force`
- 標準出力(stdout)の先が制御端末(tty)ではない場合でも色を強制する
- 要はパイプで繋いだ先にも色付き出力を渡す
- 個人的に一番良く使う

![-f](https://i.imgur.com/Ho9M9c2.png)
## `-n, --number`
- 行番号を表示
- Ver. 99.9.9以上で[削除されており、](https://github.com/busyloop/lolcat/commit/2074d47238520f44931bd0204947f6acdc489f7a)理由は「バッファリングを考慮していなかったので、4kb入力すると壊れてしまうから」[らしい](https://github.com/busyloop/lolcat/issues/77)

![-n](https://i.imgur.com/qaqqePc.png)

## `-t, --truecolor`
- 24-bit([truecolor](https://www.weblio.jp/content/TrueColor))の色コードを用いる

# 色の調整
## `-p, --spread=<float>`
- 虹の速度 (def: `3.0`)
- 色が変わる時の隣との色幅を指定する

![-p](https://i.imgur.com/kb2X9Mx.png)
## `-F, --freq=<float>`
- 虹の周期 (def: `0.1`)
- 次の色に遷移する文字幅を指定する
- 値を増やすと彩度が増す

![-F](https://i.imgur.com/SmoFPZV.png)
## `-S, --seed=<int>`
- 虹色を生成する時のシード (def: `0`)
- `0`を指定するとランダムシードになる

## `-i, --invert`
- 前景/背景の色を反転

![-i](https://i.imgur.com/p5KHQ4d.png)

# アニメーション
## `-a, --animate`
- 「**サイケ(psychedelics)**」モード
- アニメーションしながら出力をする

![-a](https://i.imgur.com/C7txSyp.gif)
## `-d, --duration=<int>`
- 遷移までの時間 (def: `12`)

![-d](https://i.imgur.com/3iyPVwV.gif)
## `-s, --speed=<float>`
- `-a`で次の色に遷移する速度 (def: `20.0`)

![-s](https://i.imgur.com/ATC3WaO.gif)

# まとめ
たのしいね
BMIが計算したい！！

```js
let w =document.querySelector(".weight");
let h =document.querySelector(".height");
w = parseFloat(w);
h = parseFloat(h);
let result=document.querySelector(".result");
let btn =document.querySelector(".btn");
btn.addEventListener("click", function() {
	let r =w/(h*h);
	result.innerText = r;
});
```
@importと、requireって何が違うの？

# @impirtとは
@importはscssが用意しているメソッドです。そのため、application.scssと拡張子を変更しないと使えません。また、application.scssからscssファイルをインポートするために使用しなけばなりません。

scssはscss専用のメソッドなので、requireとは異なります。


# reqireとは

requireはRailsのアセットパイプラインの仕組みを使ってファイルをインポートすることを指します。

## アセットパイプラインとは

アセットパイプラインとは、JavaScriptやCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するためのフレームワークです。アセットパイプラインでは、CoffeeScriptやSass、ERBなど他の言語で記述されたアセットを作成する機能を追加することもできます。 アセットパイプラインはアプリケーションのアセットを自動的に他のgemのアセットと結合できます。たとえば、jquery-railsにはRailsでAJAXを使えるようにするjquery.jsが含まれています。

アセットパイプラインはsprockets-rails gemによって実装され、デフォルトで有効になっています。アプリケーションの新規作成中にアセットパイプラインを無効にするには、--skip-sprocketsオプションを渡します。
引用　- rails ガイド

つまりは、cssファイルやJavaScriptのファイルを１つにまとめ、圧縮することで処理速度を早くするための仕組み。sprocketsというgemがこの機能を担ってるってことです。


# 両者の違い

こう書いてみると、@importもrequireも何かをひっぱてきているような感覚は同じですが、importはscssの専用メソッドで、ファイルを読み込む記述、対してrequireは、cssやjsのファイルを1つにまとめて圧縮したファイルを読み込んでいるという違いがあることが分かりました。
Azure WebAppsでリモートIPはどうやってとれるか

# はじめに

Azure WebApps for containerにSpringBootで作ったWebアプリをデプロイしているのですが、一部のパスにIP制限をかける必要があり、色々試した結果わかりました。
今回試したのは、WebAppsに直接リクエストを投げた場合なので前面にApplicationGatewayなど別物が挟まると変わる可能性があります。

# 結論

リクエストのx-client-ipの中に入っています。

# 補足

x-forwarded-forにもリモートIPが入っていますが、WebAppsに直接リクエストを投げた時はポート番号も含まれた状態になっていました。
そのため、TomcatのRemoteIpValveをデフォルトの状態で動かすと、パースができずIllegalArgumentExceptionで落ちます。
migrationファイルのnull: falseって？

#migrationファイルのnull: falseって？

###→指定したカラムが（データベースに）カラの状態で保存されることを防ぐ

```ruby:rb
class CreateNotifications < ActiveRecord::Migration[5.2]
  def change
    create_table :notifications do |t|
      t.integer :visitor_id, null: false
      t.integer :visited_id, null: false
      t.string :action, default: '', null: false
      t.boolean :checked, default: false, null: false
      t.timestamps
    end
    add_index :notifications, :visitor_id
    add_index :notifications, :visited_id
  end
end
```

#モデルに記載するvalidates :content, presence: trueと何が違うの？
似たバリデーションとして、presence: trueがあります。
これは、
#####Railsの方でカラの情報を保存させないようにするためのものです。
データベース側ではSQLで保存することができてしまうのですね。

#どちらを記載すれば良いのか？
どちらも記載しておくと安全ですね。
migrationファイルでは、データベースに対する設定なのに対して、
modelファイルでは、Rails側の設定。
結論：目的の場所が異なるので両方設定しておくことが良いですね。
【Nuxt.js】vuetifyのスクロールイベントでトップへ戻るボタンを作る

vuetifyにはデフォルトでスクロールイベントを起こす機能があり、その機能を組み合わせることによりトップへ戻るボタンを作ることができます。

vue.jsでは「vue-go-top」というページ戻り専用のライブラリーはありますが、今回はvuetifyのみを利用して作成します。

# クリックしたらTopに戻る
vuetifyには`$vuetify.goTo()`と指定するだけでスクロールイベントを起こすことができます。
[スクローリングディレクティブ]
(https://vuetifyjs.com/ja/directives/scrolling/)

```vue
<v-btn @click="$vuetify.goTo(target, options)"></v-btn>
```

こちらに０をいれると、クリックしたときに一番上まで戻ります。

```vue
<v-btn @click="$vuetify.goTo(0)"></v-btn>
```

## scriptに記入する
`$vuetify.goTo(0)`を下記のようにscriptに記入することでtemplate側をすっきりできます。

```vue
<v-btn @click="toTop"></v-btn>
```

```javascript
methods: {
  toTop () {
    this.$vuetify.goTo(0)
  }
}
```

# スクロールしたら表示される
こちらはv-scrollを使用します。

## スクロールで呼び出す関数をセットします。

```vue
<v-btn
  v-scroll="onScroll"
  @click="$vuetify.goTo(0)">
</v-btn>
```

※デフォルトはウィンドウですが、スクロールの変更を監視するターゲットは任意のIDセレクターに変更できます。

## methodsに記入していく
onScroll関数に記入。
`typeof window === 'undefined'`はターゲットのデフォルトがwindowの場合使用。
`window.pageYOffset`で垂直スクロール量を取得`target.scrollTop`も同様です。

```javascript
methods: {
  onScroll (e){
    if (typeof window === 'undefined') return
    const top = window.pageYOffset ||   e.target.scrollTop || 0
  }
}
```

## 表示・非表示の設定

v-showで表示・非表示を切り替えます。
さきほどのスクロール値を取得してfabに格納。指定の値にきたら表示するようにします。

```vue
<v-btn
  v-scroll="onScroll"
  v-show="fab"
  @click="$vuetify.goTo(0)">
</v-btn>
```

```javascript
data: () => {
  return {
    fab: false
  };
},
methods: {
  onScroll (e){
    if (typeof window === 'undefined') return
    const top = window.pageYOffset ||   e.target.scrollTop || 0
    this.fab = top > 500
  }
}
```

# すべてまとめて表示する
さきほどの機能をまとめ、装飾やアニメーションを追加するとのようなソースになります。
少し動きも付けたかったので`transition`を使ってみました。

```vue
<transition name="fade">
  <v-btn 
    v-scroll="onScroll"
    v-show="fab"
    fab
    dark
    fixed
    bottom
    right
    color="primary"
    @click="toTop">
    <v-icon>fas fa-angle-up</v-icon>
  </v-btn>
</transition>

<script>
export default {
  data: () => {
    return {
      fab: false
    };
  },
  methods: {
    onScroll (e){
      if (typeof window === 'undefined') return
      const top = window.pageYOffset ||   e.target.scrollTop || 0
      this.fab = top > 500
    },
    toTop () {
      this.$vuetify.goTo(0)
    }
  }
}
</script>

<style scoped>
.fade-enter-active, .fade-leave-active {
  transition: 0.5s;
} 
.fade-enter, .fade-leave-to {
  opacity: 0;
  transform: scale(0);
}
</style>
```

これで外部ライブラリを使わずvuetifyの機能のみでページへ戻るボタンが作れます。
Thinkpad wireless keyboard を mac でつなげたときの初期配置

上のメニューバーの入力ボタンから、「キーボードビューワーを表示」を押せば、押したキーに対応するキーが表示される。
しかし、Thinkpad wireless keyboard のいくつかのキーは押しても表示されないものがあるので、ここでメモる
役割は Karabinar の設定画面で言う「From Key」に該当する呼び名を記す。


| 配置      |   役割 |
|-----------------|------------------|
| Windowsキー        | left_command |
| 左Alt           |    left_alt (equal to 'left_option') |
| 右Alt             |   right_alt (equal to 'left_option') |


Karabiner

![20200720-19.26.51 238.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139085/91bcb54e-73e1-09ec-6c58-ff4f97533bb1.png)
![20200720-19.26.51 237.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139085/adbcda99-fd1a-9e53-e430-a62c7c96e820.png)
Selenium Grid を Docker で試す

[Anaconda イメージに Chrome をインストールしてみたり](https://qiita.com/hoto17296/items/c2abfb60d3c6a77f065d) していたが、やはりビルドに時間がかかってしまってしんどいので Chrome 部分だけ別イメージとして切り出せないかと考えていたところ、WebDriver の操作を REST API 経由で行える Selenium Grid なる仕組みがあることを知ったので試してみた。

## Selenium Grid を起動する
Selenium Grid を利用できる Docker イメージが公式から公開されているのでこれを使う。

[SeleniumHQ/docker-selenium: Docker images for Selenium Grid Server (Standalone, Hub, and Nodes).](https://github.com/SeleniumHQ/docker-selenium)

複数のブラウザを使う場合は Hub と各ブラウザの Node をそれぞれ立ち上げる必要があるが、今回は Chrome で試したいだけなので Standalone のイメージを使った。

``` yml:docker-compose.yml
version: "3"

services:

  chrome:
    image: selenium/standalone-chrome
    ports:
      - 4444:4444
    volumes:
      - /dev/shm:/dev/shm
```

ポート 4444 で REST API が公開される。
WebDriver を操作する API は `/wd/hub` らしい。

``` console
$ docker-compose up
```

## Python から Selenium Grid を使う
Python から Selenium Grid を使う場合は `selenium.webdriver.Remote` を利用する。

``` console
$ pip3 install selenium
```

``` python:main.py
import sys
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities


def search(driver, query):
    driver.get('https://google.com/')

    q = driver.find_element_by_name('q')
    q.send_keys(query)
    q.submit()

    r = driver.find_element_by_class_name('g').find_element_by_class_name('r')
    title = r.find_element_by_tag_name('h3').text
    url = r.find_element_by_tag_name('a').get_attribute('href')

    return title, url


if __name__ == '__main__':
    query = ' '.join(sys.argv[1:])
    options = {
        'command_executor': 'http://localhost:4444/wd/hub',
        'desired_capabilities': DesiredCapabilities.CHROME,
    }
    with webdriver.Remote(**options) as driver:
        title, url = search(driver, query)
        print(f'{title}\n{url}')
```

Google 検索して結果トップのタイトルと URL を表示するスクリプトを書いてみた。

``` console
$ python3 main.py qiita
Qiita
https://qiita.com/
```
Union-Find  で一人用ぷよぷよの実装をちょっと楽に

ぷよぷよ、なんて実装の難しいプログラムであろうか。
…多くは対戦AIなどが語られるが、一人用の実装でも難易度は十分に高い。

そこで、本記事では競プロでお馴染みのデータ構造「素集合データ構造(Union Find木)」を利用して、実装をちょっとだけでも楽にできるんだぜ…という話をしてみる。

# どこで使う？

 - 同じ色のぷよを繋がりを消去
 - 消去したぷよの数を計算

…こんなものだが
従来使われていた探索アルゴリズムでは、**とにかく実装が面倒なのである。** なんとなく想像はつくと思うので詳細は省略するが、個人的にはおそらく探索よりもUnionFind木を利用する方が圧倒的に実装が楽であると思う。
ただ、メモリは探索よりも消費する。…といっても、実用範囲ではせいぜい80個分くらいの配列が付け足されるだけなので、マシンにとっちゃもはや「ない」ようなもんでしょう(初心者観点から)
計算効率もちょっと悪いが、同じく雀の涙程度である。

# Union Find木とはなにか

初めて知る人はこちらのページを参考にしてほしい。良い解説である。https://qiita.com/ofutonfuton/items/c17dfd33fc542c222396

動作確認はオンラインジャッジより行うのが良い。以下はAtCoderのもの。https://atc001.contest.atcoder.jp/tasks/unionfind_a


# 使い方

とりあえず、わかりやすくイメージできるように、次のようなぷよの配列があると仮定して考えてみよう。

```

\ ⬜️⬜️⬜️⬜️⬜️⬜️　/  0, 1, 2, 3, 4, 5
/ ⬜️⬜️⬜️⬜️⬜️⬜️　\  6, 7, 8, 9,10,11
\ ⬜️⬜️⬜️⬜️⬜️⬜️　/ 12,13,14,15,16,17
/ ⬜️⬜️⬜️⬜️⬜️⬜️　\ 18,19,20,21,22,23
\ ⬜️⬜️⬜️⬜️⬜️⬜️　/ 24,25,26,27,28,29
/ 🟥⬜️⬜️⬜️⬜️⬜️　\ 30,31,32,33,34,35
\ 🟩⬜️⬜️⬜️⬜️⬜️　/ 36,37,38,39,40,41
/ 🟥🟦⬜️⬜️⬜️⬜️　\ 42,43,44,45,46,47
\ 🟦🟦🟦🟩🟩🟩　/ 48,49,50,51,52,53
/ 🟥🟥🟧🟩🟥🟩　\ 54,55,56,57,58,59
\ 🟥🟩🟩🟧🟧🟥　/ 60,61,62,63,64,65
/ 🟩🟧🟧🟥🟥🟩　\ 66,67,68,69,70,71
```
左は置かれているぷよ、右はそれぞれの配列を識別する番号を表す。
(任意の番号をnとおくと、xy座標型には (n%6,n/6) として変換できる。 )

今に発火せんとしている。

この状態から、まずこれら72個すべての配列の要素において、それらをパラメータとしたUnion Find木を定義する。

そして

 - 横に隣り合っている要素同士(13-15, 63-64など)
 - 縦に隣り合っている要素同士(17-23, 43-49など)
 
のすべての組み合わせにおいて、「その座標にあるぷよの種類が同じであればuniteする」という作業を行う。
すると、

```

\ ⬜️⬜️⬜️⬜️⬜️⬜️　/  0, 0, 0, 0, 0, 0
/ ⬜️⬜️⬜️⬜️⬜️⬜️　\  0, 0, 0, 0, 0, 0
\ ⬜️⬜️⬜️⬜️⬜️⬜️　/  0, 0, 0, 0, 0, 0
/ ⬜️⬜️⬜️⬜️⬜️⬜️　\  0, 0, 0, 0, 0, 0
\ ⬜️⬜️⬜️⬜️⬜️⬜️　/  0, 0, 0, 0, 0, 0
/ 🟥⬜️⬜️⬜️⬜️⬜️　\ 30, 0, 0, 0, 0, 0
\ 🟩⬜️⬜️⬜️⬜️⬜️　/ 36, 0, 0, 0, 0, 0
/ 🟥🟦⬜️⬜️⬜️⬜️　\ 42,43, 0, 0, 0, 0
\ 🟦🟦🟦🟩🟩🟩　/ 43,43,43,51,51,51
/ 🟥🟥🟧🟩🟥🟩　\ 54,54,56,51,58,51
\ 🟥🟩🟩🟧🟧🟥　/ 54,61,61,63,63,65
/ 🟩🟧🟧🟥🟥🟩　\ 66,67,67,69,69,71

```

となる。

こうなればあとは簡単である。

存在するrootごとにその要素の数を数え(30なら1個、36なら1個………43なら4個、51なら5個……71なら1個　といった具合。0はたくさんあるが、ぷよの置かれていない集合なので無視する)、4つ以上なら消す対象の木としてrootの数値を保持しておく。
そしてもう一度ループしてその木の要素のぷよを消し、その数に応じてスコアを加算。

ぷよが消せたら、空中に浮いているぷよを落としてもう一度この作業を行う。そして、消せるぷよがなくなるまで繰り返したら次のループへ。

という感じ。おしまい。

# 備考

僕が実際に実装した例。なお、上記のアルゴリズムとは若干異なる部分もいくつかあるが、仕組みは同じである。
https://github.com/Perukii/PeruPuyo
Lambdaで使うKinesis Data Streamテストイベントの作成

ちょっとメモ。LambdaでKinesis Data Streamのテストイベントを作るときは、「テストイベントの設定」画面でイベントテンプレートに「Amazon Kinesis Data Stream」を選択する。イベントの内容に、それらしいJSONデータが設定される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55718/78c5dd7f-fd5a-09ea-818c-7d44c9d746c6.png)

ここで `data` に収められているのは、デコードすると "Hello, this is a test 123." となる文字列なのだけど、実際にはテストをする上でここに任意のデータを入れておきたい。その時は、Pythonでは次のようにbase64変換した文字列を生成する。

1. データをJSON文字列などに変換する（`str`型になる）。
2. データをUTF-8に変換する（`bytes`型になる）。
3. データをbase64エンコードする。

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

~~~
>>> print(type(data), data)
<class 'dict'> {'Timestamp': '2020-03-17T09:41:29.284244', 'Name': 'Akio Asada', 'Mail': 'asada@example.com'}
>>> data_str = json.dumps(data)
>>> data_bytes = data_str.encode('utf-8')
>>> data_base64 = base64.b64encode(data_bytes)
>>> print(type(data_base64), data_base64)
<class 'bytes'> b'eyJUaW1lc3RhbXAiOiAiMjAyMC0wMy0xN1QwOTo0MToyOS4yODQyNDQiLCAiTmFtZSI6ICJBa2lvIEFzYWRhIiwgIk1haWwiOiAiYXNhZGFAZXhhbXBsZS5jb20ifQ=='
~~~

まとめてやれば、こうなる。

~~~
>>> base64.b64encode(json.dumps(data).encode('utf-8'))
b'eyJUaW1lc3RhbXAiOiAiMjAyMC0wMy0xN1QwOTo0MToyOS4yODQyNDQiLCAiTmFtZSI6ICJBa2lvIEFzYWRhIiwgIk1haWwiOiAiYXNhZGFAZXhhbXBsZS5jb20ifQ=='
~~~

この `eyJUa（略）ifQ==` という文字列を、テストデータ作成画面の `data` の値に入れる。
RDRA2.0の業務フロー図をPlantUMLで描く

## RDRA2.0 + PlantUML = 最高

当方が担当するプロジェクトの要件定義フェーズでRDRA2.0を実践するにあたり、各種ダイアグラムをPlantUMLで記述することについての記事を参照することができて、とても参考になりました。

- [PlantUML Example for RDRA 2.0 ハンドブック](https://qiita.com/ogomr/items/97058a87337eaa2ba21a)
- [PlantUML で始めるリレーションシップ駆動要件分析 (RDRA)](https://qiita.com/nkenbou/items/86d5718b63f610dfd67f)

残念ながら後者の記事では、RDRAの業務フロー図をPlantUMLのアクティビティ図で描くのは満足のいく形にならなかったと述べられています。

## PlantUMLでも満足の行く形で業務フロー図を描きたい！

RDRA2.0の業務フロー図は、各アクティビティに対して複数のユースケースが結び付けられているのが特徴です。そこで、PlantUMLのアクティビティ図を使ってアクティビティを描き、それに対するユースケースをノートとして記述してみました。

![library.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19408/c57f94c9-355f-cb82-6a25-e4e1613676e3.png)


```
@startuml
title 業務フロー図 - Web予約業務

|会員|
start
:貸出予約;
note left
(UC)貸出本の予約・取消をする
end note

|図書館員|
:予約図書の準備;
note right
(UC)予約図書一覧を出力する
----
(UC)予約図書を取り置く
end note

if (貸出図書が) then (ない)

|会員|
end
else (ある)

:予約図書を受け取る;
note left: (UC)取置図書を消し込む
stop

endif
@enduml
```

比較的シンプルに、PlantUMLの本来の機能に沿った形で、RDRA2.0の業務フロー図を記述することができたと思います。
みなさんの参考になればさいわいです。

## 参考文献

- [RDRA2.0 ハンドブック: 軽く柔軟で精度の高い要件定義のモデリング手法](https://www.amazon.co.jp/dp/B07STQZFBX)
- [PlantUML.com - アクティビティ図](https://plantuml.com/ja/activity-diagram-beta)
wgetコマンドでminicondaインストール

環境
miniconda
linux
OS: ubuntu
ダウンロード日：2020/3/16

#minicondaインストール時
ターミナルのコマンドラインからサーバにインストールしたかった。
（初心者のため、公式minicondaからダウンロードしてくるときにラップトップのデスクトップにしか落としてこれなかった。wgetのコマンドを知らなかったので苦戦しました。）
-インストール
```wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh```
-実行
```bash Miniconda3-latest-Linux-x86_64.sh```
-確認
``` conda info -e```

表示されるエラー
conda: command not found

おやおや → 内心(´;ω;｀)

#PATHを通してあげてcondaコマンド使えるようにする
現在miniconda3のディレクトリ内
ここで
```vi ~/.bashrc```
この内容のexport PATH部分を変更する。
```export PATH=~/miniconda3/bin:$PATH```
export PATHの記述がない場合はaliasの記述の下に追加する
保存して、ターミナルで下記コマンドでシステムに設定反映
```source ~/.bashrc```

再度、
``` conda info -e```
を実行すると環境情報が出てきます。

助けになった参考URL
[anaconda3.6 PATHを通す。condaコマンドが使えない場合。](http://kaerupyokopyoko.hatenablog.com/entry/2017/10/28/013923)
カラムの追加、削除の方法と間違ったマイグレーションを作ってしまった時の対処法。

よくカラムの追加や削除をするのに、その度にやり方を忘れて毎回いろんな記事を検索してしまってるので、備忘録として記事にしました。

#カラムの追加方法

`$ rails g migration Addカラム名To追加先テーブル名 追加するカラム名:型`
↓↓↓↓↓↓↓↓（例）
`% rails g migration AddPrefectureToItems prefecture:references`

書き方はキャメルケースで書きます。「SampleHogeHuga」のように単語の頭文字を大文字にすることで単語を区切ります。

#カラムの消し方
基本的には、
`rails g migration Removeカラム名From削除元テーブル名 削除するカラム名：型`
を使った方が良いと思います。
しかし、自分の場合、なぜかうまくrails db:migrateが実行できない事が多かったので、直接MySQLテーブルを操作する方法で削除しました。
#SQL文で指定したカラムを消す方法
まず、`$ mysql -u root`でmysqlに接続。
`$ SHOW DATABASES;`で指定するデータベースを探す。
`$ USE データベース名;`でデーターベースを指定する。
`$ SHOW TABLES;`でテーブルを探す。
`$ ALTER TABLE テーブル名 DROP カラム名;`で指定したカラムを削除。
↓↓↓↓↓↓↓↓（例）
`$ ALTER TABLE goods DROP stock;`

#間違ったマイグレーションファイルを作ってしまった時の対処法
まずは、マイグレーションファイルの状況確認。
`$ bundle exec rake db:migrate:status`
<img width="440" alt="スクリーンショット 2020-03-17 9.29.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543993/4347825b-892a-f783-8db0-188c6e99f34e.png">
左端が「down」になってるファイルは消せますよ〜という意味。
`$ rails db:rollback`で一個手前のファイルをダウン状態にできる。
`$ rails db:rollback STEP=○`で現在地を含めた○個前までdown状態にできます。（つまり○+1個前のファイルまで実行された状態）
`$ rm -rf db/migrate/マイグレーションファイル名`でマイグレーションファイルを削除。

`$ bundle exec rake db:migrate:status`で確認。
<img width="472" alt="スクリーンショット 2020-03-17 9.40.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543993/ba0e572f-9015-9b26-d57f-406f00021bb6.png">
削除成功！

※本来は最新のマイグレーションから順番に消していく方がいいです。
PHPでSORACOM APIを呼び出す

SORACOMのAPIをPHP（Guzzle）を使って呼び出してみます。

# SAMを用意する
ユーザーコンソールからAPIを実行するための[SAM（SORACOM Access Management）](https://dev.soracom.io/jp/start/sam/)ユーザーを用意します。

ユーザーを作成して権限設定、認証情報を作成しましょう。
AWSのIAMと同じような感じです。

発行した認証キーIDと認証キーシークレットはAPI呼び出しに必要になります。

# PHPからAPIを呼び出す

## Guzzleをインストール
HTTPクライアントのGuzzleをインストールします。

```
composer require guzzlehttp/guzzle
```

## APIを呼び出す

最初にauthAPIに認証キーIDと認証キーシークレットを渡して、APIキーとAPIトークンを取得する必要があります。
他のAPIはすべて、取得したAPIキーとAPIトークンをリクエストヘッダに含めてリクエストしなければいけません。

下記のサンプルでは、最初にauthAPIを呼び出して次にLatestBillingAPIを呼び出しています。

```php:exec.php
<?php
require 'vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

const BASE_URL = 'https://api.soracom.io/v1/';

$credential = [
    'authKeyId' => 'keyId-************************',
    'authKey' => 'secret-*****************************************',
];

$httpClient = new Client();

// APIキーとAPIトークンを取得
$url = BASE_URL . 'auth';
try {
    $response = $httpClient->request('POST', $url, [
        'headers' => [
            'Content-Type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'json' => $credential,
    ]);
} catch (ClientException $e) {
    throw $e;
}
$body = $response->getBody();
$info = json_decode($body, true);
$apiKey = $info['apiKey'];
$operatorId = $info['operatorId'];
$userName = $info['userName'];
$token = $info['token'];

// LatestBillingAPIの呼び出し
$url = BASE_URL . 'bills/latest';
try {
    $response = $httpClient->request('GET', $url, [
        'headers' => [
            'Accept' => 'application/json',
            'X-Soracom-API-Key' => $apiKey,
            'X-Soracom-Token' => $token,
        ],
    ]);
} catch (ClientException $e) {
    throw $e;
}
$body = $response->getBody();
echo $body;
```

実行結果は次のようになります。

```
>php exec.php
{"lastEvaluatedTime":"20200317003205","amount":0}
```

---

# 参考

[API リファレンス](https://dev.soracom.io/jp/docs/api/)
[FileMaker]FileMakerとGoogleカレンダーを連携[Integromat]

株式会社フルーデンス様の下記URLを参考にして、FileMakerで作成したイベント情報をGoogleカレンダーに反映させる機能を追加しました。

「Integromatを使いFileMakerとGoogleカレンダーを簡単に連携する」
https://frudens.jp/filemaker-google-integration-integromat/

その際に、**編集や削除機能**を実装しようとして難渋したので記載しておきます。

Integromatの使用方法やFileMakerとの連携は、[上記URL](https://frudens.jp/filemaker-google-integration-integromat/)に詳細が記載されているのでご確認いただければと思います。
**サンプルファイルのダウンロード**が可能です。

#Googleカレンダースケジュール作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530814/d7f74745-d87b-b091-0ad6-2199522d2511.png)
[上記URL](https://frudens.jp/filemaker-google-integration-integromat/)を参考にしてIntegromatのwebhooksとgoogle Calendarを連携させてカレンダー作成のAPIを作成します。

#カレンダー更新、削除
ここで行き詰りました。
イベント作成のユニークIDが取得できないとイベントを作成したあとに更新や削除ができなくなります。

そこで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530814/6617b877-c2a5-4872-ffe0-0d4f302e4f77.png)

このように右側にWebhook responseを追加しました。

webhook responseのbodyには「Event ID」を指定し、イベント作成時に戻り値として「Event ID」を取得できるようにしました。この「Event ID」をFileMaker内のフィールドに格納することで、特定のスケジュールに対して更新や削除が可能となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530814/c77f99d9-59b3-10b0-89b7-11a548a011d4.png)

Claris社（旧FileMaker社）も先日[Claris Connect](https://www.claris.com/ja/connect/)をリリースしましたが、今後はこういったアプリ間連携機能が主流になっていくのでしょうか。
CIに関する覚書

# CIとは
Continuous Integration：継続的インテグレーションの略。xUnitなどの単体テスト作成支援ツールを用いてテストを作成し、Jenkinsなどを用いでサーバで、定期的にテストを実行する仕組み。
定期実行を用いて、生産物（特にソフトウェア）の品質を高める目的で行う。

# xUnit
単体テストを行うためのフレームワーク。Javaの単体テストを行うためのJUnitが有名である。

# その他
CIを実現するためのノウハウの一つとして、開発環境の整備がある。MavenやGrandleにより、モジュール管理し、開発メンバ全員に同一開発環境を提供する。
また、Jenkins（のプラグイン）を用いてソフトウェア品質分析を行うことができる。
[Tips] Babylon.js でカメラの操作がスマホだと逆方向になってしまう対策

# はじめに

Babylon.js では `FreeCamera` で `attachControl` した際のカメラ操作が、
スマホで通常画面操作する際の向きとは逆になってしまっています。。:movie_camera:  :arrow_down: 

![dest.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86070/fee99410-6738-bd8c-1d2e-efb6cafddbe5.gif)

# カメラの操作を逆方向にする

修正するには [angularSensibility](https://doc.babylonjs.com/api/classes/babylon.freecamera#angularsensibility) という値をネガティブにします :thumbsup: 
`camera.angularSensibility = -camera.angularSensibility;`

念の為、Babylon.js の Playground にも動作確認出来るコードを置いておきました :airplane_small: 
https://www.babylonjs-playground.com/#TX7GF8#1

上記の実行結果です :arrow_down: 
![dest1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86070/73734f4a-63d2-c602-c8f9-f03d7e1ebfe9.gif)

ちなみに、`angularSensibility` の値は調整することで、
カメラの回転速度を向上させたり低下させたりすることが出来るので、
操作感を調整したい際は値を上げ下げしてみてください :gear: 
(`angularSensibility`の値のデフォルトは 2000.0 です)

# おわりに

カメラ操作の挙動に悩んでいる方の助けになれれば幸いです。。:pray:

# 参考リンク

- [Invert camera rotation? - Questions - Babylon.js](https://forum.babylonjs.com/t/invert-camera-rotation/1466/2)
- [FreeCamera - Babylon.js Documentation](https://doc.babylonjs.com/api/classes/babylon.freecamera#angularsensibility)
自炊したPDFの全ページにしおりを自動でつける方法

こんにちは。自炊したPDFをiPadで閲覧する際にBookmark機能は重宝すると思います。本ごとにカスタマイズしたしおりを付けるのが理想ですが、めんどうですよね。
そこで、本の『目次』とすべてのページに『ページ数』のしおりをつけることができれば、iPadでの閲覧が便利になると考えました。これを自動でするためのプログラムです。

iPadでの閲覧の場合、しおりがjavascript駆動であるとiPad上では動きません。javascript駆動でないしおりをつけるのが、このプログラムのミソです。

医療系の大学生である私が教科書をすべて自炊した際に、「目的のページに一発で飛べない」という電子書籍の欠点を打開するために作りました。

#必要なもの
widowsのPC
microsoft office excel
Coherent PDF Command Line Tools(CPDF)
（http://pdf-file.nnn2.com/?p=892）
#方法
##（概説１）
CPDFというコマンドラインで動くフリーソフトを用いて自動化していきます。iPadでの閲覧の場合、しおりがjavascript駆動であるとiPad上では動きません。CPDFでしおりを付ける際に使用する、しおり情報の入ったtxtデータを、batファイルとPowerShellとexcelをつかって、自動で作ります。そのままPowerShellにて、しおりをつけていきます。
##（概説２）
①バッチファイルにPDFをドラックアンドドロップするとPowerShellにPDFの場所を引数として渡します。
②PowerShellが起動して、『目次』のページ数と『開始ページ数』と『総ページ数』の入力を求められるので入力する
③その情報をもとにPowerShellがexcelをつかって、しおり情報の入ったtxtデータの元データを作成し、txtデータを出力します（※）。その後、PowerShell内でCPDFでしおり付PDFを出力します
（※）事前にヒナガタとなるexcelファイルを準備します。『目次』のページ数と開始ページ数を一定のセルに打ち込むと、CPDFのしおり情報に準拠したしおり情報になるように作っておきます。これを総ページ数分だけコピーして、txtデータを出力するということです。

#つづき
具体的なコードとヒナガタexcelファイルは次回の更新で記述いたします！
Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#11(モノのインターネット IoT)

Google Cloud Platform (GCP)のサービスで正式名称や略称はともかく、読み方がわからずに困ることがよくあるのでまとめてみました。

クラウド コンピューティング サービス  |  Google Cloud
https://cloud.google.com/?hl=ja



## まとめルール

まとめルールについては下記を参考ください。

Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#1(AI と機械学習/AI ビルディング ブロック) - Qiita
https://qiita.com/kai_kou/items/fa930eef23470c2f8f0b


## Amazon Web Services (AWS)のまとめはこちら！

Amazon Web Services (AWS)サービスの正式名称・略称・読み方チートシート - Qiita
https://qiita.com/kai_kou/items/cb29d261c8acc49fd22a

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita
https://qiita.com/kai_kou/items/a6795dbab7e707b0d1a6


## 概要について

サービス一覧ベージの概要を引用しています。

プロダクトとサービス  |  Google Cloud
https://cloud.google.com/products?hl=ja#product-launch-stages


間違いや、こんな呼び方あるよーなどありましたらコメントお願いします！


## Internet of Things (IoT) - モノのインターネット

### Cloud IoT Core

セキュリティを維持しながらデバイスを接続して管理します。

- 正式名称: Cloud IoT Core
- https://cloud.google.com/iot-core
- 読み方: クラウド アイオーティー コア
- 略称: なし
- 俗称: なし


### Edge TPU

エッジで推論を行うために設計された専用 ASIC。

- 正式名称: Edge TPU
- https://cloud.google.com/edge-tpu
- 読み方: エッジ ティーピーユー
- 略称: なし
- 俗称: なし
【Go】変数宣言の違い(  := 、 var )

## 変数宣言の違い( := 、 var )


基本的にはこちらで理解

[他言語プログラマがgolangの基本を押さえる為のまとめ](https://qiita.com/tfrcm/items/e2a3d7ce7ab8868e37f7#%E6%A6%82%E8%A6%81)


## 自分なりの整理

#### :=

・varとタイプ型を省略（自動判断してくれるのか、初期化の時間・容量に無駄がでるのか）
・関数内のみで宣言可能

#### var

・指定したタイプ型によって初期化される（ポインタ型はnilで初期化）
・関数外でも宣言可能

```Go:
func main() {
	var a int
	var b string
	var c []int

	var d *int
	var e *string
	var f *[]int
	g := 1

	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)

	fmt.Println(d)
	fmt.Println(e)
	fmt.Println(f)

	fmt.Println(g)
}
```

結果

```
0

[]
<nil>
<nil>
<nil>
1
```
シンボル

シンボルとは、

・見ため文字列だけど、
内部的に数値として扱われるもの。
・比較、検索に関して速度面で有利であるメリットがあるので、データの名前に使われることが多い。

[使用方法]
コロンを前置して定義する。

[使用例]
:test
#VsCode で、現在のカーソル位置にある単語をファイル内検索して、次々にマッチさせるには C+K -> C+D

CommandまたはControleキーを押したまま K -> D  -> K -> D -> K -> D  と連続的に押すことで、次々に飛べる。

![image](https://user-images.githubusercontent.com/13635059/76712088-bb935780-6758-11ea-84c8-38e687f4c0c8.png)

![image](https://user-images.githubusercontent.com/13635059/76712008-124c6180-6758-11ea-8e77-e507f4e5f56f.png)
![image](https://user-images.githubusercontent.com/13635059/76712009-12e4f800-6758-11ea-8b29-481486c9a8c1.png)

# Ref

https://code.visualstudio.com/docs/getstarted/keybindings

![image](https://user-images.githubusercontent.com/13635059/76712037-55a6d000-6758-11ea-800d-1c97c943faf7.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
.htaccessを使わず、S3から圧縮したJS,CSSを提供する

サーバーレスのアプリのため.htaccessを操作しづらい環境があったのでS3からこうやりました。
肝はアップロード時のcontent-encodingとcontent-typeの指定です。これがないとうまく読み込んでくれないです。

```bash
gzip --best -f public/js/app.js # app.js.gzが生成される -fつけないと２回目から上書きしてくれない
aws s3 cp public/js/app.js.gz s3://xxxx/ --content-encoding "gzip" --content-type "text/javascript"
```

```html
<script src="https://xxxx.s3-ap-northeast-1.amazonaws.com/app.js.gz"></script>
```

参考
[How to: Gzip compression of CSS and JS files on S3 with s3cmd](https://christianfei.com/posts/how-to-gzip-compression-of-css-and-js-files-on-s3-with-s3cmd/)
[【Tips】S3 アップロード時に ContentType を指定する](https://dev.classmethod.jp/cloud/aws/specify-contenttype-at-s3-upload/)
powercfgコマンドでちょっとハマったのでメモ

### CPU使用率の上限変更がうまくいかなかった
ウィルススキャン実行中、CPU使用率100%状態が続きPC本体のファンが数十分ゴーーッとなり続けていました。
職場一斉に始まるのでかなりの騒音。
ウィルス対策ソフト自体はCPU使用率（やコア数）を設定できないので、powercfgコマンドを使うことにしました。

1. 先ずCPU使用率の上限を80%に制限する。
2. ウィルススキャンを実行し、終了を待ち合わせる。
3. CPU使用率の上限を100%に戻す。

一連の処理をVBScriptで書いていざ実行してみると、以前より時間が掛かるもののファンは大人しくなったので、
３人に試してもらうと、２人は今まで通りファン音が鳴り響いてしまいました。

### 原因
最初に書いたCPU使用率上限を80%に変更するpowercfgコマンドは、、、

```
powercfg /SETACVALUEINDEX SCHEME_CURRENT SUB_PROCESSOR PROCTHROTTLEMAX 80
```
これ１行でCPU上限80%が即反映されると思っていたのですが、

```
powercfg /SETACVALUEINDEX SCHEME_CURRENT SUB_PROCESSOR PROCTHROTTLEMAX 80
powercfg /SETACTIVE SCHEME_CURRENT        ※この１行が必要でした。
```
VSCodeでRustの環境を構築しようしたらCouldn't start client Rust Language Server

エラーを確認してから解決するまでの一部始終です。

## とりあえずこれを入れとけば良いんでしょう？

[Rust (rls) - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust)

そして、 
`cargo`コマンドで作成したプロジェクトを開くとRLS（Rust Language Server）がインストールされると、、

## おや？

<img width="390" alt="スクリーンショット 2020-03-16 11.18.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528526/8e542aa3-519f-64b6-1f5e-bc7b01a0691d.png">

## エラーに従う
> Couldn't start client Rust Language Server
> Rustup not available. Install from https://www.rustup.rs/

こちらに従いアクセスします。
https://rustup.rs/

```shell
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
これをやれっていうメッセージが、ん、、やったような？
[[Rust] とりあえずHello World!してみた - Qiita](https://qiita.com/kozzzz/items/eba9d623bdace702ee69)

とりあえず、実行。

```
curl: option --proto: is badly used here
```
なんか文句言われた。


## こんな時は設定を見つめる
rustupに依存してそうなのでそれっぽいところを、、
おや。。。？

```
"rust-client.rustupPath": "rustup"
```

デフォルト設定がこれになってますね。
変えてみましょう。

```
"rust-client.rustupPath": "[インストールしたパス]/.cargo/bin/rustup"
```

おお、いけそう！

## The Rust Language Server server crashed 5 times in the last 3 minutes. The server will not be restarted.

はい、次の問題が発生しました。

https://github.com/rust-lang/rls

こちらのsetupにそって実行していくことにしましょう。

```shell
rustup update
rustup component add rls rust-analysis rust-src
```

そして、VSCodeの再起動。

## エラー解消！！
やりました。下のくるくるがなくなりました！
最近何かとハマる気がします。
データベース方式

# データベースモデル
## ANSI/X3/SPARC 3種のスキーマ構造

### 概念スキーマ
　データベース化対象の業務とデータの内容を論理的な構造として記述したもの
　テーブルの正規化やCREATE TABLEによる表定義が概念スキーマに相当する

### 外部スキーマ
　データの利用者からの見方を記述したもの
　SQLのビューが外部スキーマに該当する
#### サブスキーマ
　外部スキーマの別称

### 内部スキーマ
　データを記憶装置上にどのような形式で格納するか記述したもの
　ファイル編成やインデックスの設定などが内部スキーマに相当する
シェルでQueryを整形して記載してGraphQL APIを呼び出す

# 目的
GraphQLを実装している際に、GraphiQLが使えない環境でシェルから呼び出して動作確認したい場合の対応です。

外部への接続が遮断されている環境で、動作確認する必要がある場合には以下の様なシェルスクリプトを書くと良いかと思います。

# 作成したシェルスクリプト
```bash
#!/bin/bash

GRAPHQL_API_ENDPOINT="http://127.0.0.1:8000/graphql"

# ここにガンガン、クエリを書いてください。
ORG_QUERY=`cat << EOS
query {
  clubs {
    id
    name
  }
}
EOS
`

QUERY=`echo ${ORG_QUERY} | tr '\n' ' '`
JSON_PARAM=`cat << EOS
{ "query": "${QUERY}" }
EOS
`

curl -H 'Content-Type: application/json' -X POST -d "${JSON_PARAM}" ${GRAPHQL_API_ENDPOINT}
```

# CSRFのエラー(CSRF cookie not set.)が出るために、オフにしました。
Graphene Djangoで API を作成した場合 CSRF cookie not set.が表示されました。
私の場合は、動作確認だけが目的だったのでコメントアウトで対応しました。

```python:settings.py
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
```
自分のfigmaの作業テンプレートを公開するよ[モバイルアプリ向け]



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409192/153a8189-997e-8140-6224-1a5de3d18e8e.png)

# この記事について
自分が使っているfigmaのテンプレートを公開します。
ベースは[Material Design 2.0 Theming kit](https://www.figma.com/resources/assets/material-design-themeing-ui-kit/)
マテリアルデザインベースです。

# 私について
* 個人開発者としてモバイルアプリをつくって、その収益で生計を立てたいエンジニア
* Flutterで開発を始め、いくつかアプリを作ろうとするも、いづれのアプリもデザインが出来ずに断念
* デザインを学ぶ必要に迫られて、DailyCocoda!でデザインを学び始める。
* デザインは全くの初心者でセンス0
* 7/23日から始めたDailyCocodaが10/15日に目出度く完走 <-- いまここ
* アプリをリリースして生計を立てる <-- これから

# 諸注意
* 内容に一部間誤っている点があるかもしれません。その場合は（優しく）指摘してください。


# 落とし方
* figmaに登録してください。
* 登録後[このリンクを開いてください。](https://www.figma.com/file/aV5pi69KRepM4AiX9663Jp/%E4%BD%9C%E6%A5%AD%E5%A0%B4)
* この段階ではview権限しかありませんので触ることができません。触れるようにします。
* back to Files でファイルに戻ります。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409192/144f8ec8-9d2c-1cde-25a9-f4a96d8d2542.png)
* 左上に作業場ファイルがあるので、右クリック -> Duplicate でコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409192/db27e197-0b3c-d993-9b9d-fd4156648abf.png)
* そうすると作業場(Copy)ファイルが出来上がります。
* このファイルのownerはあなたなので自由に触ることができます。


# 各ページの説明
working spaceページ以外は他のマテリアルデザイン系ファイルから移植したものです。 
working spaceは自作です。モバイルフレームワークは1〜2px単位でずれている可能性があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409192/0632277e-0fee-2486-9eba-5080ba94b542.png)


#リンク
* [デザインを何もしらないエンジニアがDailyCocoda！を3ヶ月かけて完走したので、1日目の自分にアドバイスする その１ 概要編](https://qiita.com/ampersand-dev/items/e0768faf4b7260fc28d6)
* [デザインを何もしらないエンジニアがDailyCocoda！を3ヶ月かけて完走したので、1日目の自分にアドバイスする その２ figma準備編](https://qiita.com/ampersand-dev/items/0bbe2de76b39db70551f)
* [デザインを何もしらない1日目の自分に "実践的" なマテリアルデザインの使い方を説明する - Layout Color Typography 編](https://qiita.com/ampersand-dev/items/28e3ba3dfd1871be9e78)
* [自分のfigmaの作業テンプレートを公開するよ[モバイルアプリ向け]](https://qiita.com/ampersand-dev/items/847e149794aaeb20ce12)
利益を上げている個人開発者とその代表的アプリのまとめ

# この記事について
後学のために、利益を上げている個人開発者とその代表的アプリをまとめました。


# 選定基準
* 個人開発者もしくは法人化して3年以内の元個人開発者であること。
* 収益を出していること。もしくは出していると思われること。(目安：16万/月以上)  
* 個人開発で達成できる規模感、もしくはリリース当初の規模であれば達成できたであろう規模感であること。  
* ゲーム系は除く(私がゲームを作らないので)


# お願い
このリストにいない人や修正すべき情報があったら教えてください。  


# 上記3つを満たしていると思われる人・アプリのリスト
敬称略、順不同、アプリのurlはgoogle play store

| ユーザー|代表的なアプリ|参考URL|収益/月|
|:-----------------|:------------------|:------------------|:------------------|
|[ だーすー](https://twitter.com/Neko_Inu_)|[アプリ☆メーカー](https://appli-maker.jp/)、[マシュマロ](https://marshmallow-qa.com/)|[Diver Down LLC.](https://diverdown.co.jp/)|起業|
|[あたか](https://twitter.com/atagon)|[Quickmemo+](https://play.google.com/store/apps/details?id=jp.toconakis.quickmemo)|[プロ個人 /ATAKA (安宅倫広)｜note](https://note.com/toconakis_tech)|30万|
|[TAKUYA](https://twitter.com/craftzdog)|[Inkdrop](https://www.inkdrop.app/)|[Craftzdog - Takuya Matsuyama](https://www.craftz.dog/)|100万|
|[gonta](https://twitter.com/gonta_appdev)|？|[Appvelous](https://appvelous.com/)|20万|
|[nabettu](https://twitter.com/nabettu)|[tabmemo](https://tabmemo.com/)|[フロントエンドの地獄](https://blog.nabettu.com/)|11万|
|[ジャバ・ザ・ハットリ](https://twitter.com/nodenodenode1)|[テック・ブック・ランク](https://www.techbookrank.com/)、[シティーズ](https://www.cityz.jp/categories/all)|[ジャバ・ザ・ハットリのブログ](https://www.jabba.cloud/)|?|
|[入江シンゴ](https://twitter.com/iritec_jp)|[MENTA](https://menta.work/)|[入江シンゴ｜note](https://note.com/iritec)|140万|
|[Saaay](https://twitter.com/pompompomer)|[診断アプリ](https://play.google.com/store/apps/developer?id=Testii)|[アプリ個人開発者Saaayのブログ](https://saaay-blog.com/)|160万|
|[田畑 浩平](https://twitter.com/nerd0geek1)|[quick-zip plus](https://quick-zip.plus/)|[田畑浩平｜note](https://note.com/nerd0geek1)|20万|
|佐藤雄紀|[Line Bloxx](https://apps.apple.com/jp/app/%E9%A0%AD%E3%81%8C%E8%89%AF%E3%81%8F%E3%81%AA%E3%82%8B%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%91%E3%82%BA%E3%83%AB-line-bloxx/id993950628)|[アプリ開発ってどれくらい儲かるの？](http://app-dev.hateblo.jp/)|15万|
|[takashi](https://twitter.com/cloverkizuna)|[文字数カウントメモ](https://play.google.com/store/apps/details?id=com.clover.strcntmemo)|[Miraku](https://miraku.dev/)|24万|
|[りょーた](https://twitter.com/ryota_yama)|[ハヤえもん](https://play.google.com/store/apps/details?id=com.edolfzoku.hayaemon2)|[聞々ハヤえもん開発者ブログ](http://hayaemon.jp/blog/)|50万|
|[さちえ](https://twitter.com/curry_solodev)|[トリオキニ](https://triokini.com/)|[さちえさんのレジュメ](https://www.resume.id/satie)|譲渡|


# 他の記事
* [デザインを何もしらないエンジニアがDailyCocoda！を3ヶ月かけて完走したので、1日目の自分にアドバイスする その１ 概要編](https://qiita.com/ampersand-dev/items/e0768faf4b7260fc28d6)
* [メモの心理的ハードルを爆下げするテクニック -外部記憶装置としてのScrapbox (+ Alfred + chrome拡張)-](https://qiita.com/ampersand-dev/items/cb9c2a40f20967b1bdff)
* [flutter web + firebase(hosting)でポートフォリオサイトをつくったよ](https://qiita.com/ampersand-dev/items/61ed134f871e7eab95ae)
* [自分のfigmaの作業テンプレートを公開するよ[モバイルアプリ向け]](https://qiita.com/ampersand-dev/items/847e149794aaeb20ce12)
* [flutter + firebaseで本番環境と開発環境を切り替える](https://qiita.com/ampersand-dev/items/39f7f6286058435a6bed)
【angular】FormBuilderの使い方

###1.FormBuilderをインポート
`import { FormControl, FormGroup, FormBuilder } from '@angular/forms'`
FormBuilderというクラスはライブラリ「@angular/forms」に定義されています。



###2.FormBuilderの注入
`constructor(private fb: FormBuilder) { }`
注入という方法でFormBuilderオブジェクトを作成します。
コンポーネントの「コンストラクタ」と呼ばれる初期化処理をする部分に記述します。

###全体としてはこうなります↓

```typescript:component.ts
import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, FormBuilder } from '@angular/forms';

@Component({
  selector: 'app-controls',
  templateUrl: './controls.component.html',
  styleUrls: ['./controls.component.css']
})
export class ControlsComponent implements OnInit {

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
  }

}

```

##FormBuilder書き方
```typescript:component.ts
  formGroupプロパティ名:FormGroup; //変数の準備
  constructor(private fb: FormBuilder) { 
    this.formGroupプロパティ名= this.fb.group({
      名前:初期値,
      名前:初期値
    });
  }
```
初心者によるプログラミング学習ログ 264日目

#100日チャレンジの264日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
264日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>264日目<br>・webサイト模写 1.5h<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1239637441025212416?ref_src=twsrc%5Etfw">March 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
古いサーバーにWindowsServer2016をインストールしたい！

# 古いサーバーにWindowsServer2016をインストールしたい！
知人たちと毎月行っている「鍋とボドゲとサーバー定例会」にて難儀なサーバーがあったので、まとめておきます。
また、今回の手法は、試行錯誤の末に行き着いた例なので、必ずしも正しいとは限りません。

割と古めの筐体にNTFS形式のUSBブートでWindowsをインストールしたいという人には役に立つかもしれません。
（追記：MicroServer G8にWinSer2019をインストールしようとしたところ同様の現象にハマり、同じ手順でセットアップ出来ました。）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548945/f6d7ccc0-1253-7b60-e4aa-4dab03d984d3.png" width=50%>

## 環境と状況
###環境
**サーバー機**

- HP ProLiant DL360 G6（Xeon E5540*2, DDR3 48GB, SAS 146GB*4-RAID5）

**OS**

- WindowsServer2016 Datacenter（USBメモリブート）

###状況
サーバーのBIOSセットアップ後、OSのisoファイルを焼いたUSBメモリを差し込み、USBブートしても起動しない。
ブート問題が解決し、インストールしようとしたら、「このドライブにWindowsをインストールすることはできません」といったエラーが表示されインストールできない。

###改善策
1. 別のWindowsブートメディアを使用し、起動後コマンドプロンプトからUSBメモリ内のStartup.exeを実行する
2. Diskpartから手動でDiskを用意する

##経緯と作業内容
ことの発端は、OSを書き込んだUSBメモリでブートできないことから始まった。
原因はおそらくこのサーバーがNTFS形式のメモリでのブートをサポートしていないためだと思われる。
しかし、WindowsServer2016のインストールイメージは5GBを超えるものであり、FAT32形式の壁にぶち当たってしまう。
また、DVDも2層式のディスクでなければ焼く事ができない。

困り果てた末、ようやくひとつの方法が見つかった。
それは、**別のWindowsインストーラーからUSBメモリ内のインストーラーを起動する**という方法である。

手順としては、まず別のWindowsインストーラーを用意する。
今回は、DVD版のWindows8パッケージがあったので、これを利用した。
（DVDやFAT形式でフォーマットされたUSBメモリであれば起動できるため）

起動後WindowsServerのUSBメモリを差し込み、`Shift+F10`キーを押しコマンドプロンプトを表示する。
次に、`diskpart`と入力し、DISKPARTを立ち上げる。
ここで、`list volume`と入力することで、USBメモリに割り当てられているドライブ文字を確認することができる。
判断にはラベルやドライブの容量を参考にすると良い。

例
![ex_list_volume](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548945/70c6aab5-d2fe-5945-8972-abed2560bc7a.png)

今回は、USBメモリに割り当てられたドライブ文字が"C"と仮定する。
`exit`でDISKPARTを終了し、`C:\sources\Setup.exe`を実行する。
すると、不思議なことにWindowsServerのインストーラーが起動する。
これでようやくセットアップできるぜ！！！！:grin::grin::grin::grin::grin:

<br><br><br><br><br>
しかし、現実はそこまで甘くない。
セットアップを続けていくと、インストール場所の選択画面で「このドライブにWindowsをインストールすることはできません」と表示され、ドライブ/パーティションの選択ができない。GUI操作でのフォーマットやパーティション作成を試したが選択できず。

どうしようも無いので、またDISKPARTを起動する。
先ほどと同じように、`Shift+F10`キーを押しコマンドプロンプトを表示し`diskpart`と入力することで起動できる。

ここでまず、インストール先のドライブを探す。
`list disk`で接続されているディスクの一覧を表示できる。

例
![ex_list_disk](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548945/9db0681b-e39e-fe4a-4251-09071396fe9d.png)

インストール先のディスク番号を確認する。
今回はディスク0にインストールする。

`select disk 0`でディスク0を選択し、`clean`で消去する。
<font color="Red">※確認無しでパーティション/データがすべて消えるため注意すること</font>

`convert mbr` と入力し、ディスクをMBRにします。
`create partition primary size=◯◯◯◯◯MB`で任意のサイズのパーティションを作成します。
`list part`でパーティションを確認し、`select part 1`でパーティション1を選択します。
`active`で起動ドライブに指定し、`format fs=ntfs quick`でパーティションをフォーマットします。
最後に`assign`でマウントします。←要らないかも？

これで、WindowsServer2016が問題なくがインストールできました。
めでたしめでたし...
【メモ】mapを使ってカウンターを作る際の初期化の挙動について

# 素因数分解
以下のような素因数分解ライブラリをよく見かける

```c++
template<typename T>
std::map<T,T> prime_factor(T n){
  std::map<T,T> res;
  for (T i=2;i*i<=n;i++){
    while( n%i == 0){
      ++res[i];
      n/=i;
    }
  }
  if (n!=1) res[n] = 1;
  return res;

}

```

しかしここで疑問なのが、存在しない参照を行っていることである。またコンパイラなり処理系に依存してしまうような未定義動作にも見えなくもない。
せっかくなのでC++の規格を読んで確認してみることにした
参照したのは[C++14 (C++1y) ISO/IEC 14882:2014　N4140の23.4.4.3 map element access](https://timsong-cpp.github.io/cppwp/n4140/map.access)
以下が規格からの抜粋である

```
T& operator[](const key_type& x);

1 Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.

2 Requires: key_type shall be CopyInsertable and mapped_type shall be DefaultInsertable into *this.

3 Returns: A reference to the mapped_type corresponding to x in *this.

4 Complexity: Logarithmic.
```

規格を読んだのは初めてだが、4点に分けて明快に実装されているべきことが書いてある。
存在しないkeyが参照された場合の動作は"Effect"の部分にかかれている。keyとしてx,valueとしてTのデフォルトコンストラクタが呼ばれる。
int やlong longでどうなるのかはちょっとわからなかったがDefaultConstructibleでなおかつクラス型でない場合は、ゼロ初期化されるらしい（[C++ reference](https://en.cppreference.com/w/cpp/container/map/operator_at)）、おそらく規格なのだろうが規格のどこに書いてあるのかはよくわからなかった。
そしてReturnsの項目によれば、`*this`のkeyに対応する参照が返ることになっているとわかる。（これは当たり前だが）
計算量は$O(\log n)$（平衡二分木なので）

まとめると、基本的には存在しないkeyを参照した場合、0あるいはデフォルトコンストラクタで生成されたものが勝手に入ってくれる。
そのため、カウンターのようなものを実装する場合（すなわちvalueがintやlonglongな場合）は、keyの存在を確認せずにdict[key]++として大抵（規格通りに実装された全て？）の処理系で正しく動くことが分かった。。(なお本当にcount目的だったらunordered_mapを使うべきかもしれない)

結局解決していない初期化について(T()と書かれた部分について、int型ではどのように動作すると規格化されているか)に詳しい方などからのコメントをお待ちしています。
ディープラーニング　服装の分類機　素材集め編_1

#【概要】
大目標として、女性服の分類機を作成します。
今回はディープラーニングを行うための素材を集めるための手法について簡単に記述します。

#【目標】
ネットで画像を取得する

#【環境】
Windows10
google crome (ブラウザ)
python3.6
selenium (pythonライブラリ)

#webスクレイピングについて
###知っておくべきこと
webスクレイピングは用法容量を守らないと大変なことになります。
webサイトの規約に違反する場合や相手サーバへ負荷をかけてしまう場合は違法となります。
またスクレイピングで取得したモノの扱い方も注意しましょう。肖像権、著作権など知らなければいけないことは山ほどあります。頑張りましょう。

これらについては自分で時間をかけて調査して、健全なスクレイピングを行ってください。

# Python + Selenium
私がスクレイピングにセレニウムを利用する理由はjsで動的に生成されるサイトにも対応できるからです。requestsなんかでもweb探索は可能ですができないことが多く感じたためライブラリを変更しました。
あとは実際にwebを自動的に探索している様子を見るのが楽しかったというのもあります。

###サンプル

```py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import urllib.request as req

site_a= "webページのurl"
options = Options()
# options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
driver.get(site_a)
time.sleep(3)
```
これを実行すると自動的にcromeが起動し、指定のページを開き、3秒後にページを閉じます。

簡単な導入ですが、勝手にブラウザが立ち上がってページを開く様子は見ていて楽しいですね♪

ここから画像を取得したり、連鎖的に他のページへ移動する手法は少し踏み込まないといけません。

調べていくうちにurlの構造を学ぶことができたり、htmlの構造なども学ぶきっかけになるかと思います。そのうちスクレイピングはcromeが最強かもしれないと思い始めるかもしれません。

それらを書き出すと果てしなく長くなりそうなので別記事にでも記述しようかと思います。
Railsでタブやナビゲーションをカレント表示する方法

Rails管理画面アプリのナビゲーションを作成するにあたって、
現在ページのカレント表示のやり方で簡単な方法が分かったので紹介します。

### 例）トップページの場合

まずはトップページを例とします。
トップページへのヘルパーメソッドは`admin_path``（/admin）`とします。


```_navbar.html.erb
<ul class="nav">
  <li class="nav-link <%= 'active' if request.path == admin_path %>"><a href="<%= admin_path %>">トップページ</a></li> #ここの行に注目
  <li class="nav-link"><a href="#">リンク1</a></li>
  <li class="nav-link"><a href="#">リンク2</a></li>
</ul>
```

### 解説

`request.path`で現在のパスがわかるので、これと`admin_path`のヘルパーメソッドを比較し、
trueだった場合はactiveのクラスを付与するようにしています。
`（if request.path == admin_path の箇所）`

### 例）トップページ以外の場合

次はトップページ以外を例とします。
前提として`routes.rb`には`admin_users`を`resources`として設定していること。
トップページ以外へのヘルパーメソッドの例は`admin_users_path``（/admin_users）`とします。

```routes.rb
Rails.application.routes.draw do
  resources :admin_users
end
```
```_navbar.html.erb
<ul class="nav">
  <li class="nav-link <%= 'active' if request.path == admin_path %>"><a href="<%= admin_path %>">トップページ</a></li>
  <li class="nav-link <%= 'active' if request.path.starts_with?(admin_users_path) %>"><a href="<%= admin_users_path %>">ユーザー一覧</a></li> #ここの行に注目
  <li class="nav-link"><a href="#">リンク2</a></li>
</ul>
```

### 解説

`request.path`で現在のパスがわかるので、これと`admin_users_path`のヘルパーメソッドを`starts_with?メソッド`で先頭の文字列をチェックし、
trueだった場合はactiveのクラスを付与するようにしています。
`（if request.path.starts_with?(admin_users_path) の箇所）`

#### 参考にさせていただいたURL
[Rails4・Rails5 で現在のURLを取得する。](https://marketing-web.hatenablog.com/entry/rail4_get_url)
ディープラーニング　服装の分類機　考え方編

#【概要】
大目標として、女性服の分類機を作成します。
この記事はディープラーニングを行う上での計画の立て方について考察しながら書くメモです。

#【目標】
・服装の分類機の精度を効率よく上げるための計画を立てる。
・当面の目標として女性用の服を5クラス分類する。
・分類するジャンル：
ニット、パーカー、シャツ、ボレロ、カットソー

#【考察】
###手を動かす前に構造を考える
男性の服は割と分かり易い構成をしているものが多いが女性の服はあり方が自由で非常にバリエーションが多いように感じます。

簡単で偏見的な書き方ですが、男性用の服＝上半身の服＋下半身のパンツ＋靴　というものがメジャーだという印象を持っています。

反して女性の服はワンピースのように上下にわたるもの、重ね着、微妙な構造の違いで名称が変わるものなど、分類を行う上で非常に判別を難しくする要素があり、後から分類対象を10種、20種と増やしていくと、判別させる手法がこんがらがると予想されます。

後からでも対応できる分類を行うためにも、まずはその事象の体系を把握しておく必要があります。

今回の場合はレディースファッション系のサイトで大枠の分類を確認してみましょう。
トップス、アウター、シューズなど大枠のファッションの分類があります。
トップスの下にはパーカーやシャツのような分類が行われています。シャツの下にはノースリーブ、七分丈など。。。
とても分かり易くプロの方々が体系分けした構造を確認することができます。

分類学の本などを読んで分類の考え方を学ぶのもいいと思います。

###派生するパターンを網羅するために
今回分類を行うジャンルは「トップス」の下に属するジャンルといえます。
その後、それらの派生を3種類判別することを視野に入れる場合、まずはトップス配下の分類を行い、その後各ジャンルごとの派生の2段階目の分類を行うほうが効率がいいです。
そのため分類を行う対象の体系を捉える必要があります。
別の側面から体系を捉える必要もあるかもしれません。

例外はいくらでもありそうな気がしますがまずは事象を丁寧に観察することが大事だと考えています。