OmniAICreator/Qiita-1.07M huggingface dataset:
バッチで同じ拡張子のファイルをマージする

[バッチでLhaplusコマンドを使用してファイルを自動解凍する](https://qiita.com/atsnsgw/items/255cc5d6fc64241ea54b)
に引き続き、今度はファイルをマージするバッチになります。
# 環境
Windows 10
Lhaplus 1.74 （投稿時）
コマンドプロンプト
# 完成品
```
@echo off
rem 親フォルダ以下の各フォルダ内で、指定した拡張子のファイルをマージするバッチ
setlocal enabledelayedexpansion

rem ◆変数定義◆
set LOG_FILE=%CD%\log_file.txt
set CURRENT_DIR=%CD%
set S_DATE=%DATE%
set S_TIME=%TIME%
set IS_MERGED_DIR=FALSE

rem ■メイン■
echo "親フォルダ以下の各フォルダ内で、指定した拡張子のファイルをマージします。"
call :guidanceExtention
call :guidanceStart
call :cfmAndDelDir
call :merge
call :dirSearchAndMerge
goto :mergeEnd

rem ◆ガイダンス（拡張子）◆
:guidanceExtention
set /p RES1="マージ対象ファイルの拡張子を入力してください。...[拡張子を入力] "
exit /b

rem ◆ガイダンス（開始）◆
:guidanceStart
set /p RES2="マージを開始しますか？...[Y/N] " 
if /i %RES2%==Y exit /b
if /i %RES2%==YES exit /b
goto :END

rem ◆mergedディレクトリ存在確認◆
:cfmAndDelDir
for /r /d %%1 in (*) do (
	cd %%1
	if /i exist merged (
		echo 削除対象ディレクトリ：%%1\merged
		set IS_MERGED_DIR=True
	)
)
cd %CURRENT_DIR%
if /i %IS_MERGED_DIR%==True call :deleteDir
exit /b

rem ◆一括フォルダ削除◆
:deleteDir
set /p RES3="上記の出力先フォルダが既に存在します。削除してもよろしいですか？...[Y/N] "
if /i %RES3%==Y goto :delOK
if /i %RES3%==YES goto :delOK
goto :END
:delOK
for /r %%2 in (merged) do (
	rmdir /s /q "%%2" > nul 2>&1
)
echo 上記ディレクトリを削除しました。
exit /b

rem ◆実行ディレクトリ配下のディレクトリを調査◆
:dirSearchAndMerge
for /r /d %%3 in (*) do (
	cd %%3
	call :merge %%3
)
exit /b

rem ◆マージ処理◆
:merge
if exist *.%RES1% (
	rem merged.*が無ければ、ディレクトリ作成＆マージ処理
	if not exist merged.%RES1% (
		mkdir merged
		echo マージ作業ディレクトリ：%1
		copy /b *.%RES1% merged\merged.%RES1%
	)
)
exit /b

rem ◆終了処理◆
:mergeEnd
echo マージ処理が終了しました。プログラムを終了します。
echo 開始日時：%S_DATE% %S_TIME%
echo 終了日時：%DATE% %TIME%
pause

:end
exit
```
# 使い方
**※この記事のコードを使用したことにより不都合、不利益が生じても責任は持てませんので使用する際は自己責任でお願いします。**
①上記コードをbatで保存。（この時必ず、改行コードはCRLF、文字コードはSJISで保存してください。でないと上手く動作しません。）
②保存したbatファイルをマージしたいファイルがあるディレクトリで実行します。
③画面の質問に応じ、拡張子、開始するしないを入力すると**まず出力用のディレクトリが既に存在しないかをチェックし、存在する場合マージを実行する前に削除するかどうかを問います。その後、各ディレクトリに指定した拡張子のファイルが存在する場合、各ディレクトリ毎にマージしファイルをmergedフォルダに出力してくれます。**
# 苦労したところ
 - 一番初めの実行ディレクトリ内の処理を考えるのに時間がかかった。callコマンドで実行する順番を変えて対応した。

# おわり
色々ネットを彷徨う中でログも保存しておけたらいいかも！と調べて、typeコマンドを使用する方法を試してみましたがtypeコマンドは実行する毎にファイル内容をすべて読み込むので今回は見送りました。今思えば最後にtypeコマンドを一回だけ実行すればよかったのかも...？
とにかく、できあがってよかったです。
OVRDebugConsoleが使用できない(場合もあります)

# はじめに
Oculus Questの開発でデバッグする際にOVRDebugConsoleをよく利用しているのですが、
最近使用できない状況があり、理由がわかるまでにちょっと時間がかかったので、
同じような状況があればお役に立てればと思います。

#開発環境
Unity 2019.1.9f1
Oculus Integration for Unity - 1.37

#発生した現象
あるコードにOVRDebugConsole.Logを追加したところ、以下のエラーが発生し、ビルドが通りませんでした。
<pre>
error CS0103: The name 'OVRDebugConsole' does not exist in the current context
</pre>

#原因
スクリプトのコンパイル順が原因でした。
Unityのマニュアルを見ると、コンパイル順序はPhase1～4があり、OVRDebugConsoleは"Assembly-CSharp"に含まれるのでPhase3になります。
一方、問題のコードは"Assembly-CSharp-firstpass"に含まれており一番先頭のPhase1のため、
OVRDebugConsoleは参照できない状況になっていました。
(どこに含まれるかは、Projectウインドウでスクリプトを選択したときに、InspectorのAssembly Informationに表示されます)
[特殊フォルダーとスクリプトのコンパイル順]
(https://docs.unity3d.com/ja/current/Manual/ScriptCompileOrderFolders.html)

#そのほか
今回、Runtime Inspector & Hierarchyというアセットを使おうとしてうまく動かなかったため、調査しようとして上記現象に遭遇しました。
[Runtime Inspector & Hierarchy]
(https://assetstore.unity.com/packages/tools/gui/runtime-inspector-hierarchy-111349)

InspectorとHierarchyを実機上で動かせるという大変便利そうなアセットで、Oculus Goでは動かした人がいるようなので、Oculus Questでも動かせると考えたのですが、自分の環境ではHierarchyは表示されるがInspectorが表示されないという現象になっており・・・未解決です。
[VR開発中にOVRRaycasterで少しハマった話]
(https://qiita.com/tamalign/items/4d887717455bab66a7bf)
What are the role and responsibilities with experience wise in selenium?

Selenium is one of the most preferred and popular automation testing tool. Whether you are an experienced or a fresher in selenium, you will always find a great career path in it.

Roles and responsibilities in selenium for experienced(1 year)
➔ Defect running track
➔ Debugging test cases
➔ Fixing errors
➔ Test reporting
➔ Enhancing test cases using java programming
➔ Generating test cases using selenium

Roles and responsibilities in selenium for experienced(2 years)
➔ Collecting database for data driven testing
➔ Analyzing test result
➔ Analyzing test reports
➔ Synchronization and parameterization
➔ Creating test cases using Java and TestNG annotations or using selenium webdriver
➔ Performing regression testing
➔ Creating test automation resources
➔ Defining test results
➔ Creating reusable components
➔ Error handling
➔ Parallel test execution


So these are the major roles and responsibilities for 2 years experienced in selenium automation testing. If you are interested in testing field, then go for selenium testing,  as it is the best automation testing tool in today’s IT.You can get free <a title="Selenium tutorial" href="https://intellipaat.com/tutorial/selenium-tutorial/introduction/">Selenium tutorial</a> here to learn selenium completely with the best experience and become skilled in selenium testing to get the best opportunities as a software tester in selenium.
ダイジェスト認証(RFC2617)の仕組み

#ダイジェスト認証(RFC2617)とは
　ダイジェスト認証とはHTTPの認証方式の一つ。BASIC認証と対比されることが多く、BASIC認証では防げない盗聴や改ざんを防ぐために考案されたもの。
　ここでは簡単にダイジェスト認証について学んだので公開してみます。

※一般的にダイジェスト認証は、SSL/TLSを使用している場合にBASIC認証でも安全性は高いと言われているが、リスクヘッジの面で実装しておくとさらに安心です。

##パラメータ
下記パラメータをAuthorizationヘッダに入ります。

・username
・realm
・algorithm
・qop
・URI
・nonce
・cnonce
・nc
・response

(別途)
ヘッダには含まれませんが、passwordを用意しておく必要があります。

###username
ユーザー名。
###realm
認証領域。
###algorithm
ハッシュ関数(通常MD5)
###qop
Quality of protectionの略
authかauth-initが入り、auth-initの場合bodyもハッシュ計算に使用される。
###URI
URIまたはパス
###nonce
サーバ側から返すランダムな文字列
###cnonce
Client nonceの略(多分)
クライアント側で渡すランダムな文字列
###nc
同じnonceを使用する場合のカウント値
00000001 → 000000002
みたいな感じ
###response
ここがダイジェスト認証のキモ
ダイジェスト認証ではこのresponseが計算しにくいことでリプレイアタックなどの攻撃を防いでいるそうです。

下記計算方式
algorithum = MD5
qop = auth
とする。

A1 = username ":" realm ":" password
A2 = HTTPメソッド ":" URI
response = MD5(MD5(A1) ":" nonce ":" nc ":" cnonce ":" qop ":" MD5(A2))

##安全性
　ダイジェスト認証では、上記のresponseが計算しにくいことで安全性を保っています。下記メリット例
　★通信が盗聴されても、responseの値からpasswordを導き出すことはほぼ不可能
　★見た目上はBASIC認証と変わらないので、認証方式がダイジェスト認証ということを隠すことができる。
(初回リクエスト時はBASIC認証と同じため)
　★nonce,cnonceが常に変わる続けるため、もしどちらか一方がバレてもresponseはバレない
　

#ハッシュ方式について
現在はMD5では弱いという業界的な意見もあり、SHA-256を使用することが推奨されています。(RFC7616)
フロントの使える構文(JavaScript,TypeScript)ってどこ見たらいいの？

# 前提とゴール
- 誰かがフロントのベースは作ってくれた
- どういう構文使えるのかわからん
  - 参照するリファレンスの場所、なぜそれを見るのか、がわかればゴール
- 個人的な所感です
  - それは見ないでくれ、みたいな記事が多すぎるため
  - flow,Angularなど、使ったことないので外していますが、結論はきっと同じです

# そのフロントは何で書かれている？
## 1. Babel(らしい)
### 見る場所
MDNのJavaScriptのリファレンス
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference

### 理由
Babelはcoreとpluginにわかれており、読み込んでいるpluginにより、使える構文がかわります
pulginは、ECMAScriptという仕様を元に用意されています
MDNのリファレンスには、いい感じにECMAScriptの仕様がまとまっています

MDNのリファレンスを見て書いた構文がエラーになった場合、フロントのベースを作った人に聞きましょう
エラーは、pluginが足りていないか、Babelの設定がよくない、あたりが原因です
適当にググって古い情報にあたると消耗します


## 2. TypeScript(らしい)
### 見る場所
公式のリファレンス

メニューの `Handbook` に、基本的な構文があり、
https://www.typescriptlang.org/docs/handbook/basic-types.html

メニューの `What's New` に、TypeScriptのversionごとの追加的な仕様が書いてあります
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html

そして、MDNのJavaScriptのリファレンス
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference

### 理由
ECMAScript＋TypeScript特有の構文、が使えます

MDNのリファレンスを見て書いた構文がエラーになった場合、フロントのベースを作った人に聞きましょう
エラーは、TypeScriptの設定がよくない、TypeScriptではまだ使えない、あたりが原因です
適当にググって適当な情報にあたると激しく消耗します


## どこにもない構文だった
後述するReactとかのライブラリの都合である可能性はありますが、Web APIかもしれません

### 見る場所
MDNのWeb APIのリファレンス
https://developer.mozilla.org/ja/docs/Web/API

### 理由
`Fetch API` や、 `DOM` 、 `Service Worker API` などは、JavaScriptとは別の仕様の話です
MDNのリファレンスに、いい感じにまとまっています


# React？Redux？Vue？Vuex？
## 1. React(らしい)
### 見る場所
公式のリファレンス

`MAIN CONCEPTS` に、JSXなど基本的な書き方が並んでおり、
https://ja.reactjs.org/docs/introducing-jsx.html

`ADVANCES GUIDES` に、TIPS的な内容が書いてあります
https://ja.reactjs.org/docs/accessibility.html

慣れてきたら `API REFERENCE` に、細かく書いてあります
https://ja.reactjs.org/docs/react-api.html

TypeScriptを使っている場合は、 **TypeScript側** にもJSXについてのリファレンスがあります
https://www.typescriptlang.org/docs/handbook/jsx.html

### 理由
JSXはReactの書き方です
Reactだときちんと認識して、公式を見ましょう
TypeScriptの兼ね合いは、どこを見ればいいのかややこしいですね


## 2. Redux(も使っているらしい)
### 見る場所
公式のリファレンス

`Basic Tutorial` に、基本的な概念が並んでいます
https://redux.js.org/basics/actions

慣れてきたら `API Reference` に、細かく書いてあります
https://redux.js.org/api/api-reference

### 理由
ReactとReduxは混ざりがちで、どちらの概念なのかわかりづらいと思います
ざっくり言うと、Actions, Resucers, StoreはReduxの概念なので、
Reactのリファレンスを見ても書いてないです、Reduxのリファレンスを見ましょう


## 3. Vue(らしい)
### 見る場所
公式のリファレンス

右上のメニューの `学ぶ > ガイド` に、基本的な内容が書いてあります
https://jp.vuejs.org/v2/guide/syntax.html

慣れてきたら `学ぶ > API` に、細かく書いてあります
https://jp.vuejs.org/v2/api/

TypeScriptを使っている場合は、 **Vue側** にリファレンスがあります
https://jp.vuejs.org/v2/guide/typescript.html

### 理由
VueはJSXとも違う書き方をします
(JSXでも書けますが、たぶん書いてないでしょう)
公式を見ましょう


## 4. Vuex(も使っているらしい)
### 見る場所
公式のリファレンス

右上のメニューの `ガイド` に、基本的な概念が並んでいます
https://vuex.vuejs.org/ja/guide/state.html

慣れてきたら `APIリファレンス` に、細かく書いてあります
https://vuex.vuejs.org/ja/api/

### 理由
VuexもReduxと同じく、Vueと概念が混ざりがちです
ざっくり言うと、Store, State, Getters, Mutations, ActionsあたりはVuexの概念です
Vuexのリファレンスを見ましょう

## 補足
プラグインなどで、公式のリファレンスには書いてない書き方も多くあります
`package.json` を開いて、フロントのベースを作った人に、 `この書き方はどのプラグインか？` 聞きましょう

# まとめ
Qiitaを閉じて、MDNのリファレンスと、ライブラリのリファレンスを見ましょう
とてもメンテナンスされているからです
C#学習　-非同期処理-

C#学習中のため、学習内容をメモしていく。
間違いやアドバイスがあればコメントからよろしくお願いします。

#Task処理
Task処理に関して少し勘違いしていたのでメモ

```C#
        void TaskSample()
        {
            Task.Run(() =>
            {
                HeavyMethod();
            });

            Console.WriteLine("おはよう");
        }

        void HeavyMethod()
        {
            // 重い処理
            Thread.Sleep(1000);
            Console.WriteLine("こんばんは");
        }

```

```
おはよう
こんばんは
```

別メソッドで非同期に動く処理はTask.Runで囲まれたHeavyMethodメソッドのみ。「おはよう」表示処理はHeavyMethodメソッド後に実行されると勘違いしていた。

「おはよう」表示を「こんばんは」より後にしたい場合は、HeavyMethodメソッドの終了を待つようにする。

```C#
        async Task TaskSample()
        {
            await Task.Run(() =>
            {
                HeavyMethod();
            });

            Console.WriteLine("おはよう");
        }

        void HeavyMethod()
        {
            // 重い処理
            Thread.Sleep(1000);
            Console.WriteLine("こんばんは");
        }
```

```
こんばんは
おはよう
```

HeavyMethodメソッドの戻り値を受け取りたいときはこうする。

```C#
        async Task TaskSample()
        {
            string str = await Task.Run(() => HeavyMethod());

            Console.WriteLine(str);
        }

        string HeavyMethod()
        {
            // 重い処理
            Thread.Sleep(1000);
            Console.WriteLine("こんばんは");

            return "こんにちは";
        }
```

```
こんばんは
こんにちは
```

string str = await Task.Run(() => { HeavyMethod(); });
{}をいれいると「型voidをstringに暗黙的に変換できません」とエラーになる。


#参考した記事
https://qiita.com/acple@github/items/8f63aacb13de9954c5da

https://qiita.com/Alupaca1363Inew/items/0126270bca99883605de


おわり。
Leetcode #127: Word Ladder

```swift
func ladderLength(_ beginWord: String, _ endWord: String, _ wordList: [String]) -> Int {
    if !wordList.contains(endWord) {
        return 0
    }
    let wordList = Set(wordList)
    let alphabets: [Character] = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","x"]
    var queue = [beginWord]
    var steps = 1
    var visited = Set<String>()
    while !queue.isEmpty {
        for _ in 0..<queue.count {
            if queue[0] == endWord {
                return steps
            }
            var word = Array(queue.removeFirst())
            for i in 0..<beginWord.count {
                for char in alphabets {
                    let tmp = word[i]
                    if word[i] != char {
                        word[i] = char
                        let str = String(word)
                        if wordList.contains(str) && !visited.contains(str) {
                            visited.insert(str)
                            queue.append(str)
                        }
                        word[i] = tmp
                    }
                }
            }
        }
        steps += 1
    }
    return 0
}
```
Leetcode #752: Open the Lock

```swift
func openLock(_ deadends: [String], _ target: String) -> Int {
    if deadends.contains("0000") {
        return -1
    }
    var queue = ["0000"]
    var visited = Set(deadends + queue)
    var step = 1
    while !queue.isEmpty {
        var temp = [String]()
        for status in queue {
            let chars = status.utf8
            for (i, char) in chars.enumerated() {
                let pre = String(chars.prefix(i))!
                let suf = String(chars.suffix(4-i-1))!
                for j in [1, 9] {
                    let e = (Int(char) - 48 + j) % 10
                    let str = pre  + "\(e)" + suf
                    if target == str {
                        return step 
                    }
                    if !visited.contains(str) {
                        visited.insert(str)
                        temp.append(str)
                    }
                }
            }
        }
        queue = temp
        step += 1
    }
    return -1
}
```
bit Sugoroku

#課題文
Carol は特殊なすごろくをしようとしている。

1からNの番号がふられている一直線に並べられているN個のマスがある。
1から開始のマスとして、ゴールはNが書かれているマスとする。

その場に書かれている数字の2進数で表現した時の1のビット数 だけ「前」または「後」に進めることができる。
(1未満とN+1以上のマスには移動することは出来ない、正確にNにならないとゴールできない）

自然数Nを与えられた時、ゴールに到達できる最短の移動数（開始のマスへも移動にカウントする）を求めてください。
到達できない場合は-1を出力してください。

開始のマスがすでにゴールになっている場合もあリます。

#入力値 N
マスの数を表す整数N(1≤N≤10000)が与えられます。

#ソース
```php
<?php
//入力値
$nyu = 1;

//結果値となる元
$number = 1;
$here = 1;
$array = [1];

//入力値を2進数に変換して1bitだけ取得する
for ($i=1; $i<$nyu; $i++) {
    $number_2sin = decbin($here);
    $bit1 = substr_count( $number_2sin, 1 );
    $number++;

    if ( ($here + $bit1) == $nyu ) {
        break;
    } 
    elseif ( ($here + $bit1) > $nyu ) {
        $here = $here - $bit1;
        if (array_search($here, $array) !== FALSE) {
            $counter = -1;
            break;
        }
    }
    else {
        $here = $here + $bit1;
    }
    $array[] = $here;
}
echo $number."\n";

?>
```
hamlで書いてみよう

#hamlで書いてみよう
hamlの書き方をいつも調べているので、使ったものをまとめています。
その都度更新しております。

##基礎
```haml
!!! 
%html
  %head
```

##タグ
```haml
.single-container
  %header.single-header
```


###inputタグ
```html
HTML
<input type="email" name="email" value="" placeholder="メールアドレス" class="login-input-text">

```

```haml
haml
%input.login-input-text{:name => "email", :placeholder => "メールアドレス", :type => "email", :value => ""}/
```
###form_for
```haml
haml(form_for)
= f.email_field :email, autofocus: true, autocomplete: "email", placeholder: "メールアドレス", class: 'login-input-text'
```

###link_to
```HTML
HTML
<a href="https://www.~~~~">プライバシーポリシー</a>
```

```haml
haml
%h1
  = link_to '/' do

.login-form
  = link_to '', class: "btn-facebook" do
```

###img
```haml


```


###aタグ
pタグの中にaタグでリンクを貼りたいとき

```haml
%p.text-center 
  「次へ進む」のボタンを押すことにより、
  %a{href: 'https://www.google.com'} 利用規約
  に同意したものとみなします

※インデントに注意！
```

　画面表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397779/aec2ccbb-4fac-ea2e-b709-cd283223d04e.png)

★　aタグでなく、link_toでも可能です

```haml
%p.text-center 
   「次へ進む」のボタンを押すことにより、
   = link_to "利用規約", 'https://www.~~~~~'
   に同意したものとみなします
```
書籍検索 Google Books APIs　使ってみる ＋ PHPでスクレイピング

# amazonの書籍検索が…
気がついたら使えなくなっていたので、Google Books APIs を使用し”書籍名”からイメージ画像などを取得するスクレイピングをしてみる。楽天の書籍APIも使ってみたがラノベ、なろう関係などはあんまりヒットしないみたい(笑)。

>+ [書籍検索APIは結局どれが一番いいのか](https://qiita.com/Hidekazu-Karino/items/3c2edbadbcbf1551c6cf)

# APIアクセス回数制限がある模様
Google Books APIのアクセス可能回数は1,000回/日です申請により緩和しれくれるそうなので事前に申請しておく（1,000回以上のアクセス課金は、いくらなのか？不明…）

>+ [【Google Books】API回数制限の緩和申請](http://lnovel.diary.to/archives/65829762.html)

# アクセスサンプル
```html
https://www.googleapis.com/books/v1/volumes?q=青の
```
こんな感じでブラウザから叩いてみる。とGoogleさんは「青の」の完全一致ではなく、気を利かしてくれているのか「青の」を含む書籍を取得してくるみたいです。[公式ページ](https://developers.google.com/books/docs/overview)をみると完全一致のパラメタはなさそうなので注意が必要みたい。
また結果については、デフォルト１０件ヒットするみたいね。

なのでレスポンスの転送容量も考慮し１件の検索結果となるように調整してみる。

```html
https://www.googleapis.com/books/v1/volumes?country=JP&maxResults=1&orderBy=relevance&q=オーバーロード
```

## APIキーの指定は？
折角APIキーを取得したので指定してみます。Googleのガイドをみるとクライアント側でAPIキーを使用するとセキュリティ上あれや、これや。って書いてあるのと(クライアント側では OAuth使う)、今回はサーバサイドでのスクレイピングなので、GETメソッドに書いてみる。

```html
https://www.googleapis.com/books/v1/volumes?country=JP&maxResults=1&orderBy=relevance&q=オーバーロード&key=作成したAPIキー
```

## phpによるスクレイピング
こんな感じでURLを生成して

```php
function MakeUrl($Keyword) {
  $baseurl               = 'https://www.googleapis.com/books/v1/volumes';
  $params                = array();
  $params['key']         = '作成したAPIキー';
  $params['maxResults']  = 1;
  $params['orderBy']     = 'relevance';
  $params['country']     = 'JP';
  $params['q']           = $Keyword;

  // パラメータの順序を昇順に並び替え
  ksort($params);

  // canonical string を作成
  $canonical_string = '';
  foreach ($params as $k => $v) {
    $canonical_string .= '&'.urlencode_rfc3986($k).'='.urlencode_rfc3986($v);
  }
  $canonical_string = substr($canonical_string, 1);

  // URL を作成
  $url = $baseurl.'?'.$canonical_string;

  return $url;
}
```

これ実行した結果をパースする。
欲しいのは、書籍の画像と書籍サンプルのURLとした場合とすると

```php
function cURL_GetSite($url) {
  $MediumImage = '';
  $retArray = new stdClass();

  // 指定されたURL情報の取得
  $ch = curl_init( $url );
  curl_setopt($ch, CURLOPT_HEADER, FALSE);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_setopt($ch, CURLOPT_FAILONERROR, TRUE);
  $result = curl_exec($ch);
  curl_close($ch);

  // JSON情報パース
  $json = mb_convert_encoding($result, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');

  // 画像URL, 検索ページの取得
  $retArray->thumbnail = '';
  $retArray->previewLink = '';
  $retArray->ResultXML = $result;

  $obj = json_decode($json, true);
  $obj2 = $obj["items"][0];

  $retArray->thumbnail = $obj2["volumeInfo"]["imageLinks"]["thumbnail"];
  $retArray->previewLink = $obj2["volumeInfo"]["previewLink"];

  return $retArray;
}
```

簡単な使い方としては

```php
$make_url = MakeUrl('オーバーロード');    // スクレイピングURL作成
$resultArray = cURL_GetSite($make_url);   // 問い合わせ
echo $resultArray->thumbnail;
echo $resultArray->previewLink;
```

結果は、SQLite にでも格納しておくとかすれいいよね。
割と簡単にできた。とりあえず個人で使う分にはいい感じ。
バッチでLhaplusコマンドを使用してファイルを自動解凍する

業務中に大量のファイルを解凍することがあり、興味本位で調べてみたらコマンドでLhaplusを実行できると知り調べてみました。
その結果、不格好ながらもできあがったものを紹介します。
# 環境
Windows 10
Lhaplus 1.74 （投稿時）
コマンドプロンプト
# 完成品
```
@echo off
rem 親フォルダ以下の指定した拡張子のファイルを全て同じ場所に解凍するバッチ
setlocal enabledelayedexpansion

rem ◆変数定義◆
set COUNT_ALLFILE=0
set S_DATE=%DATE%
set S_TIME=%TIME%
set IS_EXTENSION=false

rem ■メイン■
echo "親フォルダ以下の指定した拡張子のファイルを全て同じ場所に解凍します。"
call :guidanceExtension
call :guidanceFileSave
call :guidanceStart
call :searchAndDecompress
goto :decompressEnd

rem ◆ガイダンス（拡張子）◆
:guidanceExtension
set /p RES1="解凍対象の拡張子を入力してください。...[拡張子を入力] "
if /i %RES1%==cab set IS_EXTENSION=true
if /i %RES1%==gz set IS_EXTENSION=true
if /i %RES1%==jar set IS_EXTENSION=true
if /i %RES1%==lzh set IS_EXTENSION=true
if /i %RES1%==lzs set IS_EXTENSION=true
if /i %RES1%==mim set IS_EXTENSION=true
if /i %RES1%==rar set IS_EXTENSION=true
if /i %RES1%==tar set IS_EXTENSION=true
if /i %RES1%==taz set IS_EXTENSION=true
if /i %RES1%==tbz set IS_EXTENSION=true
if /i %RES1%==tgz set IS_EXTENSION=true
if /i %RES1%==uue set IS_EXTENSION=true
if /i %RES1%==xxe set IS_EXTENSION=true
if /i %RES1%==z set IS_EXTENSION=true
if /i %RES1%==zip set IS_EXTENSION=true
if /i %RES1%==zoo set IS_EXTENSION=true
if %IS_EXTENSION%==false (
	set /p RES2="不明な拡張子です。再入力しますか？...[Y/N] "
	if /i !RES2!==Y goto :extension
	if /i !RES2!==YES goto :extension
	goto :end
)
exit /b

rem ◆ガイダンス（リスト保存）◆
:guidanceFileSave
set /p RES3="解凍ファイルリストを保存しますか？...[Y/N] "
set ARC_LIST=FALSE
if /i %RES3%==Y set ARC_LIST=TRUE
if /i %RES3%==YES set ARC_LIST=TRUE
echo;
exit /b

rem ◆ガイダンス（開始）◆
:guidanceStart
echo 対象拡張子：%RES1% ファイルリストの保存：%ARC_LIST%
set /p RES4="以上の設定で解凍を始めます。よろしいですか？...[Y/N] "
if /i %RES4%==Y exit /b
if /i %RES4%==YES exit /b
goto :END

rem ◆対象ファイル検索＆解凍◆
:searchAndDecompress
echo %CD%以下を検索します。
for /r %%i in (*.%RES1%) do (
	echo リストに追加：%%i
	set /a COUNT_ALLFILE+=1
	echo %%i >> "%CD%\file_list.txt"
)
call :decompress "%CD%\file_list.txt"
exit /b

rem ◆解凍◆
:decompress
set FILELIST=%1
"C:\Program Files (x86)\Lhaplus\Lhaplus.exe" /oh /l:%FILELIST%
if /i %ARC_LIST%==FALSE del %FILELIST%
exit /b

rem ◆終了処理◆
:decompressEnd
if %COUNT_ALLFILE%==0 (
	echo 対象のファイルが存在しませんでした。プログラムを終了します。
) else (
	echo %CD%以下を検索、%COUNT_ALLFILE%のファイルを解凍しました。プログラムを終了します。
)
echo 開始日時：%S_DATE% %S_TIME%
echo 終了日時：%DATE% %TIME%
pause

:end
exit
```
# 使い方
**※この記事のコードを使用したことにより不都合、不利益が生じても責任は持てませんので使用する際は自己責任でお願いします。**
①上記コードをbatで保存。（この時必ず、改行コードはCRLF、文字コードはSJISで保存してください。でないと上手く動作しません。）
②保存したbatファイルを解凍したいファイルがあるディレクトリで実行。
③画面の質問に応じ、拡張子、解凍ファイルリストの保存有無、開始するしないを入力すると後は**実行ディレクトリ、配下のサブディレクトリ内全ての指定した拡張子のファイルをリスト化してその場に一気に解凍してくれます。**（解凍の仕方は各ユーザーのLhaplusの設定により異なります。）
# 苦労したところ
 - Lhaplusのオプションについての詳しい情報があまりなかった。
 - 各コマンドのオプションを理解するのに時間がかかった。

#おわり
>解凍の仕方は各ユーザーのLhaplusの設定により異なります。

上記に関して、オプションにテンポラリモードなるものがあるようで、それを使えば設定を統一できるかもしれませんが情報がなかったので今回は実装できませんでした。とりあえずできあがってよかったです。
これとは別にファイルをマージするバッチも作成したので時間がある時に紹介したいと思います。
→[バッチで同じ拡張子のファイルをマージする](https://qiita.com/atsnsgw/items/6294cfaa988a6aa820ca)
JavaScriptのテストとかに使えるローカルWebサーバをGoで作る。

# p5.jsでも再開しようと考えた。
でもウェブサーバ上でないとちょっと都合が悪い。github pagesとかでも良いのだけども踏み込んだことをしようとするとちょっと面倒。
ついでにHTML5コンテンツを配布するなどというケースを考えるとウェブサーバをローカルに立てればいいという単純な話でもないし。

# Goなら簡単にWebサーバが作れる。
そんな話を聞きかじって作ってみた。
実はかなり前に作ったものなので当時組み込んだ踏み込んだ仕組みがいろいろ入っていて複雑になっていた。
そこでちょっとこそぎ落としてシンプルにした。

## ソース

```golang:simpleWebServer.go
package main

import (
	"fmt"
	"net/http"
	"io/ioutil"
	"os"
	"strings"
	"time"
	//"math/rand"
	//"golang.org/x/net/websocket"
	//"io"
)

func handler(w http.ResponseWriter, r *http.Request) {
	path := ""
	ct := ""
	fmt.Fprintf(os.Stdout,r.URL.Path + " \n");

	if r.URL.Path == "/" {
		path = "/index.html"
	} else {
		path = r.URL.Path
	}

	ctm := map[string] string {
		".html":"text/html;charset=utf-8",
		".css":"text/css",
		".js":"text/javascript",
		".png":"image/png",
		".jpg":"image/jpg",
		".ico":"image/x-icon",
		".mp3":"audio/mpeg",
		".aac":"audio/aac",
		".woff":"font/x-woff",
		".otf":"application/x-font-otf",
	}
	ct = ctm[ path[strings.LastIndex(path,"."):]]

	w.Header().Set("Content-Type",ct)
	ci,_ := ioutil.ReadFile( "." + path )
	w.Write(ci)
}

func main() {
	running := true
	http.HandleFunc("/", handler)
	go func() {
		http.ListenAndServe(":8080", nil)
	}()
	fmt.Fprint(os.Stdout,"server start\n");

	/*
	http.Handle("/echo",websocket.Handler(EchoHandler))
	err := http.ListenAndServe(":8088",nil)
	if err != nil {
		fmt.Fprint(os.Stdout,"websocket err")
	}
	rand.Seed(time.Now().UnixNano())
	*/

	for running {
		time.Sleep(500 * time.Millisecond)
	}
}

// webSocket test
//func EchoHandler(ws *websocket.Conn) {
//	io.Copy(ws,ws)
//}
```

WebSocketの処理をコメントアウトしてある。
このgoのスクリプトはウェブサーバ兼アプリケーションサーバとして動作するということです。
これに加えてアセットをバイナリ化して組み込む処理も入っていたのだけれどもそこは省きました。

主に使いそうなMIMEタイプには対応しましたが必要あれば追記してもらえればいいとおもいます。SVGとかあたりは対応しても良いような気もしますよね。

## 悩む部分。
HTML5でウェブページであることを完全無視してウェブブラウザはフロントエンドだとみなしたとします。
そこでブラウザを限定しちゃいますFireFoxとかChromeとか。
そこまではいいんですが、プログラムの知識がそれほど豊富ではない人にとってシェルとかコマンドプロンプトというのは恐怖の対象のようです。

そこで希望としてはGUIを伴って動作してほしい。
しかし環境に依存しないGoで利用できるGUIライブラリをわたしは知りません（一応GO-SDL2はマルチプラットフォームですがクロスコンパイルが少しややこしいしGUIとしてはちょっと手間がかかる気もします）

もうひとつはブラウザを自動起動したい。
一応そういうモジュールも存在しているにはいるんですが、利用者が標準に指定しているブラウザが起動したはずです。
またEXECなどで動作させる場合Windowsは決まった場所にソフトが存在するわけではないでしょうから確実に起動できるとは限りません。

といったところでこのあたりの２点。どうにかしたいところです。
要するにこの２点に引っかかったので過去に悩んだままGoからフェードアウトしたわけです。

ひとまずは**わからないとかいわずに説明通りに動かせ！**というスタンスでそのあたりに目をつむったまま進行するつもりですがなにか良い解決策を知っている方はぜひ教えてほしいところです。


つづくー。
true/false判定に向いている「早期リターン」

メンバーと昼食をとってる時に「勢いで書いてるとif文をネストしがち」みたいな話が出た。ネストの解消はコツがあるんだけど、その時は特に話を広げることもなくて。記事にまとめることにしました。

```php5
public function is_deletable_event($event) {
    if ($event) {
        // 申し込みが0件
        $count = EntryTable::select('*')
            ->where('event_id', $event->id)
            ->count();

        if ($count == 0) {
            // 特別招待された申し込みが0件
            $priority = VIPEntryTable::select('*')
                ->where('event_id', $event->id)
                ->count();

            if ($priority == 0) {
                // クーポン利用の申し込みが0件
                $has_coupon = CouponEntryTable::select('*')
                    ->where('event_id', $event->id)
                    ->count();

                if ($has_coupon == 0) {
                    // 招待してない
                    if (!$event->has_invited) {
                        return true;
                    }
                }
            }
        }
    }
    return false; // 無効なイベント
}
```

たとえば上記のような処理があるとします。よく見ると、true判定を得るための4階層の入れ子が構成されていることが分かるけど、パッと見た印象で分かりにくい。これは、下記のように書き直せます。

```php5
public function is_deletable_event($event) {
    if (!$event) { // 無効なイベントは他の処理に判定を渡すため削除不可
        return false;
    }

    // 特別招待をお送りした会員がいるイベントのため削除できない
    if ($event->has_invited) {
        return false;
    }

    // 有効な申し込みがあるから削除できない
    if (EntryTable::select('*')->where('event_id', $event->id)->count()) {
        return false;
    }

    // 特別招待された申し込みがあるから削除できない
    if (VIPEntryTable::select('*')->where('event_id', $event->id)->count()) {
        return false;
    }

    // クーポン利用の申し込みがあるから削除できない
    if (CouponEntryTable::select('*')->where('event_id', $event->id)->count()) {
        return false;
    }

    return true;
}
```

falseの壁を５つ乗り越えたらtrueにたどり着く。見た目に分かりやすい。これが「早期リターン」と言われる書き方で、true/falseを判定する目的の処理に向いています。
新しいData Augmentation手法であるCutMixを試してみた

# はじめに
CutMixという新しいData Augumentation手法がシンプルな手法だったので試してみました。
今回はCifar10などを用いてこの手法の有効性を確認していません、あくまでCutMixという手法がどんなものなのかという点に重きをおいています。
検証についてはこの記事に追記、もしくは新しく記事をおこしたいと思います。

## CutMix
まずCutMixの名前の由来としてCutout + Mixupからきています。その由来通りCutoutとMixupの技術それぞれを合わせたような手法になっています。
以下CutOutとMixup、CutMixそれぞれの手法の違いが比較されている図が論文にのっていましたのでこちらにも掲載します。


![cutmix_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/5e862db4-fdd8-1fd4-36a7-e98e676396d5.png)

具体的な処理の流れは画像とラベルのペア$(x_a, y_a)$, $(x_b, y_b)$から、$(x, y)$という新しいデータとラベルのペアを作ります。
ここで$\lambda \in [0, 1]$は、ベータ分布$Beta(\alpha, \alpha)$からのサンプリングにより取得し、$\alpha$はハイパーパラメータとなります。
また画像の幅と高さそれぞれの一様分布した乱数を取り出し、切り出す起点の座標$(r_x, r_y)$とします。切り出す際の幅と高さはさきほど計算した$\lambda$を使い、$\sqrt(1 - \lambda)$で計算しそれらを$(r_w, r_h)$とします。
その後切り出す起点$(r_x, r_y)$, $(r_w, r_h)$を使って片方の画像を切り出し、もう片方の画像に切り出した部分を貼り付けます、これで新しい画像は完成です。ラベルのほうはmixupの処理と同じで$\lambda$と$(1-\lambda)$をラベルそれぞれにかけ合わせそれらを足し合わせると処理は終わりになります。

とグダグダと書きましたが論文にCutMixの擬似コードが書いてありましたので載せておきます。

![cutmix_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/eec2f727-f0bd-e994-42ba-c35d127eaff6.png)


## 実装
疑似コードを実装してみました。

```python
import numpy as np


def get_rand_bbox(image, l):
    width = image.shape[0]
    height = image.shape[1]
    r_x = np.random.randint(width)
    r_y = np.random.randint(height)
    r_l = np.sqrt(1 - l)
    r_w = np.int(width * r_l)
    r_h = np.int(height * r_l)
    bb_x_1 = np.int(np.clip(r_x - r_w, 0, width))
    bb_y_1 = np.int(np.clip(r_y - r_h, 0, height))
    bb_x_2 = np.int(np.clip(r_x + r_w, 0, width))
    bb_y_2 = np.int(np.clip(r_y + r_h, 0, height))
    return bb_x_1, bb_y_1, bb_x_2, bb_y_2

def main():
    image_path_1 = "image_1.jpg"
    image_path_2 = "image_2.jpg"
    # 説明用にラベルを簡単化しています
    label_1 = np.array([1, 0])
    label_2 = np.array([0, 1])
    image_1 = Image.open(image_path_1).resize((224, 224))
    image_2 = Image.open(image_path_2).resize((224, 224))
    beta = 0.5
    l_param  = np.random.beta(beta, beta)
    img_1 = np.array(image_1)
    img_2 = np.array(image_2)
    bx1, by1, bx2, by2 = get_rand_bbox(img_1, l_param)
    img_2[bx1:bx2, by1:by2, :] = img_1[bx1:bx2, by1:by2, :]
    new_label = l_param * label_2 + (1 - l_param) * label_1
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/e5cd2895-0b2e-a776-93d9-94360a8181f5.jpeg"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/1a65a00c-9d84-c3a8-3117-dc6bde0f489f.jpeg"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/e2a34452-d7ef-21f4-f5e2-e9de28afd367.png">

以上になります。

# 参考
- [Github - CutMix-PyTorch](https://github.com/clovaai/CutMix-PyTorch)
- [arXivTimes - CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features](https://github.com/arXivTimes/arXivTimes/issues/1308)
- [arXiv - CutMix: Regularization Strategy to Train Strong Classifiers with Localizable Features](https://arxiv.org/abs/1905.04899)
- [Qiita - 新たなdata augmentation手法mixupを試してみた](https://qiita.com/yu4u/items/70aa007346ec73b7ff05)
インフラの技術選定の失敗は高くつくよという話（ElasticSearchとCloudSearch編）

インフラの技術選定の失敗は高くつくよという話です。
未来のことを考えてアーキテクチャを考えていれば起こる問題も少なく、追加で発生するコストを減らせたかもしれません。

この記事の内容はざっくりいうと以下のような感じです

* サイト内検索を作るのに AWS CloudSearch というAWSにロックされた楽チンなソリューションを選択してしばらく運用していた
* 手元開発環境と本番環境のインフラ構成が食い違うことにより諸々の細々とした問題が発生した
* 全環境で可能な限りインフラ構成を合わせようと ElasticSearch を使うように変更する


※この記事は手元開発環境への導入のプルリクエストが書き終わった時点で書いているので、本番への導入でまた何か問題が起こる可能性はありますが・・・


#### 最初にAWS CloudSearchを導入した。その時何を考えていたか？
AWS CloudSearchは超ざっくりいうと「全文検索エンジンを細かい設定とか気にせずすぐに使えるAWSフルマネージドのサービス」です。
CloudSearchの裏ではElasticSearchが動いているらしく、だいたい同じことができますが、細かいこと気にしなくていいです。自分でElasticSearch立ち上げてメモリ設定してスケール設定して、細かい日本語形態素解析設定とか、そういうことを気にしなくていいのは良いです。ただし、1台4000円程度から。

当時（11ヶ月前くらい）の状況と考えてたこととしては

* 本番環境と開発環境の2つのCloudSearchインスタンスを作る
* 開発者が当時2人だけ。だからLocalで開発するときも開発環境のCloudSearchインスタンスに繋げればおっけー⭐️ 
    * Localの環境整えるのも手間だしね
    * Localと開発のデータ差異もプロジェクトが始まってまもないのでそんなにないのでDBの内容と CloudSearch の Index が多少食い違ってもOK
* サイト内検索の精度は、最初はその機能がどう使われるかの検証するレベルなのでそんなに高くなくて良いし、導入コストをたくさん払いたくない

#### 発生したトラブル

* LocalからCloudSearch繋げないと検索周りの確認ができないが、env設定変更が面倒
* 面倒がゆえに、開発中に一時的にCloudSearchに繋げないでメソッド内部で固定値を返すように無理やり変更。これがうっかりプルリクエストに入ってマージされて本番でも固定値しか帰らないようになるトラブル
* 無理やり固定値を返さなくても良いようにLocalではDBから検索するように分岐をするようにした（LaravelのServiceProviderでの分岐）。本格的なサイト内検索を作ろうとすると、CloudSearch叩く方とDBから検索する方と両方の開発を同時に進めなくてはならず、コストが膨らんでいった
* ちゃんと検索機能を開発しようとするとDBとの整合性も大事なので、手元で書いて開発環境にデプロイして確認、また書いてを繰り返すのがコスト


#### 根本対応をしたい。環境差異を無くそう
開発者も3人になって、Localと開発環境のDBデータの差異も大きくなってきた。もう環境差異があってはやっていけない！ ということで合わせることに。

環境を合わせる選択肢は以下のものが現れました

* CloudSearch を各開発者向けに1台ずつ立ち上げる
    * 10人いたら10台*4000円？ 無駄じゃね
* 裏で ElasticSearch 動いているんだから ElasticSearch 動かせばよくない？
    * EC2 に ElasticSearch 立てて自分たちでマネージしていくの？ きつくない？

こんな話があり、しかしちょっと調べてみると ElasticSearch は思ったよりも簡単に導入できそうだということがわかりました。

* Localに関しては、Laradock（Laravel 動かせる Docker開発環境）で, `docker-compose up` するときに elasticsearch を追加したらすぐに立ち上がることがわかりました。しかもkibanaも同様に簡単につけられる
* 開発/本番環境に関しても、フルマネージドのAWS ElasticSearch Serviceがある
    * これはまだ本運用に入っていないので断言できませんが、バージョン指定してLocalと合わせられるので差異は大きな問題にはならないと考えています

#### というわけで、コード書き換え

* 幸いコードの方はアプリケーション層とインフラ層がインターフェースで疎結合になるアーキテクチャを採用しており、アプリケーション層の書き換えはほとんど発生しませんでした。素晴らしい
    * しかもその切り替えがServiceProviderでやっており、環境ごとにどちらを使うか選択可能なので、Localだけ先行してコードを書いてテストしていける
* インフラ層だけCloudSearch向けの検索query string表現（ANDとかORとかboost設定とか）を、ElasticSearch向けの表現を作り直す作業がありました。これはコピペして愚直に
* CloudSearchだとあんまり深く考えなくて良いところですが、ElasticSearchの形態素解析設定なども書く必要がありました

ここら辺の話については別途記事で詳細を書こうかなと思います。

#### 振り返って

* 振り返ると、初動でCloudSearchを選択したのは悪くなかったかもしれません。実際導入は楽チンでしたし。まず動かせるものがすぐできるというのは正義。
* サイト内検索を単純なものから機能を追加していく前にElasticSearchに置き換えるタスクを差し込んでやるのはありだったかもしれません
    * ただ、ビジネス的な要請でさっさと機能追加したかったので、このタスクを間に差し込む判断ができたかどうかは微妙なところです。「最高の形になってから進める」だと本質的な開発が止まってしまいこともあるのでバランス大事。
* 今後ここら辺でインフラアーキテクチャ起因での問題は減らせると思うので、もっと変更が大変になってからではなくて、現時点で判断材料を並べてチームで判断できたのはよかったと思います
PHPでクラスのエイリアスに文字列でアクセスしてみる

PHPでクラスのエイリアスに文字列でアクセスしようとしたらうまくいかなかった。
`use as`は駄目だったけど[`class_alias`](https://www.php.net/manual/ja/function.class-alias.php)を使うとうまくいった。

難しい...

```php
class Test
{
    public static function method()
    {
        echo 'method';   
    }
}

use Test as Test2;
```

```php
Test::method();// method
Test2::method();// method
```

```php
call_user_func('Test::method');// method
call_user_func('Test2::method');// class 'Test2' not found
```

```php
$class = 'Test';
$class::method();// method
$class = 'Test2';
$class::method();// Class 'Test2' not found
```

```php
$class = 'Test2';
class_alias('Test', 'Test2');
$class::method();// method
```

### [頂いたコメント](https://qiita.com/horikeso/items/07b8c2bef9d2264452de#comment-9cfd2b13b0d54a748e20)を参考に追記

[名前空間と動的言語機能](https://php.net/manual/ja/language.namespaces.dynamic.php)

> 要素への動的なアクセス
> 完全修飾名 (クラス名に名前空間プレフィックスをつけたもの) を使う必要があります。

というわけで`class_alias`を使わないならばエイリアスではアクセスできないっぽい。

今回はnamespaceがなかったのでたまたま上手くいってしまったが、
本来はTestも`Test::class`で完全修飾名を取得してアクセスしないとだめ。

`class_alias`を使っていない場合は動的にアクセスしたいなら文字列には完全修飾名を指定するしかない。

```php
$class = Test::class;// クラスの完全修飾名を取得 'Test'
$class::method();// method
$class = Test2::class;// クラスの完全修飾名を取得 'Test'
$class::method();// method
```
Ubuntu に最新版のprotobufをインストール

[公式のリリースノート](https://github.com/protocolbuffers/protobuf/releases)から最新のversionを確認。
2019/07/17時点では3.9.0


最新版をDL(versionは適宜変更)

```
$ curl -OL https://github.com/google/protobuf/releases/download/v3.9.0/protoc-3.9.0-linux-x86_64.zip
```

解凍

```
$ unzip protoc-3.9.0-linux-x86_64.zip -d protoc3
```

pathが通っている場所へ移動

```
$ sudo mv protoc3/bin/* /usr/local/bin/
$ sudo mv protoc3/include/* /usr/local/include/
```

念の為権限の変更

```
$ sudo chown [user] /usr/local/bin/protoc
$ sudo chown -R [user] /usr/local/include/google
```

確認

```
 $ protoc --version
libprotoc 3.9.0
```

余計なファイルを削除

```
$ rm -rf protoc-3.9.0-linux-x86_64.zip protoc3
```
環境構築(VSCode + kotlin + spring boot + Gradle)

※ 投稿者：いまだにグラドルと読みそうになる初心者です。
springMVC以外は業務経験がないため、趣味開発の雑記となります。

似たような構築のブログは見つかったけど、クリティカルなものがなかったので、初投稿です。

# 環境
OS:Windows10 home
# 用意するもの
VScode(https://code.visualstudio.com)
Java(https://www.java.com/ja/download/help/download_options.xml)
OpenJDK(http://jdk.java.net)
Kotlin(https://github.com/JetBrains/kotlin)
この辺の詳しいのは他記事で常に最新の情報を追いかけたほうが無難
## 構築手順
### 1.環境変数
  - JAVA_HOME
  - java(openJDK)
  - kotlin
  - gradle

### 2.VSCodeの拡張
 - Java Extension Pack(java諸々のpack)
 - Gradle Language Support(Gradle 言語 サポート)
 - kotlin(kotlin系の拡張はどの辺使えばいいか煮詰まってないので、適当に...)
 - Kotlin Language(これが言語サポートだと↑のはいったい...)
 - Kotlin Debugger(これは必要)
 - Spring Boot Extension Pack(Spring Bootの諸々)

### 3.projectを作成する
コマンドパレッドに"spring initializr:generate a gradle project"を入力し、作りたい環境をずんずん選択していく。
https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-spring-initializr

### 4.Gradleのタスクを作成する
英語できないマンなのでいちいち「./gradlew 〇〇」とかやってられないから
ターミナル > タスクの実行 を行い.vscodeのファイルにtasks.jsonがなければ「タスクを構成する」と出てくるので、それを実行。
実行したら「/.vscode/tasks.json」が出来てるので、タスクを書く

```json:tasks.json
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "./gradlew build"
        },
        {
            "label": "run",
            "type": "shell",
            "command": "./gradlew bootRun",
        },
        {
            "label": "clean",
            "type": "shell",
            "command": "./gradlew clean"
        },
        {
            "label": "check",
            "type": "shell",
            "command": "./gradlew check"
        }
    ]
}
```
### 5.とりあえず実行してみる
「ターミナル > タスクの実行」に4.で設定した"label"が表示されてると思うので、
build　→ runの順番で実行。
ログに
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326926/123da19e-727d-f933-658d-eafa74c5fcba.png)
が出て来たら成功。

#参考
https://qiita.com/chakimar/items/39937cf39d2069758c83
https://qiita.com/yhayashi30/items/910a79da8b7c7fe7872e
https://huideyeren.info/2019/03/23/spring-boot-setup
https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-spring-initializr
RxJS operatorsの旅【１】auditTimeとthrottleTime

みなさん、RxJS使っていますか？

フロントエンドフレームワークとしてAngularを採用している場合は、嫌でもRxJSに触れることになると思います。沢山ある[RxJSのオペレーター](https://rxjs-dev.firebaseapp.com/api/operators)と仲良くなるのが上達への近道なのでアウトプットも兼ねてやっていこうと思います

# auditTime と throttleTime の違い

## auditTime

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198179/fe7ea822-c3c9-7c84-b40c-6140eb778a19.png)
[auditTime](https://rxjs-dev.firebaseapp.com/api/operators/auditTime)より引用

`auditTime(duration)` は、ソースのstreamからデータが流れてきてからduration(ミリ秒)だけ待ってからその時点での最新の値をemitします。

頻繁に変わる値を間引きたい場合に有効です。似たoperatorとして [debounceTime](https://rxjs-dev.firebaseapp.com/api/operators/debounceTime)もありますが、debounceTimeの場合は値が安定する場合までは値がemitされないという特徴があります。

## throttleTime

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198179/1e8e7e43-0097-dff6-26db-63b18032b2a5.png)

[throttleTime](https://rxjs-dev.firebaseapp.com/api/operators/throttleTime)より引用

`throttleTime(duration)` は、ソースのstreamからデータが流れてきてからemitし、その後duration(ミリ秒)の間は値をemitせずに無視します。

アニメーションやトランジションのあるUIの操作に対する連打を防ぐ等のシチュエーションで有効です

## auditTime と throttleTime の違いについて

どちらも　「値を間引く」「値が頻繁に変わっても、その間隔をduration以上に保てる」といった特徴があります。しかし、「はじめの値が来てから一定時間後にemit」と「はじめの値が来たらemitし、その後一定時間emitしない」という違いがあります。

## まとめ

operatorは沢山あって使いこなせないことが多いですが、１つ１つの機能を見ていくとシンプルな設計になっていて、使い所を考えることで習得に繋がりそうです。
Where should I start learning Microsoft Azure development

If you are a beginner in Azure and want to learn Azure from scratch, then go for Azure training from these platforms: 
● Intellipaat 
● Udemy 
● Coursera 

These are few good e-learning platforms that will help you learn Azure from very basic level to the advanced level. And these are very convenient platforms for learning Azure, as you don’t need to travel anywhere and you can learn Azure with the best experience from your own pace. 

I hope this video helped you to get familiar with the technology Azure. Now I will tell you what you will learn in Azure, and how these platforms are good and helpful to you. 

So, first know what are the concepts to master in Azure: 
➢ <a title="What is microsoft Azure" href="https://intellipaat.com/blog/what-is-microsoft-azure/">What is microsoft Azure</a> 
➢ A deep introduction to Azure fundamentals 
➢ How to work on azure network management
➢ Azure platform for cloud computing applications 
➢ Implementation of azure SQL database 
➢ What is azure web app services 
➢ Deploying virtual machines 
➢ Deploying azure active directory 

So, these are the topics that you will learn in Azure. And these are the concepts in Azure that you must learn and become skilled in them, as mastering these concepts of Azure will help you clear Developing Microsoft Azure Solutions 70-532 certification exam, which is a recognized certification for Azure. So, this is about Azure course. And now I will tell you that why these platforms are good for learning Azure.
HTML の 要素 を 重ねて を 表示する(基準となる要素からの設置場所指定)

# 目的
- HTMLファイルの要素同士を重ねて表示する方法をまとめる。

# 押さえるポイント
- 基準にしたい要素にpositionプロパティでrelativeを与える。
- 重ねたい要素に対してpositionプロパティでabsoluteを与える。
- topプロパティ、rightプロパティを使用して重ねたい要素の位置を指定する。

# 書き方の例
- 下記にCSSファイルの内容を記載する。

``` css
基準となる要素の名前かクラス名 {
  position: relative:
}

重ねたい要素の名前かクラス名 {
  position: absolute;
  top: 左上から設置したい場所への高さのピクセル数;
  right: 左上から設置したい場所への右方向のピクセル数;
}
```

# より具体的な例
- img要素を基準にh1要素を重ねる。
- h1要素をimg要素の上から20ピクセル、左から100ピクセルの所に設置する。
- 基準はimg要素。
- 下記にHTMLファイルの内容を記載する。

``` html
<img src="">
<h1>おはようございます。</h1>
```

- 下記にCSSファイルの内容を記載する。

``` css
img {
  position: relative;
}

h1 {
  position: absolute;
  top: 20px;
  right: 100px;
}
```
HTML の 要素 を 重ねて を 表示する(画面左上からの設置場所指定)

# 目的
- HTMLファイルの要素同士を重ねて表示する方法をまとめる。

# 押さえるポイント
- 重ねたい要素に対してpositionプロパティでabsoluteを与える
- topプロパティ、rightプロパティを使用して重ねたい要素の位置を指定する。


# 書き方の例
- 下記にCSSファイルの内容を記載する。

``` css
要素の名前かクラス名 {
  position: absolute;
  top: 左上から設置したい場所への高さのピクセル数;
  right: 左上から設置したい場所への右方向のピクセル数;
}
```

# より具体的な例
- h1要素を上から20ピクセル、左から100ピクセルの所に設置する。
- 基準は左上。
- 下記にHTMLファイルの内容を記載する。

``` html
<h1>おはようございます。</h1>
```

- 下記にCSSファイルの内容を記載する。

``` css
h1 {
  position: absolute;
  top: 20px;
  right: 100px;
}
```
【CSS】セレクタの書き方まとめ

#そもそもセレクタとは

```test.css
h1 {
 color: #fff;
}

.sample {
 background-color: #fff;
}
```

上記コードで言うと、h1や.sampleがセレクタです！
CSSのプロパティを適用する対象のことですね！
今回はこのセレクタの様々な書き方についてまとめました！

# セレクタの様々な書き方
###Aクラスの中のBに適用する場合
セレクタの間にスペースを入れる。

```test.html
<div class="A">
  <div class="B">あああああ</div>
</div>
```

```test.css
.A .B {
 color: red;
}
```
この場合は"あああああ"が赤色になります。

###AとB両方に適用する場合
セレクタをカンマで区切る。

```test.html
<div class="A">あああああ</h1>
<div class="B">いいいいい</h1>
```
```test.css
.A,.B {
 color: #fff;
}
```
この場合は"あああああ"と"いいいいい"両方が赤色になります。

###Aの直下の階層にある要素に適用する場合
```test.html
<div class="A">
  <h１>あああああ</h1>
</div>
```

```test.css
.A > h1 {
 color: red;
}
```
この場合は"あああああ"が赤色になります。

### 隣接している要素に適用

```test.html
<h１>あああああ</h1>
<h２>いいいいい</h２>
<h２>うううううう</h２>
```

```test.css
h1 + h2 {
 color: red;
}
```
この場合は"いいいいい"のみが赤色になります！
"ううううう"はh1と隣接していないので適用されません！

### ある要素の後ろにある要素に適用
```test.html
<h２>いいいいい</h２>
<h１>あああああ</h1>
<h２>うううううう</h２>
<h２>えええええ</h２>
```

```test.css
h1 ~ h2 {
 color: red;
}
```
この場合は"ううううう"と"えええええ"のみが赤色になります！
"いいいいい"は適用されません！

#さいごに
以上、基本的なセレクタの書き方でした！
特に`.A .B`と`.A,.B`は基本ですが、間違えやすいので注意です！
HTML の 要素 に 乗った時 カーソルの見た目 を 変える

# 目的
- HTMLファイルの要素にカーソルが乗った時にカーソルの見た目を変更する方法をまとめる。

# 押さえるポイント
- カーソルの見た目を変更するにはcursorプロパティを使用する。
- 見た目は「text」「pointer」「default」の三種類より指定する。

# 書き方の例
- 下記にCSSファイルの内容を記載する。

``` css
要素の名前かクラス名 {
  cursor: カーソルの見た目の名前;
}
```

# より具体的な例
- h1要素にカーソルが乗った時にカーソルの見た目をtextに設定する。
- p要素にカーソルが乗った時にカーソルの見た目をpointerに設定する。

``` html
<h1>おはようございます。</h1>
<p>これは日本の朝の挨拶です</p>
```

- 下記にCSSファイルの内容を記載する。

``` css
h1 {
  cursor: text;
}

p {
  cursor: pointer;
}
```
機械学習ことはじめ

#はじめに
　これから、機械学習を勉強していこうと思います。温かい目で見て頂けると幸いです。取り合えず、勉強して分かったものをアップしていきます。

#機械学習とは
　機械学習とは、簡単に言うとパソコンに膨大なパターンを学習させて、__まだ見たことのない問い__に対して、パソコンに回答させるというものです。そして、画像認識などでは、人間よりも精度が高い成果が出てきています。

#手順その１
　まず、膨大なパターンを覚えさせます。パターンとは、人の顔やサイコロの目の出方など様々なケースがあります。

![画像_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207458/e9cfca24-280c-557f-ef14-471c1019a218.png)

#手順その２
　膨大なパターンから、規則性を導かせます。これが、いわゆる手法と言うやつです。学習方法には、様々なものがあり、それぞれのケースに合わせて、最適なものを選択します。

　![画像_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207458/cf96a970-fec7-9a39-56f0-3faa532dd801.png)

#手順その３
　見たことのないパターンについて、パソコンに回答させます。顔写真を見せて、男か女かを判断させたり、次に出るサイコロの目を当てさせたりします。

![画像_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207458/0525117f-7e5c-5413-a9fa-b63b242141bd.png)

勿論、外れることもあります。

![画像_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207458/210871b0-9f7d-fd68-18a3-882185c33441.png)

#まとめ
　今わかっているのは、こんな感じです。これから、手法などを紹介していこうと思います。
メール送信で添付ファイルに空ファイルが付いてしまった時の覚書

ネットで調べつつ実装して少しハマったので、覚書として残しておきます

## 前提

* mb_send_mail()で自前でheaderとbodyを整形してメール送信している
* 添付ファイル付きでメール送信している
* 中身が空の添付ファイルが最後に付く

## 結論

bodyの最終行のboundary文字列末尾に--を付けてなかった

## 参考

* https://tools.ietf.org/html/rfc2046#section-5.1.1
Pythonのお勉強１０日目

## 自作デスクトップパソコンに挑戦した。
パソコンの知識乏しい、Python超初心者の備忘録です。
自作されたい方は　youtubeの動画（最新CPUで自作動画）,google:自作パソコンで検索
または、書籍　自作PCバイブル２０１９　１００％ムックシリーズなどを参考にしてください。
（メモリー、グラフィックボード、CPU、マザーボードに相性があります）

---
####使用用途、予算を決めて　部品を調達　組み立て　Python環境の構築


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435503/c04e49c5-c62f-8f1d-6489-23dc363d8737.png)


- 用途：Python関連
- 予算：１０万以下
- 調達：部品は大手通販を利用する　
- 組立：自作の書籍を参考に組み立てる。　
- 構築：Qiitaの記事を参考にPython環境を構築する。


#####まず　近くの量販家電に足を運びPCケースを物色。図１
　　  拡張性などからATXのアウトレット品を購入（GX1200) 自宅で開封。
　　電源スイッチ、USB端子は正面側にあるものと思い込みケースを設置してみると
　　側面板を開ける事が出来ない！
　　マニュアルを読むことにしましたが、側面板を開けた状態からの配線の説明のみ。
　　今時のケースは電源部分が底面に来ることから　電源スイッチの位置は上部前側
　　と判明、（後面を底面にして置いていた！）やっと内部にアクセスできました。

####パーツを調達　図２

###組み立て
#####電源固定：PCケースのマニュアルに従い　電源ユニットを固定する。電源ユニットとマザーボードが別区画に分かれているのでケーブル等の干渉もなし。
##### CPU:参考書に従って　マザーボードにCPUを取り付ける。
#####CPUクーラー：CPUの上面にCPUクーラーを取り付ける。巨大なものでした。
#####メモリ、SSD：メモリとSSDをマザーボードに取り付ける
#####マザーボード：マザーボードをケースに固定する
#####配線：電源ユニットのケーブル、ケースからのケーブルをマザーボードに取り付ける。ケース前面のケースFanコントローラーからのSATAケーブルを電源ユニットと接続
####動作確認：電源を入れて、キーボードのDelキーを押す。CPU温度など状態確認、USBからBootに変更図３
####OSのインストール（USBメモリー）
####マザーボード添付のDVDからDriverソフトをインストールする。（外付DVDドライブが必要です）
####Internet接続してライセンス認証を行う。

（今回CPUはGPU内臓のIntel 9th Corei5、HDDなし、SSDもM2Typeでマザーボードに取り付けるタイプで行ないました。グラフィックボードやHDD,2.5インチSSDなどを取り付ける場合は手順が異なります。特にグラフィックボードやハイスペックCPUを使う場合は水冷クーラーなどで排熱、静音性、クーラー増設、エアーフロー確認、大容量電源ユニットなど必要です）

###Python 環境構築：(個人的な構築です。）
　　いろいろ記事を参考にさせて頂きましたがわかりません
　　結局以下のように現在環境構築しています
#####まず　Anacondaを推奨設定でInstall
#####次に　VisualStudio２０１９のPython関連のものを含めてInstall
#####VisualStudioのPythonプロジェクトで環境を選択する
#####　　図１　　　　　　　　　　図２　　　　　　　　　　　　　　　　図３
<img width="934" alt="Screen Shot 2019-07-17 at 8.19.56 PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435503/59173c8b-e595-13d6-5abc-51823775a109.png">
pythonを取り巻く環境はハードウエアと違い進化のスピードが早く、バージョン依存などいろいろ複雑なので、しばらくこのままで利用してみます。
---
FortiOSハンドブック意訳 -Malware-

# FortiGate FortiOS ハンドブック
> セキュリティプロファイル > アンチウイルス > 概念 > マルウェア
>> https://docs.fortinet.com/document/fortigate/6.0.4/handbook/842733/malware

超意訳で一部自身の補足も含めています。

## マルウェア
> コンピュータの安全性に対する様々な種類の脅威を包括する単語

### ウイルス
> 自己複製型で自分自身のコピーをほかのプログラムまたはデータファイルにインストールする。また、望ましくない機能を実行するペイロードを運ぶ。
> 一例として、「個人情報へのアクセス」「データ破壊」「デジタルデータの改ざんまたは破壊行為」など

### ワーム
> ほかのコンピュータに拡散するために自分自身を複製するもの。通常、標的であるコンピュータまたはネットワーク上に存在する端末の脆弱性を利用して拡散する。
> ウイルスとの差は、既存のファイルに自分自身をコピーしない点である。
> ワームはペイロードを運ばないが、複製行為実行に伴い、ネットワーク帯域の消費やディスクなどのリソースを消費する。

### トロイの木馬
> トロイの木馬としての定義は、配布方法によって決定される。
> ソーシャルエンジニアリングなどを通じ、正当なユーザーに対してコードを実行・インストールさせる。
> ワームやウイルスと違い一般的には自己増殖しない。
> 一般的なペイロードはインストールされれたシステムに対するバックドアを準備すること。

### ランサムウェア
> 支払いが行われるまでシステムを身代金の代わりに保持するマルウェアである。
> ファイルを暗号化するかシステムをロックすることにより、システムの所有者からのアクセスを制御する。
> 通常、要求とともにメッセージが表示され、支払いが完了するとシステムのロックを解除するためのユーティリティまたはキーがユーザーに送信される。

### スケアウェア
> 2つの種類が存在している。
> 1つ目は、マルウェアに感染していないのにも関わらず、感染しているとユーザーに通知し怖がらせ、ウイルス駆除ユーティリティを購入させる。このユーティリティは機能しないか、追加のマルウェアである。
> 2つ目は、ボットネットの一部もしくは児童ポルノ保管などの違法行為が端末にて行われているとユーザーを怖がらせ、ウイルス駆除ユーティリティを購入させようとする。

### スパイウェア
> ユーザーの知らないうちにユーザーとそのコンピュータに関する情報を収集する。
> 一例として、銀行のIDとパスワードなどを収集する。

### アドウェア
> アドウェア自体はマルウェアではない。アドウェアは、作成者の収益を生み出すために作り出されたソフトウェアです。
> アドウェアが組み込まれているソフトウェアは、マルウェアが含まれているとブロックされます。

### ボットネット
> マスターとなる端末に代わってインターネット上の他の端末に対してデータを転送するために奪われたインターネット接続されたコンピュータです。その端末はゾンビと呼ばれ、端末で構成されたネットワークがボットネットです。ゾンビの別名称として、ロボットまたはボットと呼ばれることもあります。
> ロシアを拠点とするKaspersky Labsの報告によると、スパム、ウイルス、ワームではなくボットネットが、現在インターネットにとって最大の脅威となっています。シマンテックからの報告も同様の結論に達しました。
>> ボットネット保護も参照してください。
>> https://docs.fortinet.com/document/fortigate/6.0.4/handbook/688528/fortiguard-botnet-protection

### フィッシング
>> フィッシングとは、有名な機関、会社、またはWebサイトなどの信頼できる機関からの通信になりすまして機密性の高い機密情報を入手するために使用されるソーシャルエンジニアリングの手法です。
>> 通常、マルウェアは通信自体ではなく、通信内のリンクに存在します。

### グレイウェア
> グレーウェアプログラムは、コンピュータにインストールされた迷惑ソフトウェアプログラムです。
> グレーウェアプログラムは一般的に迷惑と見なされますが、システムパフォーマンスの問題を引き起こしたり、悪意のある目的で使用される可能性もあります。
Windows10 WSLにawscliをインストール


aptを使ってインストールすればOK.

```
$ apt install awscli
```

パスを通す

```bash
$ export PATH=~/.local/bin:$PATH
```


入ったか確認

```bash

$ aws --version
aws-cli/1.16.198 Python/2.7.15+ Linux/4.4.0-17763-Microsoft botocore/1.12.188

$ which aws
/root/.local/bin/aws
```
Material-UIのSelectの高さを変えたい時

Material-UIでSelectを使う時、optionのlength数がかなり多い時があると思います。
今回はレアケースの紹介になりますが、「Material-UIのSelectで高さを調整したい」をテーマにしようと思います。

## ビフォー＆アフター
例でお見せするのは「0〜1000」（50飛ばし）の数字から選ばせるセレクトボックスです。
このようにoptionが多すぎると、セレクトボックスをクリックした時ブラウザの高さ90％を占拠することになります。

<img width="229" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/e4bdf0bf-f147-58e2-7878-d8e225faca04.png">

高さをもう少し縮めて、表示する位置も正しく調整することにします。
目指すアフターはこちらです。
<img width="184" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327745/21d819dc-7210-e51f-d83d-90bfdb90fd73.png">


## 実装


```javascript
const selectValues = [
  0,
  50,
  ・・・
  1000,
]

  ・・・

<Select
  name="sample"
  value={this.state.sample}
  onChange={onChange}
  MenuProps={{
    anchorOrigin: {
      vertical: 'bottom',
      horizontal: 'left',
    },
    transformOrigin: {
      vertical: 'top',
      horizontal: 'left',
    },
    getContentAnchorEl: null,
    classes: {
      paper: classes.dropdownStyle,
    },
  }}
>
  {selectValues.map((value) => (
    <MenuItem value={value} key={value}>
      {value}
    </MenuItem>
  ))}
</Select>
```

スタイルを調整する`dropdownStyle`はこんな感じです。

```javascript
const styles = () => ({
  dropdownStyle: {
    maxHeight: 300,
  },
})
```

Material-UIの場合、`withStyles`を使わなきゃなのですが…！(^◇^;)

①`<Select />`のpaperに対し、cssを当てます。そこでセレクトをクリックした時に表示される、オプションをラップするPaperを調子することが出来ます！
②`anchorOrigin`、`transformOrigin`を指定することで、ドロップダウンメニューが常にセレクトボックスに対してどの位置に表示させるかと指定できます。

## まとめ
最初指定するのに迷ったので記事にしてみました。Material-UIについて、特殊な実装やスタイル調整があったら記事にしようと思います^ ^
（何気にlodashの記事について「いいね」を頂いてるのと、自分がlodash使ってるのでlodashシリーズ次回から続けます笑）