OmniAICreator/Qiita-1.07M huggingface dataset:
【C#】HttpListenerで簡易サーバー作成する

備忘録とMarkdown記法に慣れる練習兼ねて。


```D01tsumaTask1.cs

using System;
using System.Diagnostics;
using System.Net;
using System.Text;

namespace D01tsumaTask1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // HTTPリスナー作成
                HttpListener listener = new HttpListener();

                // リスナー設定
                listener.Prefixes.Clear();
                listener.Prefixes.Add(@"http://+:8080/");

                // リスナー開始
                listener.Start();

                while (true)
                {
                    // リクエスト取得
                    HttpListenerContext context = listener.GetContext();
                    HttpListenerRequest request = context.Request;

                    // レスポンス取得
                    HttpListenerResponse response = context.Response;

                    // HTMLを表示する
                    if (request != null)
                    {
                        byte[] text = Encoding.UTF8.GetBytes("<html><head><meta charset='utf-8'/></head><body><h1>どいつま.com</h1></body></html>");
                        response.OutputStream.Write(text, 0, text.Length);
                    }
                    else
                    {
                        response.StatusCode = 404;
                    }
                    response.Close();
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

```
Azure CosmosDB Java SDK で 集計クエリー (Count) を使う


JavaSDK から CosmosDB で集計クエリーを利用するのにハマった点があったのでメモします。

クエリーにVALUE句を設定しないと以下のエラーになります。

```
java.lang.IllegalStateException: com.microsoft.azure.documentdb.DocumentClientException: Message: {"Errors":["Cross partition query only supports 'VALUE <AggreateFunc>' for aggregates."]}
Caused by: com.microsoft.azure.documentdb.DocumentClientException: Message: {"Errors":["Cross partition query only supports 'VALUE <AggreateFunc>' for aggregates."]}
```

また、setEnableCrossPartitionQuery を true にしないと以下のエラーになります。

```
java.lang.IllegalStateException: com.microsoft.azure.documentdb.DocumentClientException: Cross partition query is required but disabled. Please set x-ms-documentdb-query-enablecrosspartition to true, specify x-ms-documentdb-partitionkey, or revise your query to avoid this exception.
Caused by: com.microsoft.azure.documentdb.DocumentClientException: Cross partition query is required but disabled. Please set x-ms-documentdb-query-enablecrosspartition to true, specify x-ms-documentdb-partitionkey, or revise your query to avoid this exception.
```

以下、Javaのコードです。


```java

		// Azure Cosmos DB Libraries for Java
		// https://docs.microsoft.com/ja-jp/java/api/overview/azure/cosmosdb?view=azure-java-stable

		String host = "yourhost";
		String container_id = "yourcontainer";
		String database = "yourdatabase";

		// Get key from Azure Web Console
		// read write key
		String key = "yourkey";

		String endPoint = "https://" + host + ".documents.azure.com:443";

		DocumentClient client = new DocumentClient(endPoint, key, //
				new ConnectionPolicy(), ConsistencyLevel.Session);

		String collectionLink = String.format("/dbs/%s/colls/%s", database, container_id);

		String q = String.format("SELECT VALUE count(1) FROM c");
		// IF (without 'VALUE' in query)
//		java.lang.IllegalStateException: com.microsoft.azure.documentdb.DocumentClientException: Message: {"Errors":["Cross partition query only supports 'VALUE <AggreateFunc>' for aggregates."]}
//		Caused by: com.microsoft.azure.documentdb.DocumentClientException: Message: {"Errors":["Cross partition query only supports 'VALUE <AggreateFunc>' for aggregates."]}

		FeedOptions feedOptions = new FeedOptions();
		feedOptions.setEnableCrossPartitionQuery(true);
		// IF (EnableCrossPartitionQuery = false)
//		java.lang.IllegalStateException: com.microsoft.azure.documentdb.DocumentClientException: Cross partition query is required but disabled. Please set x-ms-documentdb-query-enablecrosspartition to true, specify x-ms-documentdb-partitionkey, or revise your query to avoid this exception.
//		Caused by: com.microsoft.azure.documentdb.DocumentClientException: Cross partition query is required but disabled. Please set x-ms-documentdb-query-enablecrosspartition to true, specify x-ms-documentdb-partitionkey, or revise your query to avoid this exception.

		try {

			List<Object> results = client //
					.queryAggregateValues(collectionLink, q, feedOptions);

			System.err.println(results.get(0));

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			client.close();
		}


```

以上です。
POST送信後と送信前の文字数の違い

## 概要
ThreeLでwikiのように整形を行っている部分で
うまいこと変換されないことが問題点にあたる。

## 結論
改行コードの違い
htmlのtextareaの改行コードがCR/LF

htmlのtextareaの改行コードがCRLFであるが
javascriptの場合は、LF。

この違いがあるため \n\n 部分が認識されなかった。

## 経緯
ajaxのプレビューと本ページが差分が存在
文字列の長さの検証、違うことが確認できる。

調べてみるとtextareaの改行コードがCRLF
jsではLF
違いの確認が出来た。

## 解決策
```PHP
$text = str_replace("\r\n", "\n", $post_textarea);
```

どちらかにそろえてあげるだけで大丈夫です。
もしくはパーサー側で対応するのもありかと思う。

ほかの問題点として文字数が違うため文字数制限をかける際に少なくなったりなどがあるなるので、知っておくといいですね」。
Parcelで作るSPAじゃないVue.js環境構築

Parcelを使うと簡単にフロントエンドの開発環境構築ができますが、複数ファイルのエントリファイルに対応しているのを知ったので試してみたいと思います。



## Parcelのインストール



```bash
$ npm install --save-dev parcel-bundler
$ npm install vue
```



# 複数のhtmlファイルを作成



### 一つ目の画面作成



まずIndexページ作成を作成します。

src/index.html

```html
<html>
  <body>
    <div id="app">
      <app></app>
    </div>
    <script src="./index.js"></script>
  </body>
</html>
```



エントリファイルを作成します。

src/index.js

```js
import Vue from 'vue/dist/vue.esm.js';
import App from './App.vue';

Vue.component('app', App);

new Vue({ el: '#app' });
```



Indexページで使用するVueコンポーネントを作成します。



```vue
<template>
  <div>
    {{ message }}
  </div>
</template>

<style>
</style>

<script>
  export default {
    name: 'App',
    data() {
      return({
        message: 'Index page',
      });
    },
  }
</script>
```



### 二つ目の画面作成

今回はSPAじゃないので複数画面があり、各画面に対してエントリファイルを読み込む形にします。

次に同じようにAboutページを作成します。



src/about.html

```html
<html>
  <body>
    <div id="app">
      <about></about>
    </div>
    <script src="./about.js"></script>
  </body>
</html>

```



src/about.js

```js
import Vue from 'vue/dist/vue.esm.js';
import About from './About.vue';

Vue.component('about', About);

new Vue({ el: '#app' });

```

src/About.vue

```vue
<template>
  <div>
    {{ message }}
  </div>
</template>

<style>
</style>

<script>
  export default {
    name: 'About',
    data() {
      return({
        message: 'About page',
      });
    },
  }
</script>
```



## Parcelコマンドの設定

package.jsonに複数ファイルをwatchモードで実行できるよう設定します。



```json
"scripts": {
    "start": "parcel src/*.html",
    "watch": "parcel watch src/*.html"
},
```



## 実行してみる



まずParcelをwatchモードで実行します。



```bash
$ npm run watch
```



すると最初はParcelが必要な依存関係をインストールしてくれて、ビルドが走ります。

ビルド後は対象のファイル変更を検知してHot Reloadが効いてくれます。

ビルドファイルはデフォルトで/distへ出力されます。



watchモードではwebサーバーが起動しないので、http-serverを使ってアプリを動かします。



```bash
$ npx http-server dist -p 8000
```



起動したら、`localhost:8000` と `localhost:8000/about` にアクセスしてみるとVueが動いているのがわかります。



## まとめ

Parcelを使うことでVueの開発環境が驚くほど簡単に構築できました。

複数ファイルをサポートしているのも嬉しいですね！



## 参考

- http://simoothie-cafe.hatenablog.com/entry/2018/05/06/120222
- https://en.parceljs.org/
Scala導入編@自分用メモ

Scalaの学習をしたため，その様子をメモに残す．（少しずつ更新予定）

<h2>この記事に書いてあること</h2>
Scalaとはどんなものか
よくScalaと一緒にでてくる"sbt"とは何か

<h2>Scalaの特徴</h2>
関数型とオブジェクト指向を良い感じに取り入れることができる．
JVM上で動作し，Javaとの親和性が高い．
標準ライブラリに並列処理関連のものが多く，並列処理に向いている．

<h2>Scalaと一緒によく出てくる"sbt"とは</h2>
Scalaでプログラミングを行う際によく聞く"sbt"とは，一般的にScalaで使用される<b>ビルドツール</b>のこと．（Simple Build Toolの略）
必ずしもsbt出なければならない，ということはないが，sbtは非常に強力で柔軟なScala用のビルドツールのため，Scalaプログラミングをする上でその恩恵は絶大．


<h4>参考にさせていただいたページ等</h4>
ドワンゴ，オリジナル新卒エンジニア向け研修資料
https://dwango.github.io/scala_text/introduction-to-scala.html

<h4>さいごに</h4>
拙い文章ですが，内容やそのほか何かご指摘頂けると幸いです．
改行させたくない時のCSS

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#改行防止
サイトを作成しているとPCでのwindowsやmacによって表示が異なるしスマートフォンの対応などレスポンシブ対応が求めて簡単な作業のメモです。
[【CSS】レスポンシブ対応の方法や作り方を徹底解説【メリット＆デメリット】
](https://creive.me/archives/16922/)


#改行してないかテスト
デベロッパーツールを使用し以下確認を行いました。
①CSSに不具合がないか確認する為にウィンドウサイズを変更してみる。
②ブラウザのフォントサイズ設定を変更してみる。（ChromeならSettingsで変更可能）
[Google Chromeのフォントを変更する方法
](https://ferret-plus.com/7494)

#改行バグ発見
今回は以下のCSSのコードを追加して修正しました。[word-break
](https://developer.mozilla.org/ja/docs/Web/CSS/word-break)

```
word-break: keep-all;
```

ブラウザ幅を可変にしてもある程度崩れさせたくないならflexboxと単位の相対指定でなんとかなるはず。
[Flexbox (フレックスボックス)
](https://developer.mozilla.org/ja/docs/Glossary/Flexbox)
ATSに求められるサーバ要件

[Appleの記事](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33)に書いてある通りなのだが、簡単に言うとこういうことである。

1. 次のうちのいずれかをルート証明書として持っている
    - iOSがルート証明書として登録している
    - ユーザかシステム管理者がルート証明書として登録している
2. AES-128かAES-256共通鍵暗号を用いる。一時的な楕円曲線ディフィー・ヘルマン鍵共有アルゴリズムを使ったPerfect forward secrecy(仮に暗号化されたデータを盗聴して記録しておいても、将来的にも解読されないことが保証される)をサポートするアルゴリズムであるこれらのいずれかである必要がある
    - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
3. サーバ証明書が2048ビット以上のRSAか256ビット以上のECCで署名されていて、ダイジェストアルゴリズムとしてSHA-2(256ビット以上)であること

サーバが問題なくこれらをサポートしているかは、Mac OS X上で `nscurl --ats-diagnostics https://[domain name]/` と実行すればわかる。
Default ATS Secure Connectionの部分が `Result : PASS` となっていればOKである。
railsのroutes.rbのmemberとcollectionの違いは?

##はじめに

Railsでroutes.rbを設定するとき、**member**や**collection**を記述することがあります。

```ruby:routes.rb
resources :users  do
  member do
    get :logout
  end
end

resource :user_sign_ups do
  collection do
    get :tell 
  end
end
```

このmemberやcollectionはどんな役割をしているのでしょうか?

##memberとcollectionの違いは?

簡単に言うと、`routingにidが付くか付かないかの違い`です。

もう少しわかりやすく説明するために例をだして解説します。

```ruby
resources :users  do
  member do
    get :logout
  end
end
```
`users#logout`をmemberでルーティングを設定すると、URLは以下のようになります。

```
/users/:id/logout
```

このようにuserを識別するための:idが追加されます。

では、collectionでルーティングを設定した場合はどうなるでしょう?

```ruby
resource :user_sign_ups do
  collection do
    get :tell 
  end
end
```
`user_sign_ups#tell`をcollectionでルーティングを設定しました。

すると

```
/user_sign_ups/tell
```
urlに:idが追加されていません。

:idでurlを識別する必要がない場合はcollectionで設定します。

##おわりに

まとめると

・**memberは特定のデータにアクションを利用する**
・**collectionは全体のデータにアクションを利用する**

ときに設定します・
WebDAVがエクスプローラで使えない！場合の対処法

# 前書き

## ここに書いてあること
とあるお仕事で「Alfresco」というOSSのファイル管理システムを導入しました。
AlfrescoはデフォルトでWebDAV接続やCIFS、FTPでの接続が可能となっており、エクスプローラから直接ファイルにアクセス出来るのですが、
なぜか出来なかった（※webDAVクライアント用ツールである「CarotDAV」を経由したら繋がる）のでその解決方法を記載します。


## WebDAVとは
HTTP/HTTPS経由でファイルのやり取りが出来るプロトコルです。
ポートやプロトコルが違うけど要するにFTPみたいなものです。
特別なクライアントツール（FTPでいうWinSCPなど）が必要ないのがWebDAVのメリットのようです。


## Alfrescoとは
OSSのファイル管理システムです。
Alfrescoサーバへファイルアップロードした際に、プレビュー用PDFの生成、インデックスの取得を行う事で
・超高速なファイル全文検索機能
・ファイルプレビュー機能
などが出来るためとても優秀です。

# 原因
Windows vistaあたりから、エクスプローラでのWebDAV接続は

　①https必須
　②SSL証明書のインストール必須
　③Alfrescoサーバのホスト名とSSL証明書の発行先が一致している必要がある

になっており、②と③が出来ていなかった為エクスプローラでのWebDAV接続が出来ませんでした。

# 解決方法
　１．「③」を解決するために、Alfrescoサーバにはドメインを割り当てるか、Hostsファイルでホスト名を割り当ててください。
　　→ 【参考記事】　[【Windows】hostsファイルとは、hostsファイルの場所、hostsファイルの編集・書き換え方法](http://onocom.net/blog/windows-hosts-file/)
　２．「①」に対応するために、オレオレ認証でもいいので、https化してください。
　　→ 【参考記事】[nginxに自己証明書(オレオレ証明書)を設定](https://tech.zerobase.xyz/nginx-ssl/)
　３．「②」に対応するために、クライアントにSSL証明書をインストールしてください。
　　→ 【参考記事】[【オレオレ証明書】Windows7での自作WebDAVサーバーとの接続【SSL】](http://www.kyoji-kuzunoha.com/2011/12/windows7webdavssl.html)
【Docker】apt-getでffmpegのバージョンを指定してインストールする

# やること
`ubuntu 18.04`のDockerイメージにバージョンを指定した`ffmpeg`をインストールします。
ただし、バージョン指定を主眼に置いているため、実行ユーザーが`root`になっています。

`alpine`版も最後におまけとして載せます。

# やり方
まず最低限の`Dockerfile`が以下です。
`ffmpeg=`の後に指定しているのがバージョンです。

```dockerfile
FROM ubuntu:18.04

RUN  apt-get update \
  && apt-get install -y ffmpeg=7:3.4.6-0ubuntu0.18.04.1 \
  && apt clean \
  && rm -rf /var/lib/apt/lists/*

CMD ["/bin/bash"]
```

この記事では、`ffprobe-test:0.0.1`と名付けて`docker build`した前提で話を進めます。

```bash
docker build -t ffprobe-test:0.0.1 .
```

## 指定可能なバージョン
`ubuntu 18.04`では以下のページの`Versions published`に示されているバージョンはそのままで指定することができます。

- [Bionic \(18\.04\) : ffmpeg package : Ubuntu](https://launchpad.net/ubuntu/bionic/+source/ffmpeg)

その他の内容を指定する場合は、デフォルトリポジトリに存在していないので、リポジトリを探して追加してやる必要があります。

- [ffmpeg package : Ubuntu](https://launchpad.net/ubuntu/+source/ffmpeg)

## インストールされたバージョンの確認方法
`apt-cache`で確認できます。
Docker周りのコマンドについては省略します。

```bash
docker run --rm -i ffprobe-test:0.0.1 apt-cache policy ffmpeg
```

```bash:実行結果
$ docker run --rm -i ffprobe-test:0.0.1 apt-cache policy ffmpeg
ffmpeg:
  Installed: 7:3.4.6-0ubuntu0.18.04.1
  Candidate: 7:3.4.6-0ubuntu0.18.04.1
  Version table:
 *** 7:3.4.6-0ubuntu0.18.04.1 100
        100 /var/lib/dpkg/status
```

バージョンを`7:3.4.2-2`に変えてやると以下のような実行結果となります。

```bash
$ docker run --rm -i ffprobe-test:0.0.1 apt-cache policy ffmpeg
ffmpeg:
  Installed: 7:3.4.2-2
  Candidate: 7:3.4.2-2
  Version table:
 *** 7:3.4.2-2 100
        100 /var/lib/dpkg/status
```

# alpine版
おまけです。
こちらは実行ユーザーに`root`じゃないものを指定しています。

```dockerfile
FROM alpine:3.10.2

# ffmpegのインストール
RUN apk add --update --no-cache ffmpeg=4.1.4-r0

# ユーザー追加
RUN adduser -D ffmpeg_user -G nogroup
# docker run時に使われるユーザーに追加したものを指定
USER ffmpeg_user
```
LeetCode / Min Stack

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/08/21/125915)からの転載）

[https://leetcode.com/problems/min-stack/]

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

push(x) -- Push element x onto stack.
pop() -- Removes the element on top of the stack.
top() -- Get the top element.
getMin() -- Retrieve the minimum element in the stack.
 

Example:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin();   --> Returns -3.
minStack.pop();
minStack.top();      --> Returns 0.
minStack.getMin();   --> Returns -2.

変わり種の問題ですが、push, pop, top, getMinのメソッドを持つクラスを定義する問題です。
クラス・メソッドの定義の仕方が分かっていれば造作もない問題ですが、ちょっとした落とし穴はあります。

#### 解答・解説

##### 解法1
何も考えずに書けば、このようになると思います。

```python
class MinStack(object):

    def __init__(self):
        self.stack = []

    def push(self, x):
        self.stack.append(x)

    def pop(self):
        if len(self.stack) > 0: self.stack.pop()

    def top(self):
        if len(self.stack) == 0: return None
        return self.stack[-1]

    def getMin(self):
        return min(self.stack)
```

これでもsubmitは通るんですが、getMinメソッドの実行時に$O(n)$の空間計算量が必要になります。しかし実際にはその必要はありません。

##### 解法2
今回は、push, pop, topメソッドで各要素を追加・削除・取得すること以外には、getMinで最小値を取得することだけがやりたい処理です。

そこでpushメソッドでlistの変数stackにappendする値を、(追加した要素, これまでの最小値と追加した要素のうち小さい方の値)のタプルにします。
これにより、getMinではstack[-1][1]で最小値を取得できるので、$O(1)$で処理できることになります。

```python
class MinStack(object):

    def __init__(self):
        self.stack = []

    def push(self, x):
        if len(self.stack) == 0:
            self.stack.append([x,x])
        else:
            self.stack.append([x, min(x, self.stack[-1][1])])

    def pop(self):
        if len(self.stack) > 0: self.stack.pop()

    def top(self):
        if len(self.stack) == 0: return None
        return self.stack[-1][0]

    def getMin(self):
        return self.stack[-1][1]
```
文字列の部分一致によって条件分岐を作る(R言語)

```if_mojiretu.r
  if (length(grep(pattern="XX", x=i)) > 0){
    Y <- 500
  } else{
    Y <- 50000
  }
  print(Y)
```
文字列オブジェクト i の中に文字列”XX"が含まれていたらgrep()は1を返すのでTRUE、含まれていなければgrep()はinteger(0)を返す。integer(0)は整数型のデータに何も格納されていない状態なので、それにlength()を取ると0を返してくれる。

追記。
grepl()を使えば返り値を論理型にできるので、こっちのほうがよい。
Rのfacet_wrapで、個々のグラフにそれぞれのgeom_"xx"line(hline,vline,abline)を設定する

皆さん
Rは大好きですよね。
ggplot2も大好きですよね。
facet_wrapも便利なのでよく使いますよね
こんなグラフ書いたりしますよね。

```
library(tidyverse)

iris_data <- iris #癖でデータフレーム化してます。
iris_data %>%
  ggplot(aes(x = Sepal.Width, y = Sepal.Length)) +
  geom_point() +
  facet_wrap(~ Species)+
  theme_bw()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211956/2446d6a9-ea09-4afd-b13a-7870ea6b28ac.png)

これだけでも最高に便利ですが、さらにこんなことしてみたですよね

- Sepal.Lengthの平均を表す線を、irisの種類別に組み込みたい(geom_hline)
- Sepal.Widthの平均を表す線を、irisの種類別に組み込みたい(geom_vline)
- irisの種類別に1次直線を引きたい(geom_abline)

今回は、それをgeom_"xx"line系列の関数を利用して組み込んでみます。
# 事前準備
iris_dataのデータフレームとは別に、下記のデータを用意します

```
dMean <- iris_data %>%
  group_by(Species) %>% #facet_wrapで指定する分類軸でgroup_by
  summarise(Sepal.Length_mean = mean(Sepal.Length),
            Sepal.Width_mean = mean(Sepal.Width))
```
Speciesの名前を残すことが大事です。（後述）
これを利用して組み込んでいきます

# geom_hline

```
iris_data %>%
  ggplot(aes(x = Sepal.Width, y = Sepal.Length)) +
  geom_point() +
  geom_hline(data = dMean, aes(yintercept = Sepal.Length_mean)) +
  facet_wrap(~ Species)+
  theme_bw()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211956/6adfc3bb-0206-17e5-cb81-0ee08d35ee62.png)
geom_hlineの引数にdataとして先程作成した`dMean`を入れることで、`Species`ごとの`Sepal.Length`の平均をグラフに入れることができます。
この後も基本的に同様の流れです。

# geom_vline

```
iris_data %>%
  ggplot(aes(x = Sepal.Width, y = Sepal.Length)) +
  geom_point() +
  geom_vline(data = dMean, aes(xintercept = Sepal.Width_mean)) +
  facet_wrap(~ Species)+
  theme_bw()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211956/7f02dfa5-0941-dc62-f454-5a04a592b500.png)

# geom_abline

```
iris_data %>%
  ggplot(aes(x = Sepal.Width, y = Sepal.Length)) +
  geom_point() +
  geom_abline(data = dMean, aes(slope = Sepal.Length_mean, intercept = Sepal.Width_mean)) +
  xlim(0,10) + #ablineがグラフに入るように軸の幅設定
  ylim(0,10) + #ablineがグラフに入るように軸の幅設定
  facet_wrap(~ Species)+
  theme_bw()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211956/f5336fd0-7669-4dea-d234-500374f449fe.png)[^1]

ちなみに`dMean`に`Species`を入れないと下記のようなグラフになります。

```
dMean <- iris_data %>%
  group_by(Species) %>%
  summarise(Sepal.Length_mean = mean(Sepal.Length),
            Sepal.Width_mean = mean(Sepal.Width)) %>%
  select(-Species) #説明のためにSpecies列削除

iris_data %>%
  ggplot(aes(x = Sepal.Width, y = Sepal.Length)) +
  geom_point() +
  geom_hline(data = dMean, aes(yintercept = Sepal.Length_mean)) +
  facet_wrap(~ Species)+
  theme_bw()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211956/78a4dda1-a3b7-410b-447e-ef1338052ee9.png)

setosa,versicolor,virginiaそれぞれのSepal.Lengthの平均が組み込まれてしまいます。
これは推測ですが、facet_wrapでの分類軸と照らし合わせる必要がありそうです。


**Enjoy!**


[^1]: このグラフを作る実際的な意味はありませんが、説明用で作りました
外付けSSDをUnity Hubのデータ保存先にしてからの不便事項

# Unity HubのUnityエディタのインストール先をSSDに変更し、プロジェクトなどもSSD側に保存するように運用し始めたのですが、 不便な事項 と 対応方法 をまとめました

![スクリーンショット 2019-08-21 12.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/6fed29f8-27f7-6400-d7af-f43234d57aa9.png)


## 環境
PC: MacBook Air
購入したSSD: [My Passport Go 500GB](https://www.wd.com/ja-jp/products/portable-storage/my-passport-go-japan.html)

## 関連記事

[外付けSSDに圧迫データ(Unity Asset Storeフォルダ)をお引っ越し(Mac)](https://qiita.com/kana_omori/items/5f54f517a36dadf9fd64)
[外付けSSDにUnity Hubのデータを保存したい(Mac) 【※未解決エラー有】](https://qiita.com/kana_omori/items/8241ee236d097677e517)

---
##### :ghost:以下、 不便事項 と 対応方法:ghost:

### その１
#### SSDを保存先として新規作成したプロジェクトが開けない

Unity HubでSSDを保存先に指定してプロジェクトを新規作成すると、Unityで開く段階で、エラーが起こり開けません。。

:rolling_eyes: **対応方法**

1. プロジェクトを新規作成する際はいったんPC側を保存先として作成
2. 作成後、SSDに丸っとコピー
3. プロジェクトのリストから、PC側が保存先の方を削除、SSD側にコピーしたものを指定してリストに追加



### その２
#### Unity バージョンを追加インストールしようとしてうまくいかない

Unity HubでSSDをインストール先にしている状態で、新しいUnity バージョンをインストールしようとした際、途中でエラー（「不完全または破損したダウンロードファイル」）が起きて失敗してしまう

:rolling_eyes: **対応方法**

おそらく、インストール画面からマウスを離して違う画面を見たりしてしまうと、このエラーが発生してしまう
（バックグラウンド処理に移行するとうまくいかない。。？）
なので、

**インストールが終わるまで、インストール画面を選択して最前面に表示させたまま、他の作業を何もしない:hugging:**


### その３
#### Unity バージョンにモジュールを追加しようとしても全然進まない

Unity HubでSSDをインストール先にしている状態で、Unity バージョンにモジュールを追加しようとした際、全然青いバーが進まない

:rolling_eyes: **対応方法**

その２と同様の原因なので、

**モジュール追加が終わるまで、インストール画面を選択して最前面に表示させたまま、他の作業を何もしない:hugging:**


### その４
#### iOS で Build And Run するとエラーになる

SSDに保存してあるプロジェクトを iOS に Switch Platform して、BuildのSave先をSSDにして、Build And Run をクリックすると、Buildの途中で
`BadImageFormatException: Format of the executable (.exe) or library (.dll) is invalid.`
というエラーが出てきてしまいBuildが完了できない

:rolling_eyes: **対応方法**

1. Unityプロジェクトを丸っとPC側にコピー、プロジェクトリストにPC側にコピーしたものを追加してUnityエディタで開く
2. BuildのSave先もPC側を指定して、Build And Runして実機確認

まだ iOS しか Build していないので他Buildでも起こるかもしれないのですが、
その１と同じような原理が原因なのでしょうか。
BuildのSave先をPCに変えるだけだと同じくエラーになってしまうので、プロジェクトをPC側に移動する必要があります。

---
##### :alien:振り返り:alien:
比較的安めのSSDを買ったのが悪かったのでしょうか。。
それとも違う理由でしょうか。。

でもとりあえずはこのまま上手に付き合っていく方法を探していきたいと思います。


以上！prz
タスクスケジューラでバッチが動作しなくて困った

#事象
とあるバッチ(BAT1)をタスクスケジューラからキックした所、リターンコード0x1で終了してしまい動かせない。

■BAT1

```
@echo off
call .\bat2.bat
```
　※bat2.batは同じディレクトリ内に格納されている。



#原因
指定が相対パスになっていた事が原因。
(理由不明。タスクスケジューラで実行する際、「場所」を指定しても相対パスは機能しない…？)



#解決策
該当部分を、絶対パスに書き換えた。つまり以下。
書換前

```
@echo off
call .\bat2.bat
```

書換後

```
@echo off
call D:\BAT\bat2.bat
```

#その他(切り分け結果)
なぜ相対パスで上手く行かないのか納得いかない。
が、取りあえず切り分け結果。

#####以下のバッチは動作した。
■BATTEST1

```
　cd /d D:\BAT\
　call .\bat2.bat
```


#####場所を"D:\BAT"に指定してBATTEST2を実行すると以下になる。
■BATTEST2

```
cd >> .\dir.txt
```

■dir.txt

```
D:\BAT
```



#####ただし、場所を"D:\BAT"に指定してBATTEST3を実行すると失敗する。
■BATTEST3

```
call .\bat2.bat
``
IntelliJ・WebStrom・PhpStorm等のJetBrains製IDEで、文字列の直前に「language=JSON」と書くと、その文字列にJSONのシンタックスハイライトが効いて便利だった。

IntelliJやWebStrom、PhpStormなどのJetBrains製IDEで、文字列の前に`// language=JSON`というコメントをつけると、IDEが文字列をJSONとして認識してくれるため、

* JSONとしてのシンタックスハイライト
* JSON構文エラーの警告
* JSONのコード補完
* コード整形

といった、地の文でJSONを書いたときにIDEがやってくれるような恩恵を享受できるようになる。


![language-json.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/6a874f0e-cfd6-11d1-0bfc-11398b358c6a.gif)


この機能は**Language Injection**と呼ばれるもの。コメントが書ける大抵の言語なら、JavaでもPHPでもJavaScriptでもScalaでも使えるようだ。

この機能はJSONに限ったものでなく、`language=SQL`や`language=HTML`などの`language_ID`を指定することで他の言語にも対応可能。

```js
// language=<language_ID>
```

<img width="452" alt="Screenshot_2019_08_21_12_44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/fad071da-c7cd-345d-17b4-b475fe67546d.png">


## PHPは`@lang`が使える

PHPではPhpDocの`@lang`でもLanguage Injectionすることができる。

<img width="754" alt="Screenshot_2019_08_21_12_32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/e2514295-d3df-f570-6d5c-65838899e626.png">

## Javaなどでは`@Language`アノテーションが使える

JavaやGroovy、Kotlinでは`org.jetbrains:annotations`をMavenなどの依存に追加することで、`@Language`アノテーションを使うことができる。Scalaには対応していない様子。

<img width="444" alt="Screenshot_2019_08_21_12_31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/c64234c3-672b-6b50-76f5-8afb76315ced.png">

## 参考文献

* [言語インジェクション - 公式ヘルプ | IntelliJ IDEA](https://pleiades.io/help/idea/using-language-injections.html#use-language-injection-comments)

## 所感

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">IntelliJやWebStrom、PhpStormなどのJetBrains製IDEで、<br><br>文字列の前に<br><br>// language=JSON<br><br>って書くと、<br><br>・JSONがシンタックスハイライトされる<br>・構文エラーが表示される<br>・補完がされる<br>・コード整形もできる<br><br>って知ってました？<br><br>僕は知りませんでした😌 <a href="https://t.co/2UphpOThoM">pic.twitter.com/2UphpOThoM</a></p>&mdash; suin❄️TypeScriptが好き (@suin) <a href="https://twitter.com/suin/status/1163854331340193792?ref_src=twsrc%5Etfw">August 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
mavenで外部ライブラリをパッケージする方法

mavenで外部ライブラリをパッケージする方法です。(spring boot使用時)
pom.xmlを以下のようにします。

	<dependencies>
		<dependency>
			<groupId>xxx.yyy.zzz</groupId>
			<artifactId>abcde</artifactId>
			<version>1.0</version>
			<systemPath>${basedir}/lib/abcde.jar</systemPath>
			<scope>system</scope>
			<optional>true</optional>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<includeSystemScope>true</includeSystemScope>
				</configuration>
			</plugin>
		</plugins>
	</build>


こうすることでabcde.jarがパッケージ化されたjarファイルやwarファイルに含まれます。
Wordpress における Bogo での多言語化対応

バージョンは

- WordPress 5.2.2
- Bogo 3.2.1

です。

Wordpress での多言語化対応に [Bogo](https://ja.wordpress.org/plugins/bogo/) を使用したのですが、いつくかハマったところがあったのでその記録となります。

## 多言語の投稿時に `slug` に `-2` が付与される 

- [スラッグが日英で同じにならない &#124; WordPress.org](https://wordpress.org/support/topic/%E3%82%B9%E3%83%A9%E3%83%83%E3%82%B0%E3%81%8C%E6%97%A5%E8%8B%B1%E3%81%A7%E5%90%8C%E3%81%98%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84/)

現象としては上記と同じになります。クリック投稿から `slug` を書き換えることで編集が可能となるようですが、誰が編集するかわからないという条件ではあまり現実的な解決策ではありません。

上記の問題は Gutenberg を使用していたときにのみ再現したため、classic-editor に戻すことで上記問題を解決しました。

## アーカイブページを言語別に作成したい

```php
$query = new WP_Query();
$args = array(
	'post_type' => 'posts', // カスタム投稿タイプならタイプ名
	'posts_per_page' => -1,
	'lang' => get_locale()
);
$posts = $query->query( $args );
```

## WP REST APIで言語別に取得したい

例えば日本語と英語であれば

 - 日本語 http://localhost/wp-json/wp/v2/posts
 - 英語 http://localhost/en/wp-json/wp/v2/posts

で取得できるようです。
TensorflowでRuntimeError: Missing implementation that supportsが出た場合の対処方法

あまり起こりえないことのようですが、発生した場合の対処方法です。

#■環境
Python3.7（Anacondaでインストール）

#■エラー内容
retrain.pyを実行時に、以下のエラーが発生する。
```RuntimeError: Missing implementation that supports: loader(*(‘C:\\Users\\Alber\\AppData\\Local\\Temp\\tfhub_modules\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’,), **{})
```

#■原因
以下のディレクトリ内が空っぽになっていることで起こっているようです。
```‘C:\\Users\\Alber\\AppData\\Local\\Temp\\tfhub_modules\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’
```

#■対処方法
tfhub_modulesフォルダを削除し、再度retrain.pyを実行します。
（tfhub_modulesフォルダは再作成されます）


#■参考文献
https://stackoverflow.com/questions/54029556/how-to-fix-runtimeerror-missing-implementation-that-supports-loader-when-cal
https://github.com/tensorflow/hub/issues/212
指定したディレクトリ以下を検索する

以下はカレントディレクトリ以下にある特定のファイル/ディレクトリを検索する場合の例.

# ファイルの場合

```
$ find ./ -name <file_name> -type f
```

# ディレクトリの場合

```
$ find ./ -name <directory_name> -type d
```
AirDrop痴漢に気をつけましょう

「AirDrop痴漢に気をつけましょう」

以前AirDrop痴漢に気をつけましょうというブログ記事をアップしていますが、
福岡でAirDrop痴漢が初摘発されました。書類送検されたとのことです。

ということで、みなさん今一度お手元のiPhoneの設定を見直しましょう。

## AirDropを普段は「受信しない」設定にする
受信設定をOffにしておけば勝手に送信されてくることはないので普段はオフにしておくことをおすすめします。

- 設定→一般→AirDrop
- コントロールセンター→ネットワーク設定のカードを長押しor強めに押す
（どちらの方法でも設定可能）

## iPhoneの名前を変える
送信者はiPhoneの名前を見て性別を判別して送っている可能性もあるので変えておくことをおすすめします。

- 設定→一般→情報→名前

## ブログ
まとめたブログ記事はこちらをご覧ください。
https://www.wow-creators.com/2019/07/12/【まとめ】airdrop痴漢やってみた/

### ニュース記事
https://news.livedoor.com/article/detail/16957054/
コンソールからRDSのリーダーを追加するときの注意点

# 要約
AWSコンソールからRDSでリーダーを追加するとき、AZを選択してからインスタンスタイプを変更するとAZの選択が"指定なし"に戻るので注意しましょう。

# 経緯
RDSのスペックを下げたかったので、フェイルオーバーでやろうと思ってインスタンスタイプが1段階低いリーダーを追加した。
CLI派だけどこのくらいならコンソールでいいやと思ってコンソールから実施した。
ap-northeast-1aに作りたかったのでAZを指定したつもりだったのに、ap-northeast-1cに作成されたのでやり直した。

### 検証
以下、やり直し時の検証

AZはap-northeast-1aが要件なので、AZを選択。
![SnapCrab_RDS · AWS Console - Google Chrome_2019-8-21_10-45-48_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214614/b8deeec6-00eb-c49e-88f1-14128dc1e636.png)

インスタンスタイプを変更。
![SnapCrab_RDS · AWS Console - Google Chrome_2019-8-21_10-46-10_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214614/3aba4542-c566-8276-b923-d2f0553484f7.png)

AZが指定なしに戻ってる！！！！
![SnapCrab_RDS · AWS Console - Google Chrome_2019-8-21_10-46-22_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214614/7972848b-6cf2-38cd-c5ea-5d2324c71e0d.png)

# 結論
コンソールから作業するときは実行前に確認しましょう。
これだからコンソールは嫌いなんだ…
SendGrid + CakePHPでWeb API利用時にTemplateを使う

SMTPを使うならいつものsetTemplateでテンプレートを指定できますが、Web APIを使う場合SendGridの純正ライブラリはCakePHP用に書かれたものではないためCakePHPのテンプレートを使うようになっていません。
テンプレートに値を埋めたテキスト(HTML)を取得して、addContentします。

宛先や件名の設定などは省略しているので公式を参照してください。

```php
// 実際はComponentにして使っています。以下のコードはControllerで使うことを想定しています

// Viewを自分でnewするので使えるようにしておきます
use Cake\View\View;

$view = new View($this->request, $this->response);

// $varsにはテンプレートで使う値が入ってます
// ['username' => 'テスト太郎']
// のような連想配列を想定しています
// viewに値を渡すとき使う$this->set()と同じなので設定できればどう書いてもいいです
foreach ($vars as $key => $value) {
    $view->set($key, $value);
}

// $templateにテンプレートを指定します
// Template直下から指定する必要があるので、
// いつものEmailテンプレートを使いたければ Email/text(またはhtml)/テンプレート名 にします
// これで$contentにテンプレートに値を埋め込んだテキストが入ります
$content = $view->render($template, false);

// マルチパートにしたければplain、html両方addContentします
if ($format == 'text') {
    $email->addContent('text/plain', $content);
} else {
    $email->addContent('text/html', $content);
}

$sendgrid = new SendGrid('API-KEY');
try {
    $response = $sendgrid->send($email);
    // ログは好きにしてください
    $this->log($response->statusCode());
    $this->log($response->headers());
    $this->log($response->body());
} catch (Exception $e) {
    $this->log('Caught exception: '. $e->getMessage(), LOG_ERR);
}
```

SendGridの例を書きましたが、Controller中でTemplateに値を埋めた状態のテキスト取得する方法は汎用的なので知っておくと他でも使えます。
CombineでObservable.create/SignalProducer.initに相当するPublisherを作る

Combine には当初、クロージャを通じて複数の値の出力と成否を送る Publisher (RxSwift における `Observable.create` または ReactiveSwift における `SignalProducer.init`) が実装されていたようなのですが、[途中で削除されてしまったらしい](https://github.com/freak4pc/rxswift-to-combine-cheatsheet)...
どうしても使いたい場面があったため、Combineの学習がてら自分で実装してみました。

こちらの投稿を参照にさせていただきました🙇‍♂️
https://qiita.com/shiz/items/58abf44b77d9da2042f1

```swift:SomePublisher.swift
import Foundation
import Combine

// 名前は適当です...
struct SomePublisher<Output, Failure: Swift.Error>: Publisher {
    enum Event {
        case value(Output)
        case finished
        case failure(Failure)
    }
    typealias Handler = (Event) -> Void
    private let handler: (@escaping Handler) -> Void

    private class Subscription<S: Subscriber>: Combine.Subscription where S.Input == Output, S.Failure == Failure {
        private var subscriber: S?
        private let handler: (@escaping Handler) -> Void

        init(subscriber: S, handler: @escaping (@escaping Handler) -> Void) {
            self.subscriber = subscriber
            self.handler = handler
        }

        func request(_ demand: Subscribers.Demand) {
            self.handler(self.handle)
        }

        func cancel() {
            self.subscriber = nil
        }
        
        private func handle(_ event: Event) {
            guard let subscriber = self.subscriber else {
                return
            }
            
            switch event {
            case .value(let input):
                _ = subscriber.receive(input)
            case .finished:
                subscriber.receive(completion: .finished)
            case .failure(let error):
                subscriber.receive(completion: .failure(error))
            }
        }
    }
    
    init(_ handler: @escaping (@escaping Handler) -> Void) {
        self.handler = handler
    }

    func receive<S>(subscriber: S) where S : Subscriber, S.Failure == Failure, S.Input == Output {
        let subscription = Subscription(subscriber: subscriber, handler: self.handler)
        subscriber.receive(subscription: subscription)
    }
}
```

使い方はこんな感じ。

```swift
func values(count: Int) -> SomePublisher<Int, Never> {
    return .init { (publisher) in
        // ここにストリームを実装する...
        for i in 0..<count {
            publisher(.value(i))
        }
        publisher(.finished)
    }
}
```

本当はイニシャライザを以下のような仕様にしたかったのですが、 `Subscriber` の管理と受け渡しがうまく実装できなかったので、 `Event` 型を使ってストリームする実装にしています。

```swift
    init<S>(_ handler: @escaping (S) -> Void) where S : Subscriber, S.Failure == Failure, S.Input == Output {
        ...
    }
```

Combineに実装が復活するといいですね。
Dockerを使ってAWS Lambdaのデプロイパッケージをビルドする（Python 3.7）

# はじめに
https://aws.amazon.com/jp/lambda/
最近AWS Lambdaを使用する機会が増え、Python3.7のデプロイパッケージのビルド処理を汎用化したので共有します。

AWS Lambdaではライブラリなどを一つのzipファイルにまとめたものをパッケージとしてアップロードする必要があります。
Windowsで開発する場合、OSの違いからライブラリをそのままzipするだけだと動かない場合もあります。
そこで、Dockerを使ってLambdaの環境を再現したうえでパッケージを作成するという処理を実装してみました。

# ソース
https://github.com/yusukey0720/lambda_packager_python
↑にいい感じにまとめてみたので参考にしてください。

# 使い方
※Dockerがインストールされていること。

## requirements.txt
* ここに必要なライブラリを記載。

```{txt:./src/requirements.txt}
numpy
pandas
```

## lambda_function.py
* ここに処理を記載する。

```{python:./src/lambda_function.py}
def lambda_handler(event, context):
    # some functions
```

## ビルドする
* 下記のコマンドからビルド処理を実行する。
    * Dockerが立ち上がる
    * requirementsをインストール
    * ソースをzipする
    * distに出力される

```{bash}
sh build.sh
```

## デプロイ
* distに出力されたファイルをs3にアップロード
* AWSコンソール画面からs3のパスを入力して保存

# さいごに
やはりDockerは便利ですね。
s3のアップロードやzipの反映まで自動化できるとより便利になるなと感じました。
不明点等あればコメントください。
【異常検知】学習データは0個でOK！？

[前回の記事](https://qiita.com/shinmura0/items/3d2e54604181fad6ebf0)では、ディープラーニング x ガウス過程の論文を紹介しました。
今回は、その応用をご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/b07478b9-7c33-f163-7975-30c17222b60a.png)

※コード全体は[こちら](https://github.com/shinmura0/Neural-Kernel-Network/blob/master/AnomalyDetection_GP.ipynb)に置きました。

#異常検知のプロセス
画像の異常検知を例にします。
ディープラーニングを使う場合は、通常は以下のプロセスが考えられます。

+ 正常な画像を集めてくる。画像の数は**多ければ多いほど良い**（少なくとも10枚以上）。
+ 必要に応じて、cifar-10などの正常画像と見比べる画像を用意する。
+ 集めた画像で学習実行
+ テストデータで推論実行

---

ところが、正常な画像がなく、いきなり異常検知を実行する場合はどうでしょうか？
つまり、以下のプロセスです。

+ **テスト画像(a)**が与えられる
+ **(a)**で学習実行
+ **(a)**で推論実行

そんなの無理だよ！と思われるかもしれませんが、前回ご紹介した論文を応用すると
可能になります。ただし、制約も多くあります。

#手法
前回紹介した論文（NKN）では、以下のようにマスクした部分を忠実に復元する
ことができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/9c91e52f-4f06-ab47-c002-bf05f42f74a0.png)

※上の図は論文より引用しています。

異常検知を行うには、まずマスクの位置を変えながら復元画像を生成します。
図にすると以下のとおりです。

![sigma2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/1ead0645-8ef2-2605-b6fb-0f9319ded3ff.gif)

左図は学習画像、マスクする部分を移動させながら、右図のように
再構成画像をつなぎ合わせていきます。

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/254e22dc-0475-79c9-60b8-5a978d788c87.png)


そして、上図のように元画像と再構成画像の差を比べ、差が大きいところを
異常と認識させます。

#結果
繰り返しになりますが、本手法は**学習データは不要で、テストデータそのものから
学習していく手法です。**

コード全体は[こちら](https://github.com/shinmura0/Neural-Kernel-Network/blob/master/AnomalyDetection_GP.ipynb)に置きました。Colab(GPU)で動くはずです。
NKNの著者のコードを**雑に**いじっており、かなり余分なコードも存在しています。


+ 落書きその1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/b07478b9-7c33-f163-7975-30c17222b60a.png)

左の図は、真ん中に落書きをしたものです。この画像を使って学習させました。
学習の手法は前述したとおりです。

真ん中の図は再構築画像です。落書きが見事に消えています。
右図は元画像と再構築画像の差をとったものであり、落書きの部分が赤くなっています。

+ 落書きその2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264781/c6a9053c-c7fe-f648-6101-a732c5401577.png)

左の図は、下の方に落書きをしたものです。この画像を使って学習させました。
真ん中の図は再構築画像です。落書きが見事に消えています。

右図は元画像と再構築画像の差をとったものであり、落書きの部分が黄色～オレンジに
着色されています。

もちろん、正常な画像で学習させると、ほとんど青いヒートマップになり、
実際の異常スコア（ピクセルの差）も小さくなります。

#制約
この手法は、学習画像が実質不要ということもあり、かなり実戦で使えそう！
と思った方もいらっしゃるかもしれませんが、かなり制約が多いです。

+ 学習時間
この手法は、テストデータ1枚に対しマスクを移動しながら学習を行います。
ディープラーニングを使った通常の処理、学習（時間がかかる）→推論（速い）
という概念は通用しません。学習と推論はセットで行っています。
従って、**リアルタイムの処理は不可能です**。

+ パターンの規則性
最初は[DAGM](https://qiita.com/leetmikeal/items/7c0d23e39bf38ab8be23#dagm-2007)のデータを使って試してみましたが、うまくいきませんでした。
パターンの規則性が、はっきりしているものじゃないとうまく機能しません。

#改善策
ただし、パターンの規則性については**正規化**を行えば改善する可能性が高いです。

正規化について説明する前に、ここでの異常スコアの算出方法を説明します。
異常スコアは以下の式を使っています。

```math
AnomalyScore=max(|x_i-\hat{x}_i|)
```

ただし、$x_i$は元画像のピクセル値、$\hat{x}_i$は再構築画像のピクセル値です。
ピクセルの差が一番大きいところを異常スコアにしています。

そして、ここでいう正規化とは以下の式で異常スコアを算出することを
意味しています。

```math
NewAnomalyScore=max(|\frac{x_i-\hat{x}_i}{\sigma_i}|)
```

ただし、$\sigma_i$はガウス過程により推定された標準偏差です。
著者の実装から$\sigma_i$を取り出そうとしましたが、中身が分からず諦めました。
どなたか分かる方が、いらっしゃれば教えてください。

#まとめ
+ NKNを使えば、学習データはいらず、テストデータのみで異常検知可能。
+ ただし、複雑なパターンの画像はうまくいかない。改善策はあるが、効果は未知数。
+ NKNによる異常検知は、学習時間が長いため、正常データが10個以上集められるときは「[ディープラーニングを使った異常検知](https://qiita.com/shinmura0/items/06d81c72601c7578c6d3)」を使うのが無難。
marked.jsのサニタイズ(エスケープ)2STEP

# marked.js便利ですよね
Markdownをプレビューしたり、HTMLで表示させる時にクライアント側で変換してもらうためにmarked.jsを使う事があると思います。
ですが、うっかりしてると結構**致命的**なミスを引き起こしてしまいます。
##前提
[marked|github](https://github.com/markedjs/marked)がすでに使える状態とします。
# STEP1  sanitize-html等のライブラリを入れる
Marked自身にもサニタイズオプションはありますが、現在それの使用は**非推奨**です。
> Warning: 🚨 Marked does not sanitize the output HTML. Please use a sanitize library, like DOMPurify (recommended), sanitize-html or insane on the output HTML! 🚨

環境にあったライブラリを選定して入れましょう。
私は[sanitize-html](https://github.com/apostrophecms/sanitize-html)を選びました。
#STEP2 サニタイズする
markedは`marked(text)`という形でtextをHTMLに変換した値を返してくれます。
sanitize-htmlは`sanitizeHtml(text)`とするとtextから`<script></script>`等を削除して返します。
簡単ですね。

では、あなたはこれら２つを使ってプレビュー付きのMarkdownエディタを作る時、この２つの関数をどのようにつなげますか?
(プレビューするだけならサニタイズの必要性は薄いのですが、一般に公開するときも同様の手順でサニタイズするとします)

フォームはこんな感じとします

```Nuxt:editor.vue
<template>
...
<textarea
 id="editor-content"
 :value="textareaValue"
 name="editor-textarea-content"
 @input="convertMarkdown"
 ></textarea>
<div id="editor-preview" v-html="convertHtml"></div>
...
</template>
<script>
const marked = require('marked')
const sanitizeHtml = require('sanitize-html')
const _ = require('lodash')
export default {
  head() {
    return {
      title: 'テストサイト'
    }
  },
  components: {
    headerComponent
  },
  data() {
    return {
      textareaValue: ''
    }
  },
  computed: {
    convertHtml() {
      //ここでmarkdownの変換と、エスケープ処理を行う
    }
  },
  mounted() {
    marked.setOptions({
      breaks: true
    })
  },
  methods: {
    convertMarkdown: _.throttle(function(e) {
      console.log(e.target.value)
      this.textareaValue = e.target.value
    }, 500)
  }
}
</script>
```
例がNuxtなので念の為解説すると、textareaに何か入力されたらconvertMarkdownが値を保存し、convertHtmlがそれを変換するという形です。、下のdivに内容がHTML化されたものが表示されるという感じで、他の部分は値の受け渡し等の設定と思ってください。
追記: 実用的にするため、`const _ = require('lodash')`を用いて、inputで関数が呼ばれすぎない様にしました。

ここでの書き方は大まかに２つあります。

```
  methods: {
    convertMarkdown() {
      const conbertContent = marked(this.textareaValue)
      this.convertHtml = sanitizeHtml(conbertContent)
    }
  }
```

と

```
  methods: {
    convertMarkdown() {
      const conbertContent = sanitizeHtml(this.textareaValue)
      this.convertHtml = marked(conbertContent)
    }
  }
```
です。どちらもサニタイズ関数を用いており一見問題ないのですが、これ**１つは簡単にJavaScriptを実行できてしまうんです**。

欠陥があるのは、先にサニタイズしている**2番目**の例です。
どちらもtextareaに`<script>alert(1);</script>`なんかを入れてもきっちり弾くので「よし、問題ないな」と思ってしまう事もあると思うんですが、
後者だと[bugbounty-cheatsheet](https://github.com/EdOverflow/bugbounty-cheatsheet/blob/master/cheatsheets/xss.md)のMarkdwodn xss例の
`[a](javascript:window.onerror=confirm;throw%201)`
の様なmarkedで展開されるリンクまでは完璧にサニタイズしてくれないので、ポップアップが出てきてしまいます。
# まとめ
***Markdownのサニタイズは一番最後!***
(ちなみにh1やh2はサニタイズで弾かれるので、適時許可しましょう)
Vuex Storeへのアクセス書き方まとめ

# storeへのアクセス

```javascript
// Componentから
this.$store

// それ以外
import store from 'path/to/store.js';
store
```

`export default new Vuex.Store()`してるファイルを読み込む。
Storeを別ファイルにしていない時はComponent以外からのアクセスはできない（と思う）。

# state
```javascript
// 基本形
this.$store.state.value;

// namespaceが設定されてるやつ
this.$store.state.namespaceName.value;

// contextからだと、namespaceに属するもののみになる
context.state.value;

// contextからルートのstateにアクセス
context.rootState.value
```

# getters
```javascript
this.$store.getters.doneTodos;

//namespaceが設定されてるやつ
this.$store.getters['namespaceName/doneTodos'];
```

`context`でも同様。

# mutations
```javascript
this.$store.commit('mutationName');

this.$store.commit('namespaceName/mutationName');
```

`context`でも同様。

# actions
```javascript
this.$store.dispatch('actionName');

this.$store.dispatch('namespaceName/actionName');
```

これも`context`でも変わらず
`dispatch()`はPromiseを返すので`then()`とか`await`できます。

# mapGetters()
`...`はスプレッド構文。配列を展開して列挙してくれる。

```js
// ルートに記述しているgetters
computed: {
    ...mapGetters(['doneTodos']),
}

// モジュール化してるやつ
computed: {
    ...mapGetters('namespaceName', ['doneTodos']),
}
```

# mapState()
こちらも`mapGetters()`と同じように使える。

```js
computed: {
    ...mapState(['state'])
}
```

```js
computed: {
    ...mapState('namespace', [
        'state',
    ])
}

```

```js

computed: {
    ...mapState('namespace', [
        'state',
    ])
}

```
【メモ】よく忘れるコマンド集

# よく忘れるコマンド集

## "pattern" の検索
```bash
grep -rnw 'directory' -e "pattern"
```
## 重複ファイルの検索
```bash
sudo apt install fdupes #fdupes が無い場合
fdupes -r ./ > duplications.txt
cat duplications.txt
```
```
他に
rdfind path-to-treat
```
## ファイル名の空白をアンダースコアに変換
[ファイル/ディレクトリ名に空白が入っているファイル/ディレクトリの空白を下線_に置換するワンライナー](https://www.nemotos.net/?p=674)から転載

```bash
find . -name "* *" | rename 's/ /_/g'
```

## 各ディレクトリのファイル数を数える/ファイル数の多いディレクトリの抽出
```bash
for d in `find hogehoge -type d`; do echo $d,`ls "$d" | wc -l`; done | cat > files.txt
awk 'BEGIN{FS=","}{i=NF; if ($i > 500) print $0}' files.txt > so_many_files.txt
```

## gfortran で fftw3 を使ってコンパイルするよ
```bash
gfortran hoge.f90 hoge1.f90 -I/usr/include -lfftw3 -ohoge.x
```

## rsync 関係
[rsync 関係](https://qiita.com/rpscrw/items/55d4e27015ae464e7427)

## Linuxで「特定の文字列を含むファイルを全て検索する」ためのコマンド
[http://qiita.com/kenju/items/9bebc75df1e0b3c3ee9b](http://qiita.com/kenju/items/9bebc75df1e0b3c3ee9b)からの転載

```bash
##########################
# grep
#   -r : 再帰的にgrepコマンドを実行する
#   -n : 行番号を出力する
#   -w : 文字列全体にマッチする場合
#   -l : (option)これをつければファイル名だけを出力（マッチした部分は省く）
#
# Usage
#   # 現在いるディレクトリ配下から「httpd」という文字列を含むファイルすべてを抽出する
#   $ grep -rnw . -e "httpd"
##########################
$ grep -rnw 'directory' -e "pattern"
```

## ディレクトリの使用量を確認する
```bash
du -h --max-depth=1
```
（辿る階層は任意。上の例では、カレントディレクトリに存在する子ディレクトリの容量を表示する。）

## UUIDの確認
```bash
blkid
lsblk -f
```

## Linuxバージョンの確認(Ubuntu)
```bash
uname -a
cat /etc/issue
cat /etc/lsb-release
cat /proc/version
```

## Linuxステータス関係ツール
```bash
free
top
# 3rd party
htop
vtop
gtop
slurm
screenfetch
```
## ハードウェア情報など
```bash
cat /proc/cpuinfo # CPU
cat /proc/meminfo # Memory
# /proc には様々なハードウェア情報がある
df -h             # HDD
fdisk -l
sudo dmidecode    # マザーボード情報
```

## 停電対応
```bash
> sudo at -t 201612100000
```
入力待ちになるので、

```
> shutdown -h now
> ([CTRL] + [D]) #キーコンビネーション
```
と打てば、

```
job 4 at Sat Dec 10 00:00:00 2016
```
のように返ってくるはず。

## Dropboxの再起動
```bash
> dropbox stop
> dropbox start
```
Dropboxが停止している場合、

```
Dropbox isn't running!
```
と言われる。'dropbox start'　で起動時にも

```
Starting Dropbox...Dropbox isn't running!
Done!
```
<p><del>と言われるが、同期は再開するようである。</del></p>

と出る場合は、やっぱりダメかも。リモートから X forwarding している場合、
しばらくすると、

```
connect localhost port 6000: Connection refused
```
というエラーが出て同期しない。Xなしでログインしていれば、問題無く以下のようなコメントを吐いて同期を開始する。

```
Starting Dropbox...Done!
```

## トンネルを掘る
```bash
ssh -N -f -L10022:xx.xx.xx.xx:22 -L10080:xx.xx.xx.xx:80 user@host
```

## ポート番号指定＋暗号鍵
```bash
ssh -p[port no.] -i ~/.ssh/rsa_key user@host
```

## Mac OS Catalina で SIP disable の後
コマンドそのものというより、やり忘れることが多い...

```bash
sudo mount -uw /
```
【メモ】解析で使ったワンライナーたち

# 解析で使ったワンライナーたち
#### 一時保管場所につき説明なし
```bash
cat 81_latlon.txt | gawk 'BEGIN{OFMT="%.12f"}{print int($3/100)+ ($3 % 100)/60, int($2/100)+ ($2 % 100)/60}'  > OB20-12_shot_lonlat.gmt
```
```bash
sudo /etc/ifplugd/action.d/action_wpa wlan0 up
```
```bash
for f in `ls`; do echo "[" $f "]"; cat $f | grep gmt; done #ファイル名＋検索結果
```
```bash
cat duplications.txt | sed -e 's/^/#rm -v \"/' | sed -e 's/$/\"/' | sed -e 's/#rm -v \""//g' > deletion.sh
```
```bash
paste n.txt s.txt | sed -e 's/\t/ /g' | awk '{print ">\n"$1,$2"\n"$3,$4}' > mbes_plan_001b.txt
```
```bash
# タグの削除(KML)
cat 20180610-01.kml |  grep coord | sed -e 's/<[^>]*>//g' | sed -e 's/^[ \t]*//g' | sed -e 's/\s/, /g'
cat 20180610-01.kml |  grep when | sed -e 's/<[^>]*>//g' | sed -e 's/^[ \t]*//g' | sed -e 's/\s/, /g'
```
```bash
for dn in `ls -l | awk '$1 ~/d/ {print $9}' | grep -e 'E\.' -e 'EV\.' | grep -v -e status`;  do rm ${dn}/node.txt ${dn}/status.html ${dn}/status_err.html ${dn}/temp_out.txt ${dn}/tmp_out_node.txt; done
```
```bash
cat 934_S18_Tr694_R149_HD1.log | grep ^G | awk '{print $2}' | sed -e 's/\[/ /g' | sed 's/\]/ /g' | sed 's/,/ /g' | awk '{print $1}' | sort | uniq > ~/raid1/tmp/934_X1.txt
```
```bash
cat EVENT.LOG | grep "B=" | awk '{print $2}' | sed -e 's/B=//g' | sed -e 's/,/ /g' | awk '{print $1}' | sort | uniq
```
```bash
for fn in `cat status_list2.txt`; do awk '{if($4 == "'${fn}'") print $14,$15}' /dat/etc/channels_merged.tbl | grep -v '^\s' | uniq | awk '{print "'${fn}'",$1,$2}' ; done
```
```bash
cat otari_list_S.txt | awk '{print $2,$3}' | sed -e 's/\///g' | sed -e 's/://g' | tr ' ' . | cut -c 1-13 | awk '{print "trg/"$1}' > pick.list
```
```bash
for file in `cat pick.list.old | cut -c 1-15 | sed 's/$/*/g'`; do ls $file >> otari_L.txt; done;
```
```bash
awk 'FS=","{if($6!="") print $1,$2,$3,$4,$5,$6,$7}' Kumamoto_checksheet_OTK_utf.csv |sed 's/\// /g' | sort -k8n -k9n | awk 'OFS=","{print $1,$2,$3,$4,$5,$6"/"$7"/"$8,$9,$10}' > Kumamoto_SAKOTK.csv
```
```bash
find trg/ -type f -print | egrep -v 'done|ch|BUSY|OLDEST|LATEST|COUNT|FREESPACE' | sort -k1n | cat -n | sort -k1nr | awk '{print }'
```
```bash
find -type f | egrep -v 'CNF|TXT|XML|LOG' | xargs winadd -v
```
```bash
for f in `ls raw`; do winadd raw$f /tele/raw$f; done;
```
```bash
for f in `ls ./`;do cat $f | wck | awk '(NR==25) {printf("%12.2f %d %s \n",'$f',$5,$6)}'; done >> ../nofch.txt
```
```bash
for f in `ls raw/`; do raw2mon < raw/$f > mon/$f; done
```
【メモ】ディスプレイをオン/オフするコマンド

#ディスプレイをオン/オフするコマンド

```bash
> xset dpms force on
> xset dpms force off
> xset dpms force standby
```

リモートから行いたい場合、DISPLAYを明示。

```bash
> xset -display :0 dpms force on

または環境変数を書き換える。
> export DISPLAY=:0
(確認)
> env | grep DISPLAY
DISPLAY=:0
```
mouseleave などで消えてしまう要素を setTimeout + debugger で無理やり捕まえる

1. Google Chrome Dev Tool のコンソールで setTimeout + debugger を仕込む
2. 時間が切れないうちに表示したい要素を表示させる
3. setTimeout -> debugger が発火して要素選択できるようになる (mouseleave しても停止中なので消えない)

```js
setTimeout(function() {
  debugger;
}, 3000);
```

CSS Trick にも同じ内容のものがあった

Set a Timed Debugger To Web Inspect Hard-To-Grab Elements
https://css-tricks.com/set-timed-debugger-web-inspect-hard-grab-elements/
【メモ】AWK で 1行目が無視される

# AWK で 1行目が無視される
#### (空白行が出力される)

CSVファイルを処理したい時、

```awk

awk '{FS=","; print $2}' hoge.csv
```
とすると、1行目が空白行として出力されて用をなさない。
正しい文法に従って、

```awk
awk 'BEGIN{FS=","}{print $2}' hoge.csv
```
とすれば、問題ない。
rsync 関係の備忘録

# rsync 関係
## オプション
これはmanページを見るべし。解説記事も山ほど([例えば](https://qiita.com/bezeklik/items/22e791df7187958d76c1))あり。

## 大量に転送するとき
オプション --partial --append をつけるべし。再開時に途中から転送される。

## rsync で samba に送ると途中停止する時

ここの[リンク](https://serverfault.com/questions/364709/how-to-keep-rsync-from-chowning-transfered-files)に書いてあるとおり、

```bash
sudo rsync -rlptDuv --progress [other option] [src] [dest]
```

などとするのが良い。 -auv とすると chown が通らずにフリーズする。

## rsync でファイルサイズを限定する
```bash

rsync -auv --progress --max-size=10M [source] [destination]
# 2G など単位付きで指定できる模様
```

## rsync で帯域制限をかける
```bash
#通常のコピーは
rsync -auv --progress [source] [destination]
#帯域制限をかけたい場合、kB/s単位で以下のオプションを加える
rsync -auv --bwlimit=200 --progress [source] [destination]
```

## 差分バックアップ（履歴あり）
```bash

#!/bin/bash

source=/foo
  dest=/bar

previous=$(ls -1t ${dest} | head -1)
if [ -z "${previous}" ]; then
  rsync -av ${source} ${dest}"hoge-"$(date +%Y%m%d-%H%M)
else
  rsync -av --link-dest=${dest}${previous} ${source} ${dest}"hoge-"$(date +%Y%m%d-%H%M)
fi
```

### 関連記事
 - [rsyncの--link-destでの差分バックアップ](https://jyn.jp/bash-rsync-link-dest/)
 - [rsyncを使って過去の変更・更新履歴だけを切り出す「差分バックアップ」を行う](https://webnetforce.net/rsync-backup/)
プログラミング初心者の備忘録ーお問い合わせフォーム編

# はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているMaomao Maoです。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

今回は、お問い合わせフォームを作ってみようと思います。

##お問い合わせフォームを作る
<p>メールアドレスの入力欄を作る</p>
メールアドレス入力欄は1行入力欄を作ります。
その際、__input__を使用します。

<p>お問い合わせ内容入力欄を作る</p>
お問い合わせ内容入力欄には、複数行入力できるようにします。
その際、__textarea__を使用します。

```
<form>

<p>メールアドレス</p>
<input>

<p>お問い合わせ内容</p>
<textarea></textarea>

</form>
```

<p>送信ボタンを作る</p>
送信ボタンにも、__input__を使います。

```
<input type="submit">
```
ボタンのテキストを変えたい場合は、__value__を使います。

```
<input type="submit" value="保存">
```
【メモ】Linuxでunzipすると文字化けする対策

# Linuxでunzipすると文字化けする対策

下記に従い、unar コマンドを使うと良さそう

[日本語を含むZIPファイルを文字化けせず解凍する方法](https://qiita.com/hoo89/items/46dcd8134061c392772f)
【メモ】ディスクイメージのマウント

# ディスクイメージのマウント

E.BC4 に設置した Raspberry Pi の SD カードをバックアップした。内容を確認するためにマウントした際のメモ。

パーティションの確認。

```bash
$ parted RPi_EBC4.img unit B print
```
```bash
警告: 管理者権限がありません。パーミッションに注意してください。
モデル:  (file)
ディスク /mnt/raid1/tmp/RPi_EBC4.img: 8068792320B
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos
ディスクフラグ:

番号  開始       終了         サイズ       タイプ   ファイルシステム  フラグ
 1    4194304B   47185919B    42991616B    primary  fat32             lba
 2    47185920B  8068792319B  8021606400B  primary  ext4
```

2番目のパーティションをマウント。

```bash

$ sudo mount -o loop,offset=47185920,sizelimit=8021606400 RPi_EBC4.img /mnt/usbstick/
```

マウント後の確認、アンマウント。

```bash

$ ls /mnt/usbstick/
bin   dev  home  lost+found  mnt  proc  run   srv  tmp  var
boot  etc  lib   media       opt  root  sbin  sys  usr
$ ls /mnt/usbstick/home/pi/
Arduino                        bmp280robust.py  index.html  png             tplog.txt
arduino-1.8.2                  data             mkdata.sh   thplog.1.txt    vpneri.sh
arduino-1.8.2-linuxarm.tar.xz  hub-ctrl         mkplot.plt  thplog.txt
bme280robust.py                hub-ctrl.c       nohup.out   thplog.txt.org
$ sudo umount /mnt/usbstick
```