OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerで古いRのバージョンを共存させる

正確には、古いRを要求するツールをRごとコンテナ化した。複数バージョン管理の方法を他に教えていただいたので、そっちも試してみる。environment moduleで切り替えまでやってみる。

# きっかけ

普段はR 3.4.4を使っているのだが、とあるツールを使うときにRのエラーがでた。R 3.1で動作確認してますよってドキュメントに書いてあったのでなんとかして共存させようと試みた。

## Rocker

RockerというR使いのためのDockerを謳うイメージを利用した。Rockerのイメージ群にはr-baseからr-studioまでいろいろあるが、今回はr-verというimageを使ってみた。ここに様々なstable versionのRがいろいろ用意されている。 [rocker-devで使えるバージョン一覧](https://hub.docker.com/r/rocker/r-ver/tags/)

## 実際に試してみた

今回試したのは[vdjtools](https://vdjtools-doc.readthedocs.io/en/master/index.html)というツール。実際のdockerfileは[こちら](https://hub.docker.com/r/yyasumizu/vdjtools/~/dockerfile/)。大雑把なところだけ書く。
### Rocker-verを呼び出す

一行目で宣言する。Rのバージョンもここで指定。

``` docker
FROM rocker/r-ver:3.1
```

### java 8をいれる。

地味にここでつまずいた。特に、r-verはdebian:jessieをデフォルトで使っているため、いつものubuntuと使用感が違ってハマってしまった。なんやかんや調べているとjessieでjavaを入れている人の[dockerfile](https://hub.docker.com/r/re6exp/debian-jessie-oracle-jdk-8/~/dockerfile/)があったので丸コピした。

``` docker
RUN \
    echo "===> add webupd8 repository..."  && \
    echo "deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee /etc/apt/sources.list.d/webupd8team-java.list  && \
    echo "deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main" | tee -a /etc/apt/sources.list.d/webupd8team-java.list  && \
    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EEA14886  && \
    apt-get update


RUN echo "===> install Java"  && \
    echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections  && \
    echo debconf shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections  && \
    DEBIAN_FRONTEND=noninteractive  apt-get install -y --force-yes oracle-java8-installer oracle-java8-set-default


RUN echo "===> clean up..."  && \
    rm -rf /var/cache/oracle-jdk8-installer  && \
    apt-get clean  && \
    rm -rf /var/lib/apt/lists/*
```

### 使い方

WORKDIRをdataにして、シームレスにaliasできるようにしてみた。bashで下を実行。

``` bash
$ docker pull yyasumizu/vdjtools
$ alias vdjtools="docker run -v $PWD:/data yyasumizu/vdjtools vdjtools"
```

dockerのインストールは省略。


# dockerを使わない共存方法

複数バージョンをインストールしておいて、environment modulesで切り替える。environment modulesはubuntu 17.10。

## Rのインストール

異なるバージョンのRを入れるのはめんどくさそうだったが、楽にしてくれるツールを見つけた。[install_R_source](https://github.com/DominikMueller64/install_R_source)

``` bash
$ git clone https://github.com/DominikMueller64/install_R_source.git
$ cd install_R_source
$ ./install_R_source 3.1.1
```

途中でエラーが出たので下の記事でfix。
[stackoverflow : error: --with-readline=yes (default) and headers/libs are not available](https://stackoverflow.com/questions/17473547/error-with-readline-yes-default-and-headers-libs-are-not-available)

``` bash
$ /usr/bin/R-3.1.1
```
を実行して動いたらうまくいっている。

## environment module

すみません、力尽きました。リクエストがあれば後日。頑張ってください。


# 感想
本当は、Annacondaのような便利型バージョン管理ツールを探していた。もっといいやり方があれば教えてください。


## 参考
[R使いのためのDocker「Rocker」を使ってみる(Windows)](https://notchained.hatenablog.com/entry/2014/12/20/151133)
[増え続ける Dockerfile 用の GitHub Repository をなんとかする](https://qiita.com/suecharo/items/a5e0cd3fe6d31443c536)
[Installing multiple versions of R](https://stackoverflow.com/questions/24019503/installing-multiple-versions-of-r)

勝間和代のメルマガの不要な文字列を削除するPythonプログラム

勝間和代さんのサポートメール（http://www.katsumaweb.com/sample.php）を音声読みあげで聞く用に、読みあげに邪魔な部分を削除するプログラムを作りました。

コピーした状態で実行すると、不要な文字列を削除してクリップボードにコピーする、というものです。

```py:SapomeYomiage.py&nbsp;-&nbsp;勝間和代のサポートメールからURLと不要な定型文を除去する。
import pyperclip, re
text = str(pyperclip.paste())
ret0 = re.sub(r"^自分コーチング手帳サポートメール.*?月のバックナンバー", "" ,text, flags=(re.MULTILINE | re.DOTALL))   #文頭の不要文字列を除去
ret1 = re.sub(r"(https?|ftp)(:\/\/[-_\.!~*\'()a-zA-Z0-9;\/?:\@&=\+\$,%#]+)", "" ,ret0)   #URLの除去
ret2 = re.sub(r"(★サポメ会員の勝間塾への新規入会.*?サポートメールのバックナンバーはこちらからお読みいただけます)","",ret1, flags=(re.MULTILINE | re.DOTALL)) #定型文除去
ret3 = re.sub(r"＜＜前週翌週＞＞ .*$","",ret2, flags=(re.MULTILINE | re.DOTALL))
pyperclip.copy(ret3)
```

##苦労したこと
探したい文字列の文頭.*?探したい文字列の末尾
という正規表現にたどり着くのに時間かかりました。
？が非貪欲、という意味になり、最も短くマッチするものを探してくれます。

flags=(re.MULTILINE | re.DOTALL)
という書き方。普通に｜で区切って書いたらなぜかうまくいきませんでした。

なかなか楽しかったです。
SwaggerCodegen + Springでバイナリファイルを返すAPI

# バージョン

- OpenAPI Specification 2.0

- `io.springfox:spring-swagger2`: `2.8.0`
- `io.swagger:swagger-core`: `1.5.18`

# やりたいこと

Jxlsを使用してサーバからExcelファイルをダウンロードするAPIがあるのですが、Jxls出力に必要なデータをMVCのModelクラスにつっこんで、Jxls出力を行うViewを作成して、そこに任せています。（PDFファイルも同じようにViewでやっています）

そのため、Controllerの戻り値としては次のようにStringになるわけです。

```java
@GetMapping("/download")
public String downloadExcel() {
    ...
    return "jxlsView"
}
```

これをそのままSwaggerでAPI生成すると、`/v2/api-docs`は次のような定義になります。

```json
"path": {
    "/download": {
        "get": {
            "response": {
                 200: {
                     ...
                     "schema": {
                         "type": "string"
                     }
                 }
                 ...
```

これだと、Swagger-Codegenで生成されるクライアント用コードも`String`のままになってしまいます。
これをバイナリ用の型（JSの場合は`Blob`）にするには、OpenAPIの仕様にあわせて、つぎのようにする必要があります。

```json
"path": {
    "/download": {
        "get": {
            "response": {
                 200: {
                     ...
                     "schema": {
                         "type": "file"
                     }
                 }
                 ...
```


# どうするか

`@ApiOperation`アノテーションを使用します。
`response`にクラスを指定することで、DTOクラスをスキーマに指定することができますが、ここに`MultipartFile.class`を指定することでバイナリファイルのための定義を得ることができます。

```java
import org.springframework.web.multipart.MultipartFile;

@GetMapping("/download")
@ApiOperation(name = "API名", nickname = "ユニークなAPI名", response = MultipartFile.class)
public String downloadExcel() {
    ...
    return "jxlsView"
}
```


# 補足

OpenAPI Specification 3 だと、バイナリファイルの定義は次のようになります。

```json
"path": {
    "/download": {
        "get": {
            "response": {
                 200: {
                     ...
                     "schema": {
                         "type": "string",
                         "format": "binary"
                     }
                 }
                 ...
```

上記のバージョンでは、SpringfoxのほうがまだOpenAPI3に対応していないようです。

今後、SwaggerCore側とSpringfox側でどのタイミングでOpenAPI3に変化していくのかは、注意が必要そうです。

# 参考

どこにもドキュメント書いてなくて、見つけるのに2日かかりました・・・

https://github.com/springfox/springfox/commit/7b6e78bfb84145a1e387fb50f6383741523f60fc
Google Chromeのキャッシュが保存されている場所

chromeのキャッシュは下記のフォルダに保存されている（Windowsの場合）

```
C:\Users\ユーザー名\AppData\Local\Google\Chrome\User Data
```
chromeでアプリの検証してて
キャッシュ本当に消えてるの？って時に確認する場所として覚えておくと
トラブルの切り分けの際に役に立つかも

参考サイト
https://www.tipsfound.com/chrome/01001
Linux上でダミーファイルを作るコマンド

Linux上でダミーファイルを作るコマンド
```fallocate -l [ファイルサイズ] [ファイル名]```

例）１Gの場合
```fallocate -l 1g dummy.iso```

「f」はファイル
「allocate」は割当
って考えると覚えやすい
Chart.jsをThymeleaf×SpringBootで

#Chart.jsをThymeleafで使う
[Chart.js](https://www.chartjs.org/)をThymeleafで使うおうとした時に、あれ？ってなったのでメモ書き
折れ線グラフにして表示したい値をコントローラーで用意して、ビューで表示するだけのサンプルです。
##コントローラー
ビューに渡す値をModelに格納します。

```Java
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class Chart {
    
	@RequestMapping("/chart")
	// ビュー側にグラフで使う値を渡すためにModelを引数にとっておきます。
    public String hello(Model model) {

		// グラフの横軸と縦軸の値を、それぞれString、int型の配列に格納しておきます。
		
		// 横軸
		// ラベルです。String型の配列に、適当に値を入れておきます。
		String label[] = {"a","b","c","d","e","f","g"};
		
		// 縦軸
		// 具体的な値です。int型で、この値も適当です。
		int point[] = {5,3,7,1,8,3,4,};
		
		// Modelに格納します。ビュー側でグラフ用の配列を受け取れるようにしておきます。
		model.addAttribute("label",label);
		model.addAttribute("point",point);
		
        return "chart";
    }

}
```

##ビュー側
```html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
	<meta charset="UTF-8">
	<script	src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
	<title>折れ線グラフサンプル</title>
</head>
<body>
	<canvas id="ChartDemo"></canvas>
	<script type="text/javascript" th:inline="javascript">
	/*<![CDATA[*/
	var ctx = document.getElementById("ChartDemo").getContext('2d');
	var ChartDemo = new Chart(ctx, {
   		type: 'line',
   		data: {
   			// コントローラーで格納したlabelを変数式で取り出すだけ。
      		labels: /*[[ ${label} ]]*/,
      		datasets: [
      			{
      				label: "Chart-1",
         			borderColor: 'rgb(255, 0, 0)',
         			lineTension: 0,
         			fill: false,
         			// 上記と同様、pointを変数式で取り出しているだけです。
         			data: /*[[ ${point} ]]*/,
         		},
      		]
   		},
   		options: {
      		responsive: true,
      	}
	});
	/*]]>*/
	</script>
</body>
</html>
```

##実行してみた
![chartdemo.jpg](https://qiita-image-store.s3.amazonaws.com/0/196350/d9571a1c-b886-2648-a687-791ac8ac3ed0.jpeg)


##参考
[Thymeleaf version 2.1.4の機能メモ](https://qiita.com/rubytomato@github/items/ac65c2203d16d1a1bbd7)
[Thymeleafチートシート](https://qiita.com/NagaokaKenichi/items/c6d1b76090ef5ef39482)
【Elixir×Phoenix】templateのpageディレクトリにディレクトリ追加してそこのpageを読み込む


```elixir:page_controller.ex
defmodule Practice.PageController do
  use Practice.Web, :controller

  plug :put_layout, "mylayout.html"

  def index(conn, _params) do
    render conn, "mypage/index.html"
  end
end
```

↑↑"mypage/index.html"は普通に書いても読み込まれない。

web\web.exの設定が必要。

```elixir:web.ex
  def view do
    quote do
      use Phoenix.View, root: "web/templates", pattern: "**/*"

      # Import convenience functions from controllers
      import Phoenix.Controller, only: [get_flash: 2, view_module: 1]

      # Use all HTML functionality (forms, tags, etc)
      use Phoenix.HTML

      import Practice.Router.Helpers
      import Practice.ErrorHelpers
      import Practice.Gettext
    end
end
```

```elixir
pattern: "**/*"

```
が必要。

[参考]
How to render a template inside a “web/templates/folder/subfolder”
https://stackoverflow.com/questions/39043777/how-to-render-a-template-inside-a-web-templates-folder-subfolder
pingで実際のネットワークの速度を調べる方法


[デマに騙されちゃダメ。Pingで帯域計測は出来ません！](https://qiita.com/keigo_kabutomori/items/1c290a22550542edeff9#_reference-7d1dc4c08f6133d54058)
↑なので、ブラウザバック推奨です。（注意喚起と戒めのために残しておきます。）


~~コマンド~~
~~ping -l 60000 [サーバ名 or IPアドレス] -t~~

~~[サーバ名 or IPアドレス] からの応答: バイト数 =60000 時間 =XXms TTL=128~~
~~[サーバ名 or IPアドレス] からの応答: バイト数 =60000 時間 =XXms TTL=128~~
~~[サーバ名 or IPアドレス] からの応答: バイト数 =60000 時間 =XXms TTL=128~~
~~[サーバ名 or IPアドレス] からの応答: バイト数 =60000 時間 =XXms TTL=128~~
~~・・・~~
~~・・~~
~~・~~
~~ある程度、流したら「Ctrl + C」で止める~~

~~上記のデータから下記の計算で求める~~
~~[サーバ名 or IPアドレス]  の ping 統計:~~
    ~~パケット数: 送信 = XX、受信 = X、損失 = X (XX% の損失)、~~
~~ラウンド トリップの概算時間 (ミリ秒):~~
    ~~最小 = XXms、最大 = XXms、平均 = XXms~~

~~よって~~
~~帯域 ≒ (60000×2) ÷ [平均ms] × (受信パケット数/送信パケット数)~~

~~例）~~
~~C:\>ping -l 60000 192.168.XX.XX~~
~~192.168.XX.XX に ping を送信しています 60000 バイトのデータ:~~
~~192.168.XX.XX からの応答: バイト数 =60000 時間 =11ms TTL=128~~
~~192.168.XX.XX からの応答: バイト数 =60000 時間 =11ms TTL=128~~
~~192.168.XX.XX からの応答: バイト数 =60000 時間 =11ms TTL=128~~
~~192.168.XX.XX からの応答: バイト数 =60000 時間 =11ms TTL=128~~
~~192.168.XX.XX の ping 統計:~~
    ~~パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、~~
~~ラウンド トリップの概算時間 (ミリ秒):~~
    ~~最小 = 11ms、最大 = 11ms、平均 = 11ms~~

~~サイズ60000bytesのパケットを送信し、~~
~~平均応答時間は11msであった。~~
~~これから計算されるネットワークの帯域は次のようになる~~

~~帯域 ≒ (60000×2) ÷ 11ms/1000 ≒ 10.9[Mbytes/s]~~


~~参考にしたサイト~~
~~http://www.atmarkit.co.jp/ait/articles/0511/26/news012.html~~
ディスクの「BitLocker暗号化を有効にする」設定方法＠Windows10

外出先でPCを落としてしまった時や忘れてしまったときの為に
PCのディスクを暗号化しておく必要がある

Windows10では標準でBitLockerというアプリが入っており、
これで暗号化が可能だ

しかしいざ暗号化しようとすると。。。

「コントロールパネル」から「BitLockerドライブ暗号化」にて「BitLockerを有効にする」をクリックすると
下記のエラーメッセージが表示される場合がある。
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/105d1f45-efef-2ace-1db6-d084b099657d.png" width=70%>
 
トラスデッドプラットフォームモジュール(TPM：Trusted Platform Module)
TCG（Trusted Computing Group）で定義されたセキュリティの仕様に準拠したセキュリティチップ（TPM：Trusted Platform Module）
OSや他のハードウェアから独立して機能するため、
外部からの攻撃にも強く、
従来はHDD/SSD/フラッシュメモリに格納していた認証に用いる暗号キーなどの情報を安全に格納・管理することが可能です。
TPMのモードには1.2と2.0があり、数値からわかる通り2.0の方が新しく、より強化されているらしい。
 
#1.グループポリシー(gpedit.msc)を起動する
Windows検索ボックスにて「gpedit.msc」と入力し起動します。
「コンピューターの構成」＞「管理用テンプレート」＞「Windowsコンポーネント」＞「BitLockerドライブ暗号化」
「オペレーティングシステムのドライブ」 ＞ 「スタートアップ時に追加の承認を要求する」
表示されたウィンドウにて、以下の「有効」にチェックを入れます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/87db1b64-19ea-4165-10be-e5de6d1e731a.png" width=70%>
Windows10 BitlockerとTPM

#2.グループポリシー(gpedit.msc)を更新する
Windows検索ボックスにて「gpupdate.exe /force」と入力します。
 
#3.「コントロールパネル」から「BitLockerドライブ暗号化」にて「BitLockerを有効にする」をクリックすると
下記の画面が表示されます。
パスワードを入力
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/e2a9b2bd-9bed-cfc5-e1e7-69c7a5b5148b.png" width=70%>
今回はファイルに保存するを選択（ファイルの中身はテキストファイルなのでもしもの時に復号できるように保存しておく）
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/fcb24a3b-6c3e-6a4f-c9cb-da89c18d72cc.png" width=70%>

#4.ドライブ全体を暗号化を選択
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/a273c831-d66c-e519-b2e2-28afac9b4288.png" width=70%>

#5.使用する暗号化モードを選択 →「新しい暗号化モードを選択」
<img src="https://qiita-image-store.s3.amazonaws.com/0/265300/38f2fc56-1792-42f9-064e-18700fb5402a.png" width=70%>

#6.再起動で完了
インスールしたてのWindows Server 2012R2に「Visual Studio 2015 の Visual C++」するとインストール失敗する

インスールしたてのWindows Server 2012R2に
「Visual Studio 2015 の Visual C++」するとインストール失敗する

原因はWindowsUpdateを行っていない事が原因のようだが、
検証環境の構築等で

**WindowsUpdateを一から全てインストールする時間がない！**

という場合は
特定のWindowsUpdateだけを手動でインストールする事で
「Visual Studio 2015 の Visual C++」をインストール可能にします。
 
手順は下記の通り

##1.Windows8.1-KB2919442-x64.msuを実行する
（下記のURLよりダウンロード）
https://www.microsoft.com/en-us/download/details.aspx?id=42153

##2.KB2919355をアンインストールする
管理者プロンプトから「dism /online /remove-package /packagename:Package_for_KB2919355~31bf3856ad364e35~amd64~~6.3.1.14」を実行する

##3.StartComponentCleanup タスクによる、不要な更新プログラムの削除を実行する
管理者プロンプトから「dism /online /cleanup-image /startcomponentcleanup」を実行する

##4.Windows8.1-KB2919355-x64.msuを実行する
（下記のURLよりダウンロード）
https://www.microsoft.com/en-us/download/details.aspx?id=42334

##5.Windows8.1-KB2999226-x64.msuを実行する
（下記のURLよりダウンロード）
https://www.microsoft.com/ja-JP/download/details.aspx?id=49063

##6.Windows8.1-KB3118401-x64.msuを実行する
（下記のURLよりダウンロード）
https://www.microsoft.com/en-us/download/details.aspx?id=51171

##7.vc_redist.x64.exeを実行する
（下記のURLよりダウンロード）
https://www.microsoft.com/ja-jp/download/details.aspx?id=48145
 

以上で終了。

Apache 2.4の実行に「Visual Studio 2015 の Visual C++」が必要となる為、
インストールしようとしたが、失敗した為、上記の方法で解消
Apache 2.4の起動まで確認済
ウィルスバスターを最新版にするときの留意事項

どのパッチを当ててよいかサイトを見ただけはわからないので
ウィルスバスターのパッチの考え方を記載
 
Critical Patch→個別修正
Service Pack→いくつかの修正がまとまったもの
 
なので基本的には最新のService Packと
Service Packのリリース日以降の各Critical Patchを全て適用すればいい
 
ただしCritical Patchが過去の修正を含んでいる場合もある為、
全て適用する必要もない事もある
→その場合はCritical Patchのページに下記のような記載がある
例：「Critical Patch（ビルド6396)には、Critical Patch（ビルド6325)に含まれていた修正も含まれていますので、Critical Patch（ビルド6396)の適用をご検討ください。」
 
また、
各Critical Patch、Service Packには
リパック版というのがあり、内容に問題があって差し替えた後のVerの事
1回リパックの場合はファイル名の後ろがr1となる
2回リパックしている場合はファイル名の後ろがr2となっている。
Apache2.4インストール手順@Windows Server2012R2

#1.下記URLから最新版をダウンロード
　https://www.apachelounge.com/download/
　今回は Apache 2.4.29 Win64 をダウンロード

#2.ZIPファイルを展開し、Apache24のフォルダを任意の場所へ格納
　例：「C:\Apache24」※Cドライブ直下へ格納
 
#3.「C:\Apache24\conf\http.conf」を修正する
　　フォルダのパスを変更
　　37行目：ServerRoot "c:/Apache24"
　　246行目：DocumentRoot "c:/Apache24/htdocs"
　　247行目：＜Directory "c:/Apache24/htdocs">
　　364行目：ScriptAlias /cgi-bin/ "c:/Apache24/cgi-bin/"
　　379行目：＜Directory "c:/Apache24/cgi-bin">
　　上記のファイルパスをApache24のフォルダを格納した場所に変更
　　今回の例では変更不要
　 ポート番号を設定する
　　60行目：Listen 80
　　使用するポート番号はデフォルトで80番となっているので
　　通常はこれで問題ないですが、
　　既に他のアプリケーションで使用していると分かっている場合には変更要

#4.Apacheをサービスとして登録
　コマンドプロンプトからプログラムが配置されている
　ディレクトリに移動し「httpd -k install」を実行
　「サービス」の画面を確認してみると
　「Apache2.4」というサービスが追加されている
 
#5.Apacheをサービス一覧から起動
　ブラウザを立ち上げ「http://localhost/ 」
へアクセス
　次のように表示されればApacheは正常に起動している
　「It works!」



[インスールの際に参考したサイト](https://www.adminweb.jp/apache/)
[OpenFOAM+ on Rescale w/Azure] ハンズ・オン @Microsoft

Sep 27th, 2017


Rescale の実験計画法を使いパラメータスタディー機能を体験しよう
======================================================

[公式ページ](https://resources.rescale.com/articles/run-a-doe-job/)の情報を元に本ハンズオンは作成されています。
差分として、本ハンズオンはCD値を抽出するポスト処理がパラメータスタディーのワークフローにつけ加えられています。

[セミナー資料](https://www.slideshare.net/RescaleJapan/microsoft-seminar-design-optimization-on-rescale)はこちらです。
このハンズオンは、本資料後半のOpenFOAMのパラメータスタディーの例とほぼ同じです。


計算実行方法
-------------------

- [STEP0: ジョブの作成と実験計画法の選択][STEP0]
- [STEP1: 入力ファイルのアップロード][STEP1]
- [STEP2: 並列設定(パラメータリストの定義)][STEP2]
- [STEP3: テンプレートの設定][STEP3]
- [STEP4: ソフトウェアの設定][STEP4]
- [STEP5: ハードウェアの設定][STEP5]
- [STEP6: ポストプロセッシング][STEP6]
- [STEP7: 計算の実行][STEP7]



[STEP0]:https://qiita.com/daikumatan/private/034dd94575e3d1711a2e
[STEP1]:https://qiita.com/daikumatan/private/0844e60b1ddb5b730c6c
[STEP2]:https://qiita.com/daikumatan/private/957862295aa4782abdb8
[STEP3]:https://qiita.com/daikumatan/private/45bff5a4a172b8db24c6
[STEP4]:https://qiita.com/daikumatan/private/dcdf99c91aff57004db6
[STEP5]:https://qiita.com/daikumatan/private/e15f7d3a54b53ff482af
[STEP6]:https://qiita.com/daikumatan/private/174002a725eef5fc444c
[STEP7]:https://qiita.com/daikumatan/private/27d948f13cf8a3b0c48a


計算結果確認
-------------------

- [計算結果の確認: 3Dグラフを作成する][result1]
- [計算結果の確認: ある特定のファイルを確認/Downloadする][result2]

[result1]: https://qiita.com/daikumatan/private/38e80cab14170f299a23
[result2]: https://qiita.com/daikumatan/private/4505c27c2a0451d65e58


データのインポート
-----------------

このハンズオンで行ったジョブを[インポート](https://platform.rescale.jp/jobs/BXxKo/)可能です。

- https://platform.rescale.jp/jobs/BXxKo/

ジョブをクローンして保存することで、インプットファイルをすべてユーザ権限でハンドリングができるようになります。
TensorFlowをWindows10にインストール

#インストールするもの
Anaconda3
TensorFlow with CPU support only（CPU版）

#実行環境
Windows10 64bit



#手順
以下のサイトを参考にしました
https://www.tensorflow.org/install/install_windows (公式)
https://www.sejuku.net/blog/43784

1. ANACONDAのインストール
Anaconda(Python3.6) https://www.anaconda.com/download/

2. AnacondaでTensorFlowのインストール場所を作成
(https://www.sejuku.net/blog/43784 を参考に)

3. TensorFlowのインストール
コマンド

```:コマンド
pip install --upgrade tensorflow
```

参考サイトではオプションが`-upgrade`となっていましたが、私の環境ではできませんでした。
4. TensorFlowがインストールされていることを確認
VMwareの仮想マシンでスナップショット を作成するときにファイルサイズが大きくならないようにするために

業務都合上、スナップショットを大量に保持しておかなければならず、
その度にディスクを圧迫する始末

どうにかならないものかと知り合いのインフラ屋に相談した所
VMのスナップショットってゆーのは「パッチを当てたり、バージョンアップさせたりする前の切戻しの為に作成する事を想定しているから、ポコポコ作成するもんじゃないよ」って言われました。

でも現状はどうしようもなく、どうにかならないか？と相談した所、
**「スナップショットはマシンの差分情報を保持して大きくなるんだよ」**っと教えられました。
どーいう事かというと
**「ファイルを格納する→削除する→スナップショットを取る」**という手順は**逆にスナップショットのサイズを大きくする！**という事
なので
**「ファイルを格納する→スナップショットを取る」**の方がスナップショットの**サイズが小さくて済む**らしい

実証はまた時間の空いた時に行いますが、
予備知識としては中々のものだと思いました。
Jacksonで一部のプロパティをJSON文字列のまま取得したい！

## 1. はじめに

Jacksonで簡単に`Json文字列 -> Javaオブジェクト`の変換処理（デシリアライズ）ができるのですが、どうしても一部のプロパティをJSON文字列のまま取得したい要件が発生しました。

何でも入る魔法のプロパティ（ここでは仮にpayloadとする）があって、別のプロパティに定義されているデータ型（FQCN）で復元したいというのが目的です。

JacksonにはJSON文字列を文字列のまま扱う`@JsonValue`がありますが、これはシリアライズの場合のみ有効なものです。残念ながらデシリアライズの場合は対象外です。

対処方法は独自の`JsonDeserializer`を実装して、`@JsonDeserialize`で個別にデシリアライズ処理を指定することです。といっても目的が「JSON文字列のまま取得したい」なので`JsonDeserializer`の実装は非常に簡単です。

## 2. ソースコード

```java:JsonRawValueDeserializer.java
package com.example.jacksondemo;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

// ★ポイント１
public class JsonRawValueDeserializer extends JsonDeserializer<String> {

    // ★ポイント２
    @Override
    public String deserialize(JsonParser parser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        return parser.readValueAsTree().toString();
    }
}
```

```java:MyModel.java
package com.example.jacksondemo;

import java.io.Serializable;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class MyModel implements Serializable {

    private static final long serialVersionUID = 1L;

    // ★ポイント３
    // I want json raw text!
    @JsonDeserialize(using = JsonRawValueDeserializer.class)
    private String payload;
    
    // these property are auto mapped by jackson (without special operation)
    private String fqcn;
    private Integer priority;
    private String messageId;

    // constructor, setter, getter omitted
}
```


**★ポイント１**
`com.fasterxml.jackson.databind.JsonDeserializer`クラスを継承し、独自の`JsonDeserializer`を定義します。
型パラメータにはデシリアライズの処理結果の型、つまり今回は`String`を指定します。

**★ポイント２**
`deserialize`メソッドをオーバーライドしてJSON文字列を返すように実装します。

**★ポイント３**
JSONをマッピングするJavaクラスにおいて、JSON文字列のまま値をマッピングしたいプロパティに`@JsonDeserialize`アノテーションを付与します。
`using`属性に★ポイント１で実装した独自の`JsonDeserializer`を指定します。

これでJSONの`payload`プロパティがオブジェクトになっていても、そのJSON文字列がそのままStringの`payload`プロパティに格納されます。
今回の目的を実現するには`dqcn`プロパティを見てデータ型を特定した後、`payload`プロパティのStringの値を目的のデータ型でデシリアライズしてあげればOKです。

## 3. さいごに

今回はJacksonのデシリアライズで一部のプロパティをJSON文字列のまま取得する方法について説明しました。
JacksonにはJsonを木構造のデータで読み込む`JsonNode`という機能がありますが、JsonとJavaをマッピングする使い方が多いかと思います。その際、特定のプロパティだけはJsonのままで、という事態になった場合は今回の使い方を試してみてください。
trans-loader: node/webpack なしではじめるフロントエンドプロジェクト

フロントエンドはツールチェイン多くて大変ですね。何から初めていいかわからないと思います。

というわけで、 babel や webpack, というかもはや node の インストールすら不要でフロントエンドを始めることができるプロジェクトを作りました。

https://github.com/mizchi/frontend-starter

```
git clone git@github.com:mizchi/frontend-starter.git --depth 1 --single-branch master
cd frontend-starter
ruby -run -e httpd . -p 8000 # 好きな静的サーバー
```

あとはブラウザで http://localhost:8000 を開くだけ。

デフォルトだとシンプルな React プロジェクトになっています。vue でもなんでも多分大丈夫。

試しに編集して動くか確認してみましょう。

```js:components/App.js
import React from "react";
export default () => <span>This is App component</span>;
```

`This is App` を何か書き換えてリロードしてみてください。適用されるはずです。

最後に一つ注意。**裏側はとても富豪的に動いているので、本番環境では使わないでください**

ここで動くコードはちょっと微調整を加えると webpack でビルドできます。 ご近所の webpack 職人を呼びつけください。

## 裏側の実装の話。

最近のモダンブラウザでは Native ES Modules が実行可能になっています。基本的にはこれを使っています。なのでモダンブラウザ限定です。

ただし、Native ESM を実用しようとすると、いくつか問題があります。

- dependecy が深い時に解決が遅い。モジュール解決のN+1問題。
- node のモジュールシステムとパス解決の解釈が違うので、そのままでは動かない
- そのままでは JSX の構文が通らない。

といった事情で、現時点でもWebpackでビルドするのが最適だとGoogleも推奨しています。
[Introduction  |  Web Fundamentals  |  Google Developers](https://developers.google.com/web/fundamentals/performance/webpack/)

これらの問題を解決するには、サーバーサイドプッシュなどのいくつかのWeb標準の問題を解決する必要があり、現時点では npm エコシステムのものをビルド無しで解決するのは現実的ではありません。


とはいえ、開発環境用だと割り切れば、色々とやりようがあります。そのための専用のServiceWorkerを作りました。

https://github.com/mizchi/trans-loader

これが何をしているかというと、

- Service Worker がフルコントロールになるまで読み込みを待機する
- js読み込み時、専用の Babel プラグインで module path を書き換える
- https://jspm.io を経由して、 npm の module をESMにコンパイルして解決
- dev.jspm.io からのリクエストを service-worker でキャッシュ
- .js の flow/react 拡張を transform
- .ts の TypeScript transform

つまりは、ServiceWorker Side Transform です。

こんなJSの初期化を

```html
<script src="/main.js"></script>
```

`wget https://raw.githubusercontent.com/mizchi/trans-loader/master/dist/sw.js` で trans-loader の sw.js をダウンロードして、こんな風に書き換えると適用できます。

```html
<script type=module>
(async () => {
  const run = () => import('/main.js') // your entry js
  if (navigator.serviceWorker.controller) {
    run()
  } else {
    const reg = await navigator.serviceWorker.register("/sw.js");
    await navigator.serviceWorker.ready;
    navigator.serviceWorker.addEventListener('controllerchange', run)
  }
})()
</script>
```

このとき、 `sw.js` は必ずドメインのルート直下に置く必要があります。自分より下位のパスにしかコントロールが持てないという serviec-worker の仕様上の制限です。ホスティングせず、わざわざダウンロードしてるのも、そのため。

要は service-worker を経由して読み込むときに、babel でモジュールパスを書き換えて無理矢理辻褄を合わせています。これによって webpack の特殊なローダー以外はほとんど挙動を再現できます。

結果として、 trans-loader の ServiceWorker が Babel コンパイラと TypeScript コンパイラを同梱することになり、uglifyjs でビルドしても 3MB になりました。一回読み込めばcache に入りますが、ブラウザキャッシュなので初回は必ず jspm.io にアクセスが飛んでしまうことも考えると、プロダクションでの使用は現実的ではありません。たぶん jspm.io に怒られると思います。

## 未来

webpack 批判も多いですが、IE11が死ぬ未来では本来こういうことができる、という紹介でした。 webpack の高度な loader は再現できませんが、学習環境、テスト環境ではこれぐらいで大丈夫ではないでしょうか。

ついでにフロントエンドの人間がなぜIE11を恨んでいるかなどを察していただければ幸いです
Windows Updateしたら Windows Serverにリモートデスクトップで接続できなくなった！

# リモートデスクトップで接続できなくなった！
昨日までリモートデスクトップに接続できていたのが、
今日から突然接続できなくなった。
変化点は昨日の夜にwindowsupdateが実行されていた事

# 要求された関数はサポートされていません
接続時に下記のようなエラーが表示される
＝＝＝＝＝＝＝＝＝＝
認証エラーが発生しました。
要求された関数はサポートされていません
 
リモートコンピュータ:<接続先のホスト名>
原因はCredSSP暗号化オラクル修復である可能性があります。
詳細については、https://go.microsoft.com/fwlink/?linkid=866660を参照してください
＝＝＝＝＝＝＝＝＝＝

# 調べてみた
以下の2つの条件が合致した場合に本現象が発生するらしい
・サーバーに2018年3月のWindowsUpdate更新プログラムが適用されていない
・クライアントPCが2018年5月のWindowsUpdate更新プログラムが適用されている

https://blogs.technet.microsoft.com/askcorejp/2018/05/02/2018-05-rollup-credssp-rdp/

# 対応は？
クライアント側のwindowsupdateは避けられないと思うので、対応策としてはリモートサーバー側のwindowsupdateしかないのか。。。

でもなく
クラアントPCにて下記の手順で回避可能（※クライアントPCのポリシーを変更するので以下自己責任でお願いします）

1. 「Windowsキー」と「Ｒキー」を同時押しして
   「ファイル名を指定して実行」を起動

2. 「名前」欄に「gpedit.msc」と入力し、
   「ＯＫ」をクリックして
   「ローカルグループポリシーエディター」を起動

3. 以下のパスを開く
　　　[コンピューターの構成]
　　　　-> [管理用テンプレート]
　　　　　-> [システム]
　　　　　　-> [資格情報の委任]

4. 設定一覧から「Encryption Oracle Remediation」を右クリックで選択し、
  「編集」をクリック

5. チェックボタンを「未構成」から「有効」に変更

6. 「Protection Level」が選択できるので、
　 「Vulnerable」を選択し、「ＯＫ」をクリック
Atcorderでの気づき、sortについて python

B - Two Anagramsという問題について

・問題の概要
アルファベットが与えられる(例：A="sdf" , B="sdfg")
もし「A」の文字列に含まれる一番アルファベット順で小さいもの(アルファベットはa → zで大きくなる)
この場合だと"d"が　
Bの文字列に含まれる一番アルファベット順で大きいもの、
この場合"s"
よりも　大きい場合　"No"　小さい場合は"Yes"と 表示させる問題。


<やり方>
A="dfs"　(小さい順に並び替える)
B= "sgfd"(大きい順に並び替える)
それぞれを比較して、もしBの方がアルファベットの並びが大きければ'Yes'と表示それ以外は'No'と表示させる。

<つまづいた点>
for文を使用してsortをしようとしていたが、pythonではsorted関数があることを発見。
無事に問題は解けたが、for文を利用してsortを実行する方法についてはまだできていないため、これから勉強する。

<問題URL>
https://beta.atcoder.jp/contests/abc082/tasks/abc082_b
GLSLで音楽（和音を使ってみる）

#和音をどう扱うのか
しばらく音楽理論と格闘して、シンプルなとこ見つけた。sus4とかセブンスを使わないでオーソドックスなところで行くなら、文字数使わずに書けそうです。
キーをC3、ノート番号でいうと60にします。ピアノの白鍵だけがメジャースケールになります。このスケールをこう書きます。

```
#define Scale 60+int[](0,2,4,5,7,9,11,12,14,16,17) 
//例えばドなら
int do = (Scale[0]);
//例えばミなら
int mi = (Scale[2]);
//例えばソなら
int so = (Scale[4]);

```
メジャーコードとかマイナーコードとかあるけど、スケール使っての和音なら,スケールのインデックスをaとした場合

```
(Scale[a])
(Scale[a+2])
(Scale[a+4])
```
この組み合わせが和音になります。この仕組みを使います。
Iはa=0
IImはa=1
IIImはa=2
IVはa=3
Vはa=3
VImはa=5
VIIm_5はa=6
でいけます。
これを踏まえた上でサンプルを書きます。コード進行は王道進行(Ⅳ→Ⅴ→Ⅲm→Ⅵm)を使ってみます

```glsl
#define BPM 120.
#define A (15./BPM)
#define B (240./BPM)

float distortion(float gain, float d)
{
    return clamp(gain * d, -1.0, 1.0);
}

float sound(float f, float time)
{
    return distortion(sin(6.2831*f*time), 2.5) *exp(-time*3.0);
}

float note2freq(int n)
{
    return 440.0*exp2((float(n)-69.0)/12.0);
}

#define Scale 60+int[](0,2,4,5,7,9,11,12,14,16,17) 

float chord(int a, float time)
{
    return (
        sound(note2freq(Scale[a]), time) +
    	sound(note2freq(Scale[a + 2]), time) +
    	sound(note2freq(Scale[a + 4]), time) 
        )/3.0;
}

float sequenceTime(int s,float time)
{
  float n =mod(time,A);
  for(int i=0;i<16;i++){
    if((s>>(int(time/A)-i)%16&1)==1)break;
    n+=A;
  }
  return n;
}

vec2 mainSound( float time)
{
    int n = int[](4,5,3,6)[int(time/B)%4]-1;
    return vec2(chord(n, sequenceTime(0x0101, time)));
}

```
この音は[shader toy](https://www.shadertoy.com/view/MdGfWG)で聞けます。

#ベースについて
ベースラインはコードのルート音を弾くのが基本らしいので、この応用も利きそうです。

#GLSLで音楽の記事
[GLSLで音楽（はじめに）](https://qiita.com/gaziya5/items/e5d058c20bc75c72b5a2)
[GLSLで音楽（まずは、ドラムだ）](https://qiita.com/gaziya5/items/e58f8c1fce3f3f227ca7)
[GLSLで音楽（メロディーいってみます）](https://qiita.com/gaziya5/items/67ebe54f4bc02bd31bd4)
[GLSLで音楽（今までの応用の一つ）](https://qiita.com/gaziya5/items/27ba6dedfc3028782f2f)
Condaで入れたSpacyでモデルをダウンロードしようとすると吐かれるエラー 'spacy' is a package and cannot be directly executed を解決する

##環境
Python 3.6.5 |Anaconda, Inc.
spacy=2.0.11

##問題

Spacyの英語のモデルを使いたかった

```bash
conda install spacy
python -m spacy download en
```

しかし

```bash
/path_to_anaconda/bin/python: No module named spacy.__main__; 'spacy' is a package and cannot be directly executed

```

なんとspacyはパッケージだから直接実行できないと。

##解決方法

condaを諦めてpipでインストールする。

```bash
pip install spacy
```

環境はAnacondaベースのためpip使って大丈夫だろうかと思いましたが、最早やむなし。動くことが大事。
[condaとpip：混ぜるな危険](http://onoz000.hatenablog.com/entry/2018/02/11/142347)

##やったこと

###1. condaでインストールしたSpacyとさよなら
```bash
conda uninstall spacy
```

###2. pipでSpacyを入れるために入れたり消したり

```bash
distributed 1.21.8 requires msgpack, which is not installed.

pip install msgpack
```

```bash
Cannot uninstall 'preshed'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

conda uninstall preshed
```

```bash
Cannot uninstall 'murmurhash'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

conda uninstall murmurhash
```

###3. pipでSpacyをインストール


```bash
pip install spacy
python -m spacy download en
```

```bash
python
>>> import spacy
>>> spacy.load('en')
<spacy.lang.en.English object at 0x7f9609368eb8>
```
PythonとwxpythonライブラリをUSBにインストールする

pythonのインストールをしてみました。
今回はUSBにインストールしておき、自宅と仕事先など複数のPCで開発できるようにしてみました。
備忘録として記事にしておきます。

#作業環境
Windows10(64bit)
Python3.6.5 0OQt5

#Pythonのダウンロードとインストール

##ダウンロードサイト
https://sourceforge.net/projects/winpython/

##参考サイト
ダウンロードとインストールの詳細についてはこちらのサイトに詳しく載っています。
【Windows10】WinPythonをインストール
https://algorithm.joho.info/programming/python/winpython-install-windows10/

###備考
インストールに必要な容量が1.9GBでした。最初、USBの空き容量が足りずインストールできなかったので、別のUSBを使いました。
インストールに思った以上に結構時間がかかりました。

#ライブラリの追加
参考にした記事はまとめて後述します。
##コマンドプロンプトから実行すればいいはずが。

コマンドプロンプトから

```console

pip install wxpython

```

を実行すればいいとのこと。

##カレントディレクトリを切り替える。
インストール先のUSB（ドライブE）にカレントをインストール先ディレクトリに変えてます。

```console

cd e:\

```

では切り替えられず、オプションをつけて、

```console

cd /d e:\

```

で移動できました。

##pipを動かしたい

ところが今度はpipが動かない。
そこで、下記サイト②を参考にパスを通しました。

```console

E:\WinPython\python-3.6.5.amd64\
E:\WinPython\python-3.6.5.amd64\Scripts

```
が、うまくいかない？！
カレントディレクトリを
E:\WinPython\python-3.6.5.amd64\Scripts

にして実行しても

```console

e:\WinPython\python-3.6.5.amd64\Scripts>pip install wxpython
Fatal error in launcher: Unable to create process using '"'
```

とでました。困った。
そして探すと、まさにそのまんまな記事を発見しました。（参考記事④）


##結局

```console

E:\WinPython\python-3.6.5.amd64>python -m pip install wxpython

```

でひとまずインストールは出来ました！

##参考サイト
①ライブラリのインストールについてはこちらのサイトを参考にしました。
http://caro.blog.so-net.ne.jp/2017-05-15

②windows10でpipが使えるようになるまで(python3.6)
https://qiita.com/huushihi/items/c7f578bf51c0017c9076

③Windows10で環境変数（システム環境変数、ユーザ環境変数）を追加
http://www.wannko.net/windows10/etc/kankyo.html

④Fatal error in launcher: Unable to create process using '"'を何とかする
https://qiita.com/Hibikine_Kage/items/3feffdf467c6ac5bd43b


#感想
PythonはRaspberryPi上などでも動かしてみたい言語でしたので、今回勉強を始められて良かったです。
kotlinでandroid入門 状態の確認

入門者が調べたことを、同レベルの人の参考になればと説明
自分が整理用に作った[コード](https://github.com/bokufolivora/hinagata)をもとにしてます

### 地域(ロケール）

#### 端末設定の取得
端末に設定してある地域情報を得るのは,Locale を使います

```
    // ロケールの取得
    val locale = Locale.getDefault()
    val language = locale.getLanguage()
    val country = locale.getCountry()
    Log.d("County", country)
    return if (language == "ja") {
        "日本"
    } else if (language == "en") {
        "英語"
    } else {
        "他"
    }
```

#### 日本時の切替
また、メッセージを日本とそのほかに変えるのは strings.xml　を使うと簡単にできます
普通に android studioでプロジェクトを作ると res\values\strings.xml が作られ
この文字を使いますが。
res\values-ja\strings.xml を作り、同じキーに日本語を設定しておけば、実行時に端末の設定が日本の場合 values-ja が使われ、それ以外の場合以前のまま values のが使われます.
プロジェクト内で使用する文字列はここに宣言しておくと、getString(R.string.key_xxx) とすると文字列として使えるので、修正忘れとかを防止できます

### ネットワーク状況の確認
#### ネットワークに繋がっているか

ネットワークに接続しているかの確認

```
    val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = connMgr.activeNetworkInfo
    if ( networkInfo != null && networkInfo.isConnected ) {
        // 接続中
    }
```
wifiも含めてネットワークに繋がっているかの確認みたいです

#### Wifiか？

なので,wifiかはもう１回確認が必要

```
    val connMgr = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val networkInfo = connMgr.activeNetworkInfo
    if ( networkInfo != null && networkInfo.isConnected
                && networkInfo.type == ConnectivityManager.TYPE_WIFI) {
        // Wifiか？
   }
```

エミュレータでの確認なので、ちょっと自信ないです。
すいません
【slick】画像の右半分をクリックすると次の画像、左半分だと前の画像にスライドするスライドショーをお手軽に作る

## 前置き
今回はカルーセルライブラリslickを用いて実装して行くので、１から実装したい方には向かない記事になっています。

slick: スライダーで実現したい大体の機能は兼ね備えていて、それを直感的に設定できる優秀なライブラリ。
公式はこちら:http://kenwheeler.github.io/slick/


導入段階は今回書きませんがこのあたりの記事が参考になります。
http://uzurea.net/explanation-of-jquery-slider-slick/

さて、本題です。
デフォルトではslickによるスライダーは、左右矢印のクリックおよびドラッグによるスライドで画像を切り替えられます。これはもちろん優秀な機能なのですが、

「左右矢印のクリック判定を、画像そのものの右半分、左半分に割り振って、それぞれをクリックするとスライドする」
という機能にするには少々手を加える必要がありました。

<img width="681" alt="スクリーンショット 2018-06-28 20.24.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/255971/cc17e2f4-a393-411d-6cbb-061f76554ac3.png">

こんなかんじ。

## クリック判定の実装

矢印の要素そのものの領域を広げれば、何も書かなくてもクリック判定ができる。
矢印要素のコードを検証ツールで見てみるとこんなかんじになっている。

<img width="796" alt="スクリーンショット 2018-06-28 20.38.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/255971/2d46d346-ba9d-c1bb-651f-40e64c298c32.png">

このbutton要素の領域をcssで調整して、before要素である矢印マークの位置をいい感じにしてあげればよさそうだ。
画像の右半分、左半分に領域を設定するのは、親要素の幅の50%に指定することでいけそうだ。

```css:slick-theme.css
.slick-prev {
  height: 100%;
  width: 50%;
  left: 0;  /*幅を画像の50%にして左寄せ*/
}
.slick-prev:before {
    position: absolute;
    left: 8px; /*何もしないと要素の中央になってしまうので位置調整*/
    content: '◀︎';
}
.slick-next {
  height: 100%;
  width: 50%;
  right: 0;  /*幅を画像の50%にして右寄せ*/
}
.slick-next:before {
    position: absolute;
    right: 8px; /*何もしないと要素の中央になってしまうので位置調整*/
    content: '▶︎';
}
```

これで、画像の右半分をクリックすれば次の画像に、左半分をクリックすると前の画像に遷移するようになった。

## その操作ができるよ！ってユーザーに伝える

根幹機能の実装自体はすぐできましたが、ここからが意外とつまづきました。

上記で実装した機能が使えることをユーザーに伝えるために、
「画像のそれぞれ半分にマウスが乗った時に矢印アイコンを目立たせる」

という実装をしてみます。

通常、これをやるにはJSでクリック判定した要素を取得して、矢印アイコンの要素のcssを変更するというごくシンプルな方法でできます。
しかし今回の場合、cssに変更を加えるのはbefore要素、つまり擬似要素。
擬似要素は非DOMなので、普通にJSで操作しようとしてもうまくいかないんでした。

一応擬似要素を動的にいじる方法はあるようで、今回の場合この記事
　http://ithat.me/2015/11/30/jquery-css-pseudo-before-after-change　
の２番目にある、無理やりhead要素にstyleタグを追加して書き換える方法が取れそうでしたが、それをやらずとも一応なんとかなりました。

before要素の元要素となるbutton要素自体のopacityを動的に変えることで、before要素の矢印も見え方が変わるようにしました。

```js:slick-option.js
$(function() {
  $('.slick-prev').on('mouseenter', function(){
    $(this).css('opacity', '1');
  });
  $('.slick-prev').on('mouseleave', function(){
    $(this).css('opacity', '.5');
  });
  $('.slick-next').on('mouseenter', function(){
    $(this).css('opacity', '1');
  });
  $('.slick-next').on('mouseleave', function(){
    $(this).css('opacity', '.5');
  });
})
```
これで、マウスが離れているときは半透明50%、マウスが乗った時は不透明になる変化にできました。

ただしこの方法は今回のように元要素が透明な場合などcssをいじっても影響がない時にしか使えないので、大体のケースは上にある擬似要素を動的にいじる方法でやるべきかと思います。

## もっといい方法があれば、教えてください。
エンジニア歴３ヶ月です。コメント待ってます。
【メモ】代表的な機械学習手法（数式）

# 元ネタ
https://qiita.com/tomomoto/items/b3fd1ec7f9b68ab6dfe2
機械学習を数学で理解したいので頭の整理として，お勉強のメモとして重要な式だけまとめていきます．

# 手法
## 回帰
### 線形回帰
#### 最小二乗法　　

当てはめたい関数： $ f(x) = ax+b $
一般形：$ f(x) = \boldsymbol{w}^T\boldsymbol{x} $　※切片含む
最小化したい評価関数： $ J = \sum_{i=1}^{n}(y_i - f(x_i))^2 $
計算方法：

```math
a = \frac{n\sum_{k=1}^{n}x_ky_k-\sum_{k=1}^{n}x_k\sum_{k=1}^{n}y_k}{n\sum_{k=1}^{n}x^2_k-(\sum_{k=1}^nx_k)^2}
```

```math
b = \frac{\sum_{k=1}^nx^2_k\sum_{k=1}^ny_k-\sum_{k=1}^{n}x_ky_k\sum_{k=1}^{n}x_k}{n\sum_{k=1}^{n}x^2_k-(\sum_{k=1}^nx_k)^2}
```
多次元も同様な考え．
参考文献：
https://qiita.com/Ushio/items/0411b0db1ed36d398bbf
https://ja.wikipedia.org/wiki/%E6%9C%80%E5%B0%8F%E4%BA%8C%E4%B9%97%E6%B3%95
https://mathtrain.jp/leastsquares


#### 最尤推定
最尤推定とは：$ \frac{\partial}{\partial x} \log {L(\boldsymbol{w})} = 0 $

最大化したい尤度関数：

```math  
L(\boldsymbol{w}) = \prod_{i=1}^n \frac{1}{\sqrt{2\pi\sigma^2}} \exp(-\frac{(y_i - f(x_i))^2}{2\sigma^2})
```

### ロジスティック回帰
予測モデルをロジスティック関数を使って作成
ロジスティック関数： 

```math
\sigma(t) = \frac{1}{1+\exp^(-t)} 
```

当てはめたい関数：

```math
f(x) = \frac{1}{1+\exp(-\boldsymbol{w}^T\boldsymbol{x})}
```

最大化したい尤度関数：

```math
L(\boldsymbol w)  = - \prod_{i=1}^N P(C=t_i|\boldsymbol x_i) \\
where \quad　P(C=t_i|\boldsymbol x_i) = f(x_i)^t(1-f(x_i))^{1-t}
```

更新方法： (tは教師信号)

```math
\boldsymbol w^{t+1} = \boldsymbol w^{t} - \alpha * \frac{\partial L}{\partial \boldsymbol w^{t}} \\
where \quad \frac{\partial L}{\partial \boldsymbol w} = - \sum_{i=1}^{N}(f(x_i)-t_i)\boldsymbol x_i 
```

参考文献：
https://dev.classmethod.jp/business/business-analytics/alteryx-advent-calendar-11-logistic-regression/
https://dev.classmethod.jp/machine-learning/logistic-regression-impl/

### サポートベクターマシーン
分類する線形モデル： $ g(x) = \boldsymbol{w}^T\boldsymbol{x} + b $   
分類器：　$ f(x) = sgn(g(x)) =$ -1 or 1 
最小化したい関数：

```math
\frac{2}{\|\boldsymbol w\|}
```


## 木
### 決定木
C4.5：
目的関数（と呼ぶのかな？）：エントロピーを最大化させるような説明変数を順に親ノードとして選択していく

```math
\Delta I_H(t) = I_H(t_B) - \sum_{i=1}^{b}w_iI_{H_i}(t_{A_i})
```
CART：
目的関数：ジニ係数を大化する説明変数を順に親ノードとして選択していく

```math
I_G(t) = 1 - \sum_{i=1}^{c}p(i|t)^2
```

参考文献：https://qiita.com/3000manJPY/items/ef7495960f472ec14377
実装：http://darden.hatenablog.com/entry/2016/12/15/222447


## NN
### Perceptron
線形な関数を組み合わせて，最小二乗法で最適化している
フィッティングさせたい関数：$ f(x) = \boldsymbol{w}^T\boldsymbol{x} $
最小化させたい関数：$ J = \sum_{i=1}^{n}(y_i - f(x_i))^2 $

### MLP (Multi-Layered Perceptron) 
各ニューラルをシグモイド関数$g(\boldsymbol{w}^T\boldsymbol{x})=\frac{1}{1+\exp(-\boldsymbol{w}^T\boldsymbol{x})}$で表すことで各点において2値分類が可能に．
全体としてみると，複数の値に分類することが出来る．
つまりは，多次元によるロジスティック回帰としてみなせるのでは？
誤差に二乗を逆伝搬することで最適化しているので最小二乗法やSVMに似ている．

# 以下特に最適化のような式が出てこないので雑に扱っていきます．
##　ベイズ
ベイズ推定を使った分類.確率を勉強していたらわかるでしょう．

## 時系列
ARIMAモデルなど

## クラスタリング　(k-means法）

## アンサンブル
母集団\theta から n個の集団$\hat{\theta}$を選んできて，それぞれの集団に学習をかける
弱学習機をn個作成して，これらをがっちゃんこ．
判別ならその中で最大のものargmax
回帰の場合は平均値．
ここらへんの設計も工夫次第だと思います．


# どれ使うか困っている時．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/146448/7f0359cc-5ceb-412e-842e-1faba76aea8c.png)
[初学者]whenever を使って定期的にバッチ処理を行う(公開設定編)

# 目的

- 自分用のメモです
- 条件
   - WordPressみたいなブログサイト
   - 記事のステータスは、「下書き」「公開待ち」「公開」の3種類
   - 記事を保存時に上記ステータスと公開日(日付)の設定が必須
   - 「公開待ち」の記事で期限到来日(公開日)によりステータスを自動で「公開」に変更

# 動作環境

- ruby 2.5.0
- Rails 5.2.0
- mysql  Ver 14.14 Distrib 5.7.22

# 手順リスト

1. 「rails g task」コマンドでタスク(処理)を作成
2. 　gem 'whenever'を導入し、タスクを定期的にバッチ処理

## 1. 「rails g task」コマンドでタスク（処理）を作成

```bash:タスクファイルを生成
rails g task check_date
# lib/tasks/check_date.rakeにファイルが生成される
```

```ruby:app/models/article.rb
# enumの設定です　[下書き　公開待ち　公開]
enum state: %i[draft wait_publish published]
```

```ruby:lib/tasks/check_date.rake
namespace :check_date do 
  desc "check_state"　# このタスクの説明を書く
# タスクの名前。　「:environment」がないとDBやモデルにアクセスできないので、使う場合は付ける
  task check_state: :environment do　
    Article.where('published_at <= ?', Time.zone.now).wait_publish.each(&:published!)
# articlesテーブルで[公開日が現在時刻以前かつステータス「公開待ち」]のものを全て「公開」に変更
  end
end
```

### 処理が本当に走るのか確認する

```bash:タスクの一覧を表示
rails -T
```

![qiita_task.jpg](https://qiita-image-store.s3.amazonaws.com/0/118229/82ccca08-164a-655e-19a8-a6a080e5a18a.jpeg)

ここで、タスク処理の設定は完了です。
次は、設定したタスクを定期的にバッチ処理を行うよう設定していきます。

## 2. gem 'whenever'を導入し、タスクを定期的にバッチ処理

```ruby:Gemfile

# crontab管理
gem 'whenever', require: false

# 上記を記載後、bundle install
```

```bash:設定ファイルを作成
bundle exec wheneverize .

> [add] writing './config/schedule.rb' #<= 設定ファイルが生成
> [done] wheneverized! #<= 成功
```

```ruby:config/schedule.rb
# Rails.rootを使用するために必要。なぜなら、wheneverは読み込まれるときにrailsを起動する必要がある
require File.expand_path(File.dirname(__FILE__) + "/environment")
# cronを実行する環境変数
rails_env = ENV['RAILS_ENV'] || :development
# cronを実行する環境変数をセット
set :environment, rails_env

# cronのログの吐き出し場所。ここでエラー内容を確認する
set :output, "#{Rails.root}/log/cron.log"

# 3時間ごとに[lib/tasks/check_date.rake]を実行する
every 3.hours do
  rake 'check_date:check_state'
end

# [課題]
# メモ：厳密に言うとこのコードにはバグが含まれていると思っていて、3時間おきにタスク実行させているので！
# 例えば12:00にタスクが走った後、公開時刻が12:01の記事があった場合でも、次にタスクが走るのは15:00、つまり15:00にならないと公開状態にならないようなコードとなっています。
# 既存のものに修正を加えるとなると、色々とデータの整合性を保たなければいけなくなるので、
# その辺今後意識していきましょう。
# [試したこと]
# コールバックを設定したけど、それだとSQLを走らせる回数が増えるのでよくない。

```

#### Corntabへの設定

```bash:

# 設定内容にエラーがないか確認
bundle exec whenever

# 設定されているcronを見る
crontab -l

# wheneverの設定更新
RAILS_ENV=development bundle exec whenever --update-crontab

# crontabの設定削除
RAILS_ENV=development bundle exec whenever --clear-crontab
```

## 気づき

```ruby:config/application.rb
config.autoload_paths += %W(#{config.root}/lib)
```
あまり考えずに設定してたけど、Rails5のproduction環境では不具合がでるので注意しとく。

[Rails5のproduction環境でlib/配下のクラス読込みがNameErrorになるのはautoloadが無効化されたからだった](https://qiita.com/K_Yagi/items/edc46fd976526279312b)

[Rails5: production環境でのAutoloadの廃止](https://qiita.com/joooee0000/items/3ab0f3d791e0d0beb639)

## 参考
https://morizyun.github.io/blog/whenever-gem-rails-ruby-capistrano/index.html
macOS を10.13.5にアップデートしたらターミナルが死んだ

#内容
先日、OSを10.13.5にアップデートすると、その後iTermを開くと一瞬で閉じてしまうということが起きた。
ターミナルから開いてみると以下のように出力されていた。

```
dyld: Library not loaded: /usr/local/opt/gdbm/lib/libgdbm.4.dylib
  Referenced from: /usr/local/bin/zsh
  Reason: image not found

[プロセスが完了しました]
```
#解決策
シェルをzshからbashに変更してみると普通に動いたので、どうやらzshに問題があったようだ。

以下のコマンドで、zshを入れ直すと生き返った。

```
brew reinstall zsh && brew unlink zsh && brew link zsh
```

#参考
https://stackoverflow.com/questions/24103888/error-loading-library-in-mac-terminal
Rubyで基底文字+結合文字だけ正規化する

## やりかた1

```rb
str = "神" + "Äが".unicode_normalize(:nfd)
# => "神Äが"
str.size
# => 5
str2 = str.each_grapheme_cluster.map {|s| s.size > 1 ? s.unicode_normalize : s }.join
# => "神Äが"
str2.size
# => 3
```

## やりかた2

```rb
str = "神" + "Äが".unicode_normalize(:nfd)
# => "神Äが"
str.size
# => 5
str2 = str.gsub(/\X/) {|s| s.size > 1 ? s.unicode_normalize : s }
# => "神Äが"
str2.size
# => 3
```

## だめなやりかた

`神`が正規化されて`神`になっている

```rb
str = "神" + "Äが".unicode_normalize(:nfd)
# => "神Äが"
str.size
# => 5
str2 = str.unicode_normalize
# => "神Äが"
str2.size
# => 3
```
Eclipse 作業を効率化するためのショートカット

1.一緒に変更する：
`ALT+SHIFT+R`

2.mainメソッドを素早く入力する：
`main+alt+/`

3.System.out.printlnを快速入力：
`syso+alt+/`

4.javaソースコードを見る
`確認したいメソッドをクリック、F3を押す`

5.使用されていないクラスを削除：
`ctrl+shift+o`

6.コードをコメントにする：
`注釈したいコードを一行または複数行を選んで、ctrl+shift+cを押す`

6.大文字、小文字変換：
`ctrl+shift+x ctrl+shift+y `

7.getter,setterを快速導入
`shift+alt+s`
delay: no func with key found エラーでハマった話

taskqueue 実行時に、対象の async function が見つからない旨のエラーが発生し、正常に処理ができなかった。
原因がいくつかあるみたいだが、今確認しているのは以下。(他の状況も見つかれば追記予定)

## キューイング中のファイル名名称変更
Taskのキューイングが行われている時に、ファイル名を変更し Deploy すると発生。
どうやら、キューを呼び出したファイル名と実行するべきFunction 名のペアリングをして制御しているようで、
名称変更によりペアが崩れると正しく処理が行われなくなる。

回避方法
* そもそもファイル名を変更しない運用にする。
* 発生してしまった場合、Queueを流しきってから、Deploy をする。

上記はほぼ流用なので、こちらを見た方がよりよい。
[Go言語でハマったNつのこと](https://qiita.com/Neetless/items/cc774592a059100de2e7) 

## 実行するべきservice が異なっている
### 前提条件
foo, baa の2つのサービスが存在する。
foo サービスから以下のtask をfoo service 内で呼び出す。
queue.yaml の設定

```
- name: baa-task
  rate: 250/s
  bucket_size: 100
  max_concurrent_requests: 1500
  target: baa
```

### 解決案

queue.yaml 側の target に 指定サービスを設定していると、task queue 実行時に明示的にHost設定していても、
queue.yaml の方のtarget 設定が優先的に使用されるため、意図したservice で動作しない。

```
hostName, _ := appengine.ModuleHostname(ctx, "foo", "", "")
task.Header.Set("Host", hostName)
if _, err = taskqueue.Add(ctx, task, "baa-task"); err == nil {
	log.Infof(ctx, "queuing [%s]", queueName)
}
```

この場合、baa-task に設定されている `target: baa` サービス で動作するため、
設定した task内部で プライベート関数 を用いた async 処理が定義されていた場合、`delay: no func with key found`エラーが発生する。

解決するためには、 hostname 側の設定を変更しても変わらないため、
queue.yaml 側の設定を直せばOK。

## 要約
1. キューイング中のファイル名変更はしない
2. queue.yaml の target はかなりの権限を持ったサービス指定パラメータ。
3. ソース内部でHostName 設定を行う場合、 queue.yaml 側の target 設定が行われていないかを確認しておく。
4. queue.yaml の定義を流用させたいときは、targetを指定しない方が取り扱いやすいかも。
Rails：jqueryでコントローラのactionを叩き、jqueryに変数を戻す方法

##作ったもの
小説家になろうのアドレスを入力、
ボタンを押すと入力先のタイトル、詳細を取得してきてajaxで表示。
![7c8654ba4856e6489e0dad4c2870677b.gif](https://qiita-image-store.s3.amazonaws.com/0/145707/ca2f5f56-5ede-878c-d215-e86900fb53d7.gif)

##概要
【jqueryでRailsコントローラの関数を呼んで、変数を画面に送り返す】
というやり方は見かけなかったので貴重かなと思っています。

【概要】
URL入力欄のURLをjqueryで感知
↓
コントローラの独自関数に送る
↓
関数内でスクレイピング、インスタンス変数に情報を入れる
↓
画面上に送り返す
↓
jqueryでid指定などをして情報を画面に表示


##ソースの説明

今回操作する画面は
Matomeモデルのshow画面上となります。

コントローラに関数を定義。スクレイピングは以下を参照してください。
[Rails スクレイピング手法 Mechanizeの使い方](https://qiita.com/shizuma/items/d04facaa732f606f00ff)

```ruby:app/controllers/matomes_controller.rb
  def scraping_novel
    require 'mechanize'

    agent = Mechanize.new
    page = agent.get(params[:url])
    @novel_title = page.at('.novel_title').inner_text
    @novel_description = page.at('#novel_ex').inner_text

    respond_to do |format|
      format.js
    end
  end
```

新しいルートを追加
ルートを追加しないと、なぜかidに関数名が入りうまくいかないです。

```ruby:config/routes.rb
Rails.application.routes.draw do
  get "matomes/scraping_novel"
  resources :novels
  resources :matomes
  devise_for :users
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root 'matomes#index'
end
```

新しいjsファイルを作成。
**コントローラ内に作った関数と同じ名前のjs.erbファイルをviews/コントローラ以下に作成**してください。
コントローラから取得した2つのインスタンス変数をパース、
分けるために間にdelimiterという単語を入れています。

```erb:app/views/matomes/scraping_novel.js.erb
<%= @novel_title %>delimiter<%= @novel_description %>
```

このjsは
・コントローラに情報を送る
・コントローラから情報を受け取って表示する
の２つを行なっています。

送るときは、
urlに関数名、
data内にコントローラに送りたい情報を書いてください。
**params[:url]**のような形でコントローラ内で取り出すことができます。

success: function(data)のdataにjs.erbファイルに書いた内容が入ってきます。
タイトルとあらすじの間にdelimiterという単語を挟んでおいたので、
それで分けてjqueryでフォームに入力しています。

URLが想定したものと違う時は
画面上にアラートを出すようになっています。

```javascript:app/assets/javascripts/application.js
  $("#get-novel-info-button").click(function(){
      $.ajax({
          url: "scraping_novel",
          type: "GET",
          data: { url : $("#modal-novel-url").val()
                  },
          dataType: "html",
          success: function(data) {
              console.log('success');
              console.log(data);
              // app/views/matomes/scraping_novel.js.erb
              //上記ファイルの中身を文字列"delimiter"で分ける
              var split_datas = data.split("delimiter");
              $("#modal-novel-title").val(split_datas[0]);
              $("#modal-novel-description").val(split_datas[1]);
          },
          error: function(data) {
              console.log('error');
              alert("URLが不正、もしくはこのURLには対応していません。");
          }
      });
  });
```


##感想
めっちゃ感動した。
スクレイピングすごい。ajaxすごい。
これ、コントローラを経由するから色々と応用できそうで楽しみすぎる。

##参考URL
[RailsでjQueryからajax](http://yaamaa-memo.hatenablog.com/entry/2016/12/26/000000)
[jQuery内からRailsのActionを叩く](https://qiita.com/somewhatgood@github/items/113773747a6faa800366)
bitbucketのすべてのRepo(権限を持っているRepo)を一気にCloneするスクリプト・コマンド

# 背景

たくさんRepoがあるときに、新しいパソコンを購入しすべてのRepoを一個ずつCloneしてくるのがめんどくさいのですべて一気にCloneしたい！


# スクリプト

コマンドでやりたかったが、一回に返ってくる量に制限があるので、Paginateしてる分をLoopしてあげるスクリプトを書いた。Repoがそんなにない場合は、コマンドでおっけー

```get_all_repo.sh
#!/bin/bash

USER=$1
PASS=$2
URL=https://api.bitbucket.org/2.0/repositories/$USER

if [ $# -lt 2 ];then
    echo "usage ./get_all_repos.sh <user> <pass> <team optional>"
    exit 1
elif [ $# -eq 3 ];then
    TEAM=$3
    URL=https://api.bitbucket.org/2.0/repositories/$TEAM
fi

TMP_FILE=tmp_res.json

while true
do
    curl --user $USER:$PASS $URL > $TMP_FILE
    cat $TMP_FILE | jq -r '.values[].links.clone[].href' | grep -v https | xargs -L1 git clone
    next=$(cat $TMP_FILE | jq -r '.next')
    if [ -z $next ];then
        echo no more next
        break;
    else
        echo next $next
        URL=$next
    fi
done
```

実行コマンド

## User(自分)の管理するRepoをすべてCloneする

```shell
./get_all_repos.sh <user> <pass>
```

## Teamの管理するRepoをすべてCloneする

```shell
./get_all_repos.sh <user> <pass> <team>
```

# コマンド

Repo数が多くない場合は、一行のコマンドで十分。実行するとパスワードが聞かれるので、パスワードを入力すれば、Cloneが始まる。

## User(自分)の管理するRepoをすべてCloneする

```shell
USER=bitbucket_username; curl --user $USER https://api.bitbucket.org/2.0/repositories/$USER | jq '.values[].links.clone[].href' | grep -v https | xargs -L1 git clone
```

## Teamの管理するRepoをすべてCloneする

```shell
USER=bitbucket_username;TEAM=bitbucket_teamname curl --user $USER https://api.bitbucket.org/2.0/repositories/$TEAM | jq '.values[].links.clone[].href' | grep -v https | xargs -L1 git clone
```



# 説明

## bitbucket API
これで、すべてのRepoの情報がJSON形式で帰ってくる

```
curl --user $USER https://api.bitbucket.org/2.0/repositories/$USER | jq '.values[].links.clone[].href' | grep -v https | xargs -L1 git clone
```

## jqコマンド
jqコマンドでJSONをパースして自分の必要な情報だけを集める。以下のもので、Cloneの中に、sshとhttpsのCloneアドレスが列挙されるようになる

```shell

jq '.values[].links.clone[].href'
```

## grep

今回は、不精して、単にhttpsを除外しただけ。本来はjqコマンドでnameがsshのものに限定すると一番よい！

```shell

grep -v https
```
KerasのContainerが名前を変えていた件

# Kerasで急に知っているレイヤーが使えなくなる

ある日最新バージョンのKerasでモデルを作っていたら突然

```
cannot import name 'Container'
```

と言われてしまいました。
複数のレイヤーの重みをまとめて1つの塊として共有したいときに便利なので時折利用するのですが
https://github.com/keras-team/keras/pull/10023
によると `Network` という名称に変わったようです。

importも

```
from keras.engine.network import Network
```

とするみたいです。使い方はContainerとほぼ同様で今の所問題なく使えていますが、急に変えられるとググっても答え出てこないので結構悩みます :sweat:
Goodby\CSVを使って csvファイルを import する時に、行によってカラム数が違う場合の対処

```
Column size should be 10, but 20 columns given
```

みたいなエラー出る時

日本語だとなんて検索したらいいんだろう？

というのをいろいろ考えたのですが、考えた結果をタイトルに入れてみました。


----

っていうかドキュメントに思いっきり書いてあったんですけどね( ˘ω˘)
斜め読みくらいはすべきでした、反省。

https://github.com/goodby/csv

Unstrict Row Consistency Mode
google翻訳さんで翻訳したら ``` 非一貫性のある行一貫性モード ```

わからんわ・・・

とはいえ、英語がわからなくても、

![csv.png](https://qiita-image-store.s3.amazonaws.com/0/155965/c9806d34-11fa-6a1f-9df6-4d7cb423efdf.png)

ここに気がつけば発見はできそうです。