OmniAICreator/Qiita-1.07M huggingface dataset:
CodePipelineが遅い

検証のために、AWSのデプロイツールをいろいろ試しています。
今回、CodePipelineによる以下のような一連のデプロイフローを試していました。

`CodeCommit -> CodeBuild -> CodeDeploy`

が、いかんせんデプロイまでにかなり時間がかかります。
前回はCodeDeployの速度改善をしましたが、リリースコンテンツを増やしたところ、`CodeCommit`の部分でもかなり時間がかかることがわかりました。

# CodeCommitが遅い
デプロイフローの一連の流れを検証している際は、リリースコンテンツを1MBぐらいにしていたので気が付きませんでしたが、リリースコンテンツを増やすとかなり時間がかかってしまうことがわかりました。

### デプロイしてみる
今まで`1MB`ぐらいだったリリースコンテンツを、`2GB`ぐらいにしてCodeCommitにコミットしました。
今回ビルドする要件はなかったので、CodeBuildは外しました。
なお、今回リリースする対象サーバーは1台とします。

### CodePipelineの結果

リリースコンテンツが`1MB`のときは、CodeCommitにコミットをしてから、デプロイが完了するまでの時間は、**約3分**でした。
![CodePipeline   AWS Developer Tools (1).png](https://qiita-image-store.s3.amazonaws.com/0/306374/a4cbac16-2533-5e4f-0191-6541864db686.png)

リリースコンテンツを`2GB`に増やしたところ、CodeCommitにコミットをしてから、デプロイが完了するまでの時間は、なんと**約12分半**でした。
![CodePipeline   AWS Developer Tools.png](https://qiita-image-store.s3.amazonaws.com/0/306374/74edf85d-eb77-4ed9-93b0-ba4f7b6ec0dc.png)

容量が増えるので、ある程度時間が増えるのは当然わかっていましたが、想定よりかなり時間がかかってしまうことがわかりました。

### CodeCommit部分
今回の一連の流れでは、まずCodeCommitのコンテンツが固められ、S3に配置されることになります。ここでかかった時間は**約8分半**です。
ここは、単純にCodePipeline側が裏でやっているだけなので、おそらく小手先による時間短縮はできないのではないかと思っております。
一気に2GBのコンテンツを追加コミットしたからなのかな〜？と思い、その後1ファイルだけコミットしてみましたが、時間は変わりませんでした。毎回リポジトリのコンテンツ全てに対して処理がされるようです。
リリースの度にこれだとしんどい…。1ファイルアップしただけなのにこれとは…

### CodeDeploy部分
CodeDeployのログを見てみると、`DownloadBundle` と `Install`で、それぞれ1分程時間がかかっていることがわかります。まあここはこんなもんですかね。
![CodeDeploy   AWS Developer Tools (2).png](https://qiita-image-store.s3.amazonaws.com/0/306374/7f58a66d-416a-e267-e31e-82257206c315.png)

# 感想
やはりどうやってもCodePipelineによるデプロイ方式だと、それなりに時間がかかってしまうようです。
CodePipelineによるデプロイ方式は、AutoScalingに対応していたり、ローリングデプロイができたりと、かなりオシャレだと思っていたのですが、頻繁にコンテンツのリリースがあったり、静的サイトや、ビルド要件がないPHPのサイトであれば、Gitpull方式や、rsync(s3sync)方式のデプロイのほうがよいかも…と感じるようになってきました。
【Unity】Version2 当たり判定


<font color="Magenta">ショットガンで敵を倒す（当たり判定）</font>
環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1


実際に動かした動画はこちら↓↓
https://twitter.com/nonnonkapibara/status/1066154795570946048

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Version2. 当たり判定<br><br>ショットガンで敵を倒す（⭐️当たり判定⭐️）を勉強したよぉ。<br>Ｏ(≧∇≦)Ｏ <a href="https://t.co/GpKwPPpLT0">pic.twitter.com/GpKwPPpLT0</a></p>&mdash; non (@nonnonkapibara) <a href="https://twitter.com/nonnonkapibara/status/1066154795570946048?ref_src=twsrc%5Etfw">2018年11月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


続きは、「はてなブログ」に記載してます↓
[かぴばらさんの覚書ブログ nonkapibara](https://nonkapibara.hatenablog.com/entry/2018/11/24/201309)
初めてAngularを使ってデモプログラムをつくってみたときにわかったこと９つ


わたしはこれまで主にjqueryを使ったシステムの開発を行ってきましたが、udemy/Youtubeのオンラインコースを受講し、angularを使ったシステム開発の基礎を学びました。
その際、Angularを初めてとするSPA(Single Page Application）の作り方はこれまでと比べて、大きく考え方が異なる箇所がいくつかあることがわかったので、それらをここで整理してみます。


ここでは、SPA以前のフロントエンド開発手法を複数ページを前提に作ることかMPA(Multi Page Application)と呼ぶことにします。
（一応、ここでそのように呼ばれているので。一般的なのかどうかは知りませんが、、、）
https://medium.com/@NeotericEU/single-page-application-vs-multiple-page-application-2591588efe58

##開発方針・制約


###①クライアントサイドとサーバサイドのプログラムは疎結合
MPAではクライアントからのアクセスがあるとそれをサーバ側で受け取り、次のページを返す動きをするため、サーバプログラムとは切り離せない関係にありました。
SPAでは基本的な画面遷移はクライアント側でのみ完結し、データが必要な時のみサーバにアクセスする。接続先はリクエストを出すときに指定ができるため、同じサーバ、ドメインである必要がありません。
そのため、クライアントサイドのプログラムはapache やAmazonS3などの静的サイトのみ公開できる環境に配置することも可能です。

###②クライアントサイドのプログラムは静的サイトなどにおいておくことができる
MPAでは、サーバ側に都度リクエストを行い、サーバ側で動的にhtmlを作成させるため、クライアントとサーバーは切り離せない関係にありました。
SPAの場合、サーバとクライアントは疎結合となるため、別のサーバに配置されていても問題はありません。
また、**クライアントサイドのプログラムはapacheやamazon S3など、静的なページのみを扱うサーバに配置しても問題なく動作させることができます。**←個人的にはこれが一番驚きでした。

###③サーバを介さなくても、画面間で値の持ち回りができる
MPAでは画面更新の際、その値を一旦サーバに渡すか、クッキーやローカルストレージなどに入れないと値を画面間で持ち回ることはできませんでした。SPAではサービス内の変数に値を登録しておけば簡単に持ち回ることができます。（angularの場合）

###④サーバとの通信はRESTでおこなう
MPAの場合、基本的には毎回サーバ側にGETかPOSTでアクセスを行い、毎回すべてのページ情報をサーバから受け取るという形であった。対して、SPAでは必要な情報だけを受け取り、ページ内の該当する部分を更新するという形となる。

###⑤セッション使わない（で済む）
MPAの場合、画面間の値の持ち回りの方法を簡略化するため、また、ユーザーの認証・認可情報などを持ち回るためにセッションを利用することが一般的でした。
SPAの場合、値の持ち回りはjavascript の変数内に保存しておけばよく、また、認証・認可の情報はjwtなどを使ってトークン内に持たせるというのが一般的になっているため、セッションを使う必要があまりありません。
セッションを利用すると、サーバーの負荷によってスケールアウトやスケールダウンする際のが難しくなってしまうので、できるだけ利用しないようにした方がよい様です。

###⑥テンプレートエンジンの利用が不要
MPAの場合、sitemeshやapache tileなどを使い、サイドメニューや画面上のロゴなどが共通的に出力されるように設定を行う必要がありました。SPAの場合、最初の読み込み後はコンテンツ部分のみを入れ替えるようにするため、この部分の考慮が不要になります。



###⑦複数のサーバと通信可能
クライアントとサーバが切り離されているため、クライアントはどこのサーバへでもアクセスできます。取得するデータによって接続するサーバを切り替えることも可能です。
例えば、機能AではGithubから開発者の情報を取得し、機能Bでは本の情報をAmazonから取得した情報を表示することなどもできます。


## 認証系

###⑧認証を別サーバで行うことができる。
認証をする際は、どこかに認証情報（IDパスワード）を渡して、連携先のサーバが理解できるトークンが入手できればよい。先述の通りクライアントとサーバは疎結合なので、認証先は最初にアクセスしたサーバ以外でもよい。（この場合、認証の際は両者から受け取った情報を裏で認証サーバに投げるというやり方となる）


###⑨認可はトークンで行う
認証・認可は最初の認証で認証サーバからtokenを受け取り、認証完了後はそのトークンをリクエストヘッダ（Authentication: が一般的）に含めることでサーバ側に誰のリクエスト化を伝えるする形が一般的。
tokenの格納先はlocalStorage、また、token改ざん防止のためにJWTを使う


## まとめ
特に他のサーバにクライアント側からリクエストを投げる点、セッションを使わない点など、MPAに慣れている人は違和感を感じるかもしれないです。（私もその一人）
でも複雑な部分はフレームワーク側が吸収してくれており、開発の際の記述はかなりシンプルになります。
そのため、最初に学習コストはかかりますが長期的にはこちらの方が記述しやすく、メンテもしやすいと思います。

また、Angularなら今流行りのマイクロサービスの実現も、比較簡単に実装できそうです。
（これまでマイクロサービスのサービスを聞いて概念的には理解していましたが、具体的にどうやって実装すればよいのかをイメージすることが難しかった）
マイクロサービスは、クラウドと相性が良いため、最初は最小スペックで公開し、
負荷に応じて自動スケールアウトしておけばコストを最小限に抑えることもできるというメリットもあります。

次に新規でシステムを開発する時は、ぜひSPAで開発しましょう！（したい）



## 参考ページ

- Angularを使った開発既存のレクチャー動画(Udemy)
https://programmingwithmosh.com/courses/angular

- Angular Tutorial (Youtube)
https://www.youtube.com/watch?v=0eWrpsCLMJQ&list=PLC3y8-rFHvwhBRAgFinJR8KHIrCdTkZcZ


- JWT(Jason Web Token) 
Jason Web Tokenについての利用の仕方、デバッガなどがここで使える。
これでジョットと読むらしい
https://jwt.io/
COBOLの私見

**1. はじめに**
---------------------------------------
  今ではすっかり新規案件のないCOBOLですが、今後の動向を私見ですがまとめたいと思います。
　とはいえCOBOLを新入社員に覚えさせようとする企業もあるのも現実です。
　汎用機が減っていく中、リプレイスの案件も多くなってくると思うので、ここでは特徴をまとめたいと思います。

**2. COBOLとは？**
---------------------------------------
  1959年に事務処理用に開発されたプログラミング言語である。
  名前は「Common Business Oriented Language」（共通事務処理用言語）に由来する。
  ※WIKIより

**3. 特徴**
---------------------------------------
　大きくあげると以下の３つの特徴があります
　・非理系の事務員でもプログラミングできる言語として誕生
　・英語に近い記述
　・ソースコードは記述が冗長だが、可読性が高い

**4. COBOLのメリット**
---------------------------------------
1. 保守性・可読性
可読性が高いため、保守性も高い
誰が書いても同じようなソースになるため、解析に時間がかからない

2. 数字が正確
金額のような「正確な数値計算」が必要な場合、演算誤差や小数点処理などで、やや正確に書ける場合があります
COBOLは数字の正確性については非常に優秀です

3.  COBOLの多い業界
前述のメリットと物凄く親和性の高い業界があります
「金融・証券・保険系」業界です
数字の正確性が必須として求められる業界です
昨今のIT業界で未だにCOBOL言語で稼働しているのは、数字の強さが一番の要因となっています

**5. COBOLのデメリット**
---------------------------------------
1. 汎用機がもうない
古いので部品があまりない
故障した場合のメンテナンスも少ない

2. 新規案件がない
既に開発が終わったものが殆どで、いわゆる「保守案件」が大半です

3. COBOL技術者の高齢化問題
可読性が高いとはいえ、エンジニアも少ない

4. 設計書・ソースがない場合がある
設計書なしで製造されていたり、実行ファイルのみを残しソースを誤って削除されている場合がある
※バックアップをとるMTやCMTの現存数も減ってきいるため使いまわしが多く誤って上書き処理を行いソースが消えてしまう場合がある

**6. 結果として**
---------------------------------------
各企業や業界の思惑はいろいろあると思いますが、COBOLを捨てて新しい言語で作成したい
または、なんとか延命したいなどありますが、ハードの問題上延命は厳しい状況です
今後の案件としてはリプレスや、マイグレーションといったものが多くなると思いますが、前述でもあげたとおり、設計書・ソースがない場合もあります
将来性のない言語でもあるので、改めてエンジニアが増えるということはないですが、リプレス、マイグレーション案件は結構大変な作業になると思われます
jsdoでblockly その10

#概要

jsdoでblocklyやってみた。
blocklyでsupershape書いてみた。

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/6be05245-b0b0-b54f-ed68-daf90a45c14d.png)


#スクリプト

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/eaa03a2f-30d8-28ae-6f1d-74734426b9f2.png)


#サンプルコード


```
var canvas = document.getElementById("world");
var ctx = canvas.getContext("2d");
var kame = function(ctx) {
    this.ctx = ctx;
    this.x;
    this.y;
};
kame.prototype.setPixel = function(xp, yp) {
	this.ctx.beginPath();
	this.ctx.moveTo(xp, yp);
	this.ctx.lineTo(xp + 1, yp + 1);
	this.ctx.stroke();
};
kame.prototype.superShape = function(x, y, a, b, m, n1, n2, n3, scale) {
    this.x = x;
    this.y = y;
	var r = 0
	var p = 0;
	var xp = 0;
    var yp = 0;
	while (p < Math.PI * 6)
	{
		var ang = m * p / 4;
		r = Math.pow(Math.pow(Math.abs(Math.cos(ang) / a), n2) + Math.pow(Math.abs(Math.sin(ang) / b), n3), -1 / n1);
		xp = r * Math.cos(p);
		yp = r * Math.sin(p);
		p += 0.01;
		this.setPixel(this.x + xp * scale, this.y + yp * scale);
	}
}
var k0 = new kame(ctx);
var demoWorkspace = Blockly.inject(document.getElementById('blocklyDiv'), {
    path: 'http://jeromeetienne.github.io/blockly-threex/apps/frame-edit/../../', 
    toolbox: document.getElementById('toolbox')
});
Blockly.Xml.domToWorkspace(Blockly.getMainWorkspace(), document.getElementById('startBlocks'));
function showCode() {
    Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
    var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
    alert(code);
}
function runCode() {
    var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
    run(code);
}
function showXml() {
    var xml = Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace());
    var code = Blockly.Xml.domToPrettyText(xml);
    var out = document.getElementById('output');
    alert(code);
    out.value = code;
}
window.run = function run(generatedCode) {
	commands = [];
	eval(generatedCode)
	setTimeout(function callback() {
		var command	= commands.shift()
		eval(command)
		if (commands.length === 0) return
		setTimeout(callback, stepDelay * 1000)
	}, 0)
}
var updateFcts = []
var commands;
var stepDelay = 0.5
var Turtle = {}
window.Turtle = Turtle
Turtle._say	= function(text) {
    var cond = text.split(',');
    k0.superShape(+cond[0], +cond[1], +cond[2], +cond[3], +cond[4], +cond[5], +cond[6], +cond[7], +cond[8]);
}
Turtle.say = function(text) {
	commands.push('Turtle._say("' + text + '");');
}	




```

#成果物

http://jsdo.it/ohisama1/2Dlr

以上。
react 復習




```javascript

わかる事
1　基本的に処理は変動しないモノには、funcsionコンポーネント　変動するやつは、classコンポーネント
2 input イベント　出力　は（inputの周りの部分）
補足
fieldsetはinputをグループ化する

import React from 'react';
import ReactDOM from 'react-dom';
import './ShippingList.css';

// import App from './App';
import * as serviceWorker from './serviceWorker';

function BoilingVerdict(props) {
  if (props.celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}



class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    return (
      <fieldset>
        <legend>Enter temperature in Celsius:</legend>
        <input
          value={temperature}
          onChange={this.handleChange} />

        <BoilingVerdict
          celsius={parseFloat(temperature)} />

      </fieldset>
    );
  }
}

ReactDOM.render(<Calculator />  , document.getElementById('root'));



// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();



```
Pythonで確率分布

StanとRでベイズ統計モデリング Chapter 6 から

# Gamma Distribution


一定期間に1回起きると期待されるランダムな事象が複数回起きるまでの時間の分布
期間1/λあたりに1回起こると期待されるランダムな事象がα回起こるまでの時間の分布
指数分布は一度イベントが一度起こるまでの間隔を表すのに対し、ガンマ分布は単位時間あたりの回数が1/βのイベントがα回起こるまでの時間間隔を表す
機械が複数の箇所が壊れてから故障する場合や、指数分布に従って起こるイベントが複数回起こる場合に用いられる。無記憶性があるのはk=1の時だけ

$ Gamma(y|\alpha,\beta) = \frac{\beta^{\alpha}}{\Gamma(\alpha)} y^{\alpha-1} exp(-\beta y) $
$ \frac{\beta^{\alpha}}{\Gamma(\alpha)} $ 積分を１にするための正規化定数
$ y $: 正の実数
$ \alpha, \beta $: 正の実数 $ \alpha $ Shape パラメータ、$ \beta $ rate パラメータ
$ E(y) = \alpha / \beta $
$ V(y) = \sqrt{\alpha} / \beta $


```
plt.figure(figsize=(10,5)) 

k = [1,3,3]
theta = [1,3,1]

x = np.linspace(0,6,100)

for i in zip(k,theta):
    rv = gamma(a=i[0], scale=1/i[1])
    y = rv.pdf(x)
    plt.plot(x, y, label=u'$ α={0:.1f}, β={1:.1f} $'.format(i[0],i[1]))

plt.xlim(0,6)
plt.grid()
plt.xlabel("y")
plt.ylabel("density")

plt.legend(fontsize='small')
plt.title("Gamma")
plt.xlabel("y")
plt.ylabel("density")

```



![fig_6_9.png](https://qiita-image-store.s3.amazonaws.com/0/245461/55f7cd77-26df-534e-0c0e-0c84358b4d4e.png)
デバイスドライバのバックアップ

#ドライバーをバックアップする手順
1. コマンドプロンプト（管理者）を起動
2. コマンドプロンプトより次のコマンドを実行します。
```mkdir C:\DriverStore```
3. コマンドプロンプトより次のコマンドを実行します。
```dism /online /export-driver /destination:"C:\DriverStore"
```
4. 作製した```DriveStore```をDVD-Rに保存する。
AWS CodeDeployの速度改善(ALB)

CodePipelineの一連の流れを確認するためにテストをしているのですが、
CodeDeployにおいて、`BlockTraffic`と`AllowTraffic`が共に5分程かかっていました。
リリースのたびに10-15分も時間がかかることになってしまいます。

画像の差し替えなど、かなり頻繁にコンテンツリリースが発生するので、このままでは使い物になりません。
そのため、なんとか速度改善ができないか足掻いてみました。

# 環境
- ALBBlockTraffic
- インプレースデプロイ方式
- AutoScaling
- リリースコンテンツの総量は1MB程度


## [対応その1] ヘルスチェックのパラメータを変更してみる
[AWSフォーラム](https://forums.aws.amazon.com/thread.jspa?threadID=254752&tstart=0)に記載があったのですが、デプロイのライフサイクル中の`BlockTraffic`と`AllowTraffic`は`ELB`のヘルスチェックの設定に関係しているとのこと。
そのため、ヘルスチェックの値を変更すれば改善が見込めそうということがわかりました。

そこで、ALBにぶら下げているターゲットグループのヘルスチェック設定を、それぞれ最小の値にしてみました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/306374/eef55cf3-a625-24f1-105f-0bad70cef398.png" width=70%>

そのうえでCodeDeployを実行したところ、`AllowTraffic`の項目を**5分強 → 約1分**と大幅に短縮することができました。
![CodeDeploy   AWS Developer Tools.png](https://qiita-image-store.s3.amazonaws.com/0/306374/6a8e64ec-e044-1d74-72ec-ad3aa08b91af.png)
ただ、残念ながら`BlockTraffic`は変わらず5分強時間がかかっています。

どうやら、ロードバランサが`ALB`ではなく`ELB`の場合は、この設定だけで`BlocdTraffic`も短くなるようなのですが、`ALB`だとうまくいかないですね…

## [対応その2] Connection drainingのパラメータを変更してみる
今度は、`BlockTraffic`が毎回`5分(300秒)強`かかっていることに着目しました。ALBの`Coonection draining`のデフォルトの時間が`300秒`なので、ここの設定がなにかしら関係しているかもと思いました。

Connection drainingは、
`ターゲットグループ > 説明タブ > 項目 > 登録解除の遅延`
と辿ったところの項目です。

ここの値を、試しに`300秒から10秒`に変更をしてみました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/306374/337b5284-5416-7ad0-27ac-183b7299c704.png" width=80%>

そのうえでCodeDeployを実行してみたところ、見事`BlockTraffic`の項目を、
**5分強 → 10秒**と大幅に時間短縮をすることができました。
![CodeDeploy   AWS Developer Tools (1).png](https://qiita-image-store.s3.amazonaws.com/0/306374/b38ab17c-2377-bdc3-aa54-3af3140da0a2.png)
# 感想
なんとかALB環境でもCodeDeployの時間短縮をすることができました。

今回AWSのcode兄弟を使用したデプロイ方式はを触ってみて思ったのは、頻繁に静的コンテンツのリリースが発生したり、コンパイルが必要ないPHPなどのサイトであれば、この仕組みは大掛かりすぎな気がしています。
今回はCodePipelineの一連の流れを確認するために、リリースコンテンツを1MB以下の状態で実施しましたが、次はリリースコンテンツの量を増やして、どのぐらい時間がかかるか試してみようと思います。
Paint.NETインストール後にMS Paint（通称ペイント）が右クリックの編集から開けず、Paint.NETが起動してしまう問題の対処法

Paint.NETインストール後にMS Paint（通称ペイント）が右クリックの編集から開けず、Paint.NETが起動してしまう問題の対処法

手順：
一度Paint.NETをアンインストール
↓
Paint.NETのインストールで「カスタム」選び
↓
「JPEG、PNG、および BMP イメージの既定エディターとして使用する」
のチェックを外す。
↓
あとは「次へ」を適当に押してインストール。
jQueryとサーバレンダリング

# 世間一般はSinglePage、サーバレンダリングはもう古い
今の職場でもそんな意見はよく耳にする。世の中は、AngularとかTypeScriptとかWeb開発技術は10年前とは大きく変わっていることはもちろん、そんな技術を使って開発したいと常々思っている。

でもね、世の中にはまだあるんですよ。
予算や人的リソースの関係で過去の遺産やノウハウを使い回しでやりくりしないといけないプロジェクトや、「ローカルネットワークでしか動作しないから」という理由で、いまどきStruts1とか使って動いてるシステムが。
そんな滅びの呪文を唱えたい化石システムであっても、仕事となればメンテナンスしていかなくてはならない。

でも、だからこそ、そんな10年前の技術をバリバリ活用するプロジェクトではjQueryって本当に重宝する。

これからJavaScriptを勉強し始めるビギナーにとっては、廃れ始めたjQueryよりVue.jsみたいなモダンなフレームワークを学んだほうが有益かもしれないが、食わず嫌いはよくないよね。
あと、Struts1に比べたらjQueryはサポートも続いているし、何よりもその手軽さ、シンプルさは今でも変わらない魅力があるので、個人的には生き残ってほしいと思っている。

そんな、古臭い技術を使う現場で働く人間にとって、なくてはならないjQueryを改めて勉強し直して感じた感想を記事にまとめてみる。

# jQueryが嫌われ始めた理由
個人的には以下じゃないかと思う。

 - ブラウザが進歩して標準サポートする機能が多くなった
	- 昔はjQueryで機能を補ってた
 - ブラウザごとの機能差異がなくなってきた（統一されてきた）
	- それまではjQueryが差異を吸収してくれてた
 - JavaScriptという言語自体(ECMAScript)が成長した
	- MVCの概念を実現しやすくなり、MVCなフレームワークが注目を浴び始めた
	- クラスやモジュールの概念が強くなってグローバル領域に作られるjQuery(`$`)が嫌われる理由になってしまった

でも、これって新しいブラウザで動くシステムを作るならってことだよね。

ちなみに、モダンなフレームワークだとDOM操作は嫌われていて、避けるべきとされているけど、その理由は**画面上の見た目と管理したいデータがごちゃごちゃになるのを避けたいから**というのが理由の一つだと思っている。
でもこれは設計次第で軽減できることなので、jQueryを嫌う理由とは違うのではないだろうか。

# jQueryの強み
ひとことで言うと **昔のやり方で開発するなら超便利**ってこと。

昔はJavaScriptでオブジェクト指向やMVCな設計をしようとすると、かなりトリッキーな方法で実装しないといけないのが普通だった。だからこそjQueryが重宝して、jQueryがあれば古いブラウザでも簡単に実装できた。今保守しているシステムも、Windows7のIE9とか、VistaのIE7だったりするので、そんな環境ならjQueryは超便利。

あと、jQueryが得意とするDOM操作だが、画面がSinglePageでなく、Struts1みたいなサーバレンダリング方式ならむしろ積極的に使わなければならない。サーバレンダリングだとページ遷移で毎回メモリ解放されるから、管理したいデータは毎回消えてしまうし、ページ遷移後も同じデータを持ちたいならレンダリングされた画面から取り直さなければいけない。これは画面遷移後にDOM操作が必須になることを意味するので、jQueryの得意とする分野になる。

また、メモリ解放が画面遷移の都度行われることは、以下のメリットもある。

- DOMに登録したイベントも定期的に消える
	- 「イベント管理地獄」に陥りにくい
- グローバル変数も定期的に消える。
	- そのページ内だけだから管理できる範囲に収まる

そもそも、サーバレンダリング方式だとサーバに主なロジックがあるからJavaScriptのロジックが少なくて、保守するjsコード自体が少なくなる。JSPのカスタムタグなどはサーバ側のロジックで画面の見た目（ビュー）を作る。

# 注意すべきは移行するとき
今はかろうじて動いているstruts1なシステムも、いつかはリプレースするときが来る（と信じている）。jQueryを使った現役コードは、その時に別のフレームワークに置き換えられるかもしれない。注意すべきは、そんなときのことを考えてコーディングすることだと思う。

流行りのモダンなフレームワークの使い方や設計思想を理解した上でjQueryと向き合っていくことは忘れてはいけないことだろう。
Grid SOPのTextureCoordinatesをoffにしたら落ちる

# はじめに
とあるシステムを作るのによくあるGPGPU + Grid SOPのParticles作ろうとしてはまったのでメモ。

# やろうとしたこと
粉をきっちり数を決めてきっちり並べたい。
基本の粉出しは@ToyoshiMoriokaさんの[こちら](https://qiita.com/ToyoshiMorioka/items/91c4e1427c2b4296c2a4)を参照。
今回は粉を飛ばすのが目的ではなく、立方体状に整列させたかった。

# 現象
Grid SOPのTextureCoordinatesをoffにして、階層を移動して戻ってくると落ちる。

# 原因・解決策
今回きっちり数を決めたかったので、Gridを通常の様に正方形状にする、つまりRowsとColumnsを同じ数にすることに抵抗がありました。
「数決まってんなら最初からそうすればいいじゃん！」と。
ここはまだよかった。

「Grid SOPのRowsをパーティクルの数、Columnsを1にすればかけたらパーティクルの数になるからいいじゃん！」
ここがまずかった。

どうやら**GridSOPのColumnsを1にしてTextureCoordinatesをoffにすると落ちる**らしいです。

この「1」がまずいと踏んで、
**解決策1. Rowsをパーティクル数/2、Columnsを2**
にしてみました。
落ちなくなったのでここが問題で間違いないようです。

と、ここでふと疑問に思い、
**解決策2. Rowsを1、Columnsをパーティクル数**
にしてみました。
落ちなくなりました。何が違うんだ...

# おわりに
原理的に筋が通ってるはずなのに動かない時つらいですよね。
タッチ使ってみてやめた友達に聞いた、「タッチの設定の問題かこっちのコードの問題かわからないのがきつい」というのが今回よく実感できました。確かにつらい。
気合でこねくり回してどうにかしましょう。
OS判別とPythonと私

# （※割とどうでもいい）

　tensorflowのチュートリアルで、こんな行を見つけたんだけど、どっからどう見てもposix
　Windowsで開発するんだけど、この書き方でいいのかなーみたいに悩んで、結局、posixでもWindowsでも動く書き方にした

※修正前

```python
tf.gfile.MakeDirs("/tmp/XXX")  // XXXは何でも
```

※修正後

```python
if os.name == 'nt': tmp_dir = "~\\AppData\\Local\\Temp\\census_data" // Windowsの場合
else: tmp_dir = "/tmp/census_data"  // posixの場合

tf.gfile.MakeDirs(tmp_dir)
```

もっとエレガントな書き方があるかも
ubuntu 18.04 /dev/kvm permission denied について

環境ubuntu 18.04
https://developer.android.com/studio/install?hl=ja
develperの手順に従ってインストールしても仮想デバイスが作成できませんでした。

エラー内容　/dev/kvm permission denied 
の場合以下のようにkvmをインストールしてからkvmグループにユーザー名を追加することで
動かせました。

sudo apt install qemu-kvm
sudo adduser $USER kvm


sudo chown username -R /dev/kvm
でも動かせますが再起動してしまうとpermissionが変更され
deniedなってしまいます。理由はわからなかったです。
どなたかわかる方がいましたら教えてくださると助かります。


追加情報
sudo apt install qemu-kvm
sudo adduser $USER kvm
したあとは再起動してください。
設定が反映されません。
第49話 二乗数

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第49話です。

```math
\begin{align}
6667^2&=44448889\\
667^2&=444889\\
67^2&=4489\\
7^2&=49\\
\end{align}
```

最後の式はそのままなので特に数学的な説明は必要ないでしょう。

中央の48の数字がどんどん消えていき、最後49だけが残る演出で、
48話を終え、49話が始まるというなかなか凝った演出でした。

最終回時では、桐生戦兎と万丈龍我の二人が、
両方共ハザードレベルが7だったので、左辺の7の二乗もそれを表しているかもしれません。

二乗といえば、こういう面白い式もありますね。

```math
\begin{align}
1^2&=1\\
11^2&=121\\
111^2&=12321\\
1111^2&=1234321\\
11111^2&=123454321\\
111111^2&=12345654321\\
1111111^2&=1234567654321\\
11111111^2&=123456787654321\\
111111111^2&=12345678987654321 
\end{align}
```
第48話 ベルトラン・チェビシェフの定理の拡張

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第48話です。

```math
\arg⁡min_{N}⁡[∀≥N,∃p∈(N,\frac{9}{8}N)] =48
```

ベルトラン・チェビシェフの定理の拡張です。
ベルトラン・チェビシェフの定理とは、ある数nとその2倍の数の間には素数が必ず存在する、という定理です。

例えば、3と6の間には5という素数があります。
10と20の間には、11,13,17と3つも素数があります。

2倍だと範囲が広いので、48以降の数とすれば、
この範囲を1.125倍まで小さくできるのが今回の式です。

48と54の間には53という素数があります。
53を避けて54～60にすると59があり、
60～66だと、61があり、という風に次の素数がどんどん出てきます。

nとn×a(a>1)との間に素数が必ずあるようにするには、aはどこまで小さくできるでしょうか。
結論から言えば、どこまでも小さく出来ます。

なぜなら、aがどんなに小さくても、nを無限大まで大きくしてしまえば、
どこかで条件を満たすnが見つかってしまうからです。

素数定理によると、素数の出現確率はlog nですから、
10000だと約1/9、1億だとその半分の約1/18です。

素数の出現確率が対数で表されるということは、2乗すると確率が半分になります。
ですから、今の数に対して何倍、という計算では
数が大きくなればなるほど余裕で条件を満たせるようになります。
do {} while (0); の意味

## 拝啓

カーネルソース読んでるとよく出てくる「do {} while (0);」
これが何なのか気になったので調べてみました。

[torvalds/linux](https://github.com/torvalds/linux/blob/master/include/linux/kernel.h)

以下swap関数のようなイメージ
至るところでdo {} while(0)が存在

``` c:include/linux/kernel.h
/**
 * swap - swap values of @a and @b
 * @a: first value
 * @b: second value
 */
#define swap(a, b) \
	do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
```

## C言語におけるマクロとは

プログラムの中の文字列を予め定義した規則にしたがって置換する機能のこと
マクロは「#define」というプリプロセッサ指令により定義される

## プリプロセッサとは

一般にある処理を行うソフトウェアに対して、
データ入力やデータ整形などの準備的な処理を行うソフトウェアのことである。
特にコンパイラに対して使うことが多い

## プリプロセッサ一覧

C言語には以下膿瘍名プリプロセッサ指令がある

|種類|説明|
---------|----
#define  |マクロを定義
#ifdef   |シンボルが定義されているときに定義する(類似で#infdef、#endif)
#if      |式が真のときに実行する
#include |ヘッダファイルのインクルード
#error   |コンパイラにエラーを発生させる
#warning |コンパイラに警告を発生させる
#prgma   |マシンやOS固有の機能をサポートする

今回ポイントとなるのは「#define」です。

## #defineについて

defineで定義されるマクロいくつか種類があります。
その中でも今回は「関数形式マクロについて取り上げます」

* オブジェクト形式マクロ
* 関数形式マクロ

関数形式マクロとは、マクロ置換を行う時に引数を取ることができ、あたかも関数のように使用できるマクロです。
関数形式マクロは、次の書式で定義します。

``` c:define.c
#define マクロ名(引数の並び) 置き換えられる処理
```

上記を使った簡単なサンプルプログラム。
数字を入れ替えるマクロを定義し、mainで実行。

``` c:main.c
#include<stdio.h>

# 引数2つを入れ替えるマクロ
#define swap(a, b) \
        do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)

int main(int argc, char** argv) {
    int x = 10;
    int y = 20;

    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);
    SWAP(x, y);
    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    return 0;
}
```

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

``` bash
$ gcc main.c -o main
$ ./main
(x, y) = (10, 20)
(x, y) = (20, 10)
```

上記のような実装では特に問題はない事が分かりました。
自分で書いたマクロを自分で利用するだけなので今回は問題なし。
じゃあ何故do{}while(0)なんて入れてるんだろうってことで調べてみると
以下2点理由があった。

* 処理の打ち切りテクニック
* マクロを使用する場所に依存するエラーを防ぐ

今回は2点目の使用場所に依存するエラーを防ぐ目的がある模様。

具体的にエラーが出る使用方法は下記

``` c:main.c
#include<stdio.h>

#define swap(a, b) \
        typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;

int main(int argc, char** argv) {
    int x = 10;
    int y = 20;

    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    if (x > 20) SWAP(x, y);
    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    return 0;
}
```

マクロが展開された状態のソースは下記となり

``` c:main.c
#include<stdio.h>

#define swap(a, b) \
        typeof(a) __tmp = (a); (a) = (b); (b) = __tmp;

int main(int argc, char** argv) {
    int x = 10;
    int y = 20;

    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    if (x > 20) typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; //ここでエラー
    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    return 0;
}
```

エラーとなる原因はマクロ展開後のif文が「if (x > 20) typeof(a) __tmp = (a);」で完結しており
以降の行で出てくるa,bが未定義といったエラー

do{}while(0)を使用することで使用場所に依存しないマクロの定義が可能となる。

``` c:main.c
#include<stdio.h>

#define swap(a, b) \
        do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)

int main(int argc, char** argv) {
    int x = 10;
    int y = 20;

    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    if (x > 20) do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
    fprintf(stdout, "(x, y) = (%d, %d)\n", x, y);

    return 0;
}
```
yolo v3の実行結果をopenCVで出力する

#前回
とりあえずyolo v3で学習済みモデルを動かすことはできた。そしてその結果は、「一致度」としてテキストとして出力されるのに加え、darknetディレクトリ内にpredictions.jpgという画像ファイルが生成されることまで確認した。

#今回のゴール
yolo v3を実行後するとその結果が画像ファイルとして自動で立ち上がるところまで。

#やってみた
何はともあれ、openCVのインストール。
brewはすでにインストール済み。

```
brew install opencv
```

他の方の記事を参考に、darknet配下のMakefileを編集する。
vimはあまり好きではないので

```
open Makefile
```
で編集する。
ファイルを開くと、以下の設定がデフォルトで表示される。

```
GPU=0
CUDNN=0
OPENCV=0
OPENMP=0
DEBUG=0
```
この項目のうち、使うものは1に書き換えれば良いらしいが、今回はopenCVのみ1に書き換え、保存。ターミナルに戻ったら忘れずにmakeする。

```
make
```
すると、めちゃめちゃエラーが出た。どうもopenCVの場所がわからない的なことを言っている。
というかそもそもopenCVはちゃんとインストールできているのか？と思い、色々調べると、以下のコマンドで確認できることがわかった。

```
pkg-config --modversion opencv
```
と思いきやそもそもpkg-configがインストールされていなかったため、brewでインストール。

```
brew install pkg-config
```
もうpkg-configを実行すると、バージョンが帰ってきたのでちゃんとインストールはされているようだ。


まさかと思い、もう一度MakefileでOPENCV=1にし、makeするとエラーが出なかった。
ただpkg-configをインストールしていなかっただけというオチ。結構時間を使ってしまった。

#結果
このあと前回同様

```
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
```
で実行すると、枠付きの画像ファイルが自動で立ち上がった。
![predictions.jpg](https://qiita-image-store.s3.amazonaws.com/0/319131/26b2a748-ce05-1e45-6753-257cdd042859.jpeg)
めでたしめでたし。
python webアプリ入門(2)

# 前回

python webアプリ入門(1)
https://qiita.com/tom_sakaguchi/items/5550e50ab2a88f2c5f38

# 今回の目標

　前回(ETロボコンに出たりでものすごく間が空いてしまいましたが・・・)は、簡単にflaskでwebアプリが作れるかどうかだけを試しました。ただ、最終的に何か実用的なものを作っていきたいという思いもあるので、もっと色々な機能を追加していこうかと思います。
あと、前回の記事を見返しましたが、結構穴だらけなのでその辺も適宜修正していこうと思います。

さて、今回の本題ですが、今回はテキスト入力機能を追加してみようと思います。ただ、単純に文字を入力できるだけではあまり楽しくないので、ちょっとした別の機能もつけてみようかと思います。

補足；今回から開発環境をMACにしました。開発環境の構築は以下を参考にしました。
(この記事に環境構築方法を書いたところで以下の参考リンクのコピペになりそうなのでやめておきます・・・)
https://www.simonsnote.com/entry/python-environment

ということで早速始めていきたいと思います。

# テキスト入力

まず、今回作った「server.py」は以下のようになります。
（私の趣味で申し訳ないのですが、今回は入力した番号の値と同じ背番号の中日ドラゴンズの選手名を出すプログラムにしました。）

~~~server.py
# server.py
from flask import Flask
from flask import render_template, request

list = ["高松", "友永", "荒木", "高橋", "藤井", "阿部"]

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])  # ①GET,POST メゾッドを受け取れるように変更
def index():
    if request.method == "GET": # ②GETメゾッドが受け取った時の処理
        return """
        下に５以下の背番号を入力してください。中日ドラゴンズの選手名を出力します
        <form action="/" method="POST">
        <input name="num"></input>
        </form>"""
    else:                      # ③POSTメゾッドが受け取った時の処理
        if int(request.form["num"]) <= 5:
            return """
            {}は{}です！
            <form action="/" method="POST">
            <input name="num"></input>
            </form>""".format(str(request.form["num"]), list[int(request.form["num"])])
        else:                  # 簡単なエラー処理
            return """
            不正な入力です！
            """

if __name__ == '__main__':
    app.run()

~~~

前回のソースからの変更をコメントにて番号をふったので、追って順に書いていこうと思います。

①これは、app.route内の「　methods=["GET","POST"]　」でhtmlのGETメゾッド、POSTメゾッドを受け取れるようにしています。これをやっておかないと入力フォームを作ったところでデータを送れないようです（この辺りは私もあまり詳しくないので以下の参考文献の方を参考にしてください）。

参考文献：https://qiita.com/nagataaaas/items/3116352da186df102d96

②これはGETメゾッドを受け取った際の処理です。はじめにブラウザでアクセスされた時に表示する画面の処理です。簡単な入力フォームの説明と入力フォームを作ります。

③これはPOSTメゾッドを受け取った際の処理です。入力された番号が背番号の選手の名前を表示します。
(続いて入力できるように、GETメゾッドを受け取った際の処理と同様に入力フォームとその説明も表示されます。)


# 動作確認

早速動作確認してみます。MACになったので以下のコマンドで動作しました。

~~~
$python server.py
 * Serving Flask app "server" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
~~~

「`http://127.0.0.1:5000`」にログインしてみると、以下の表示になりました。成功のようです。

![スクリーンショット 2018-11-24 16.50.20.png](https://qiita-image-store.s3.amazonaws.com/0/266944/22073ea9-9c28-a2ae-2377-d09688e5d9c6.png)

3を入力してreturnを押してみると・・・

![スクリーンショット 2018-11-24 16.51.42.png](https://qiita-image-store.s3.amazonaws.com/0/266944/4cc03550-41cd-e8f9-56ce-57c4d5cc464a.png)

問題ないようです！

# 最後に

個人的には、いつもCやC++、アセンブラばかりやっているのでなかなか慣れませんが、これからは折れずに更新していこうかと思います。

次はhtmlとの連携や画像のアップデートや画像処理もちょっとだけ入れていきたいです。
factory botのtraitsとtrasientが便利だった

Rspecでテスト用データを作るのに、FactoryBotを使っている方は多いと思うけど、あるオブジェクトに関連しているオブジェクトを作るとき、FactoryBotの１機能で`traits`を使っているかと思う。対して

```ruby
factory :user do
  trait :with_profile do
    after(:create) do |profile|
      create :profile, ...
    end
  end
end

# こんな感じでuserに紐づくprofileも一緒にオブジェクト作成できる
create :user, :with_profile
```

ただ、has_manyで子側の方を可変個数で作成したいとき、どうやるのかなと思ってたのだけど、一時的に本来のオブジェクトにはないattributeを許可する`transient attributes`を使えば、可変個数で作れて便利だった
ref: https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#traits

```ruby
factory :user do
  trait :with_articles do
    transient do
      amount { 1 }
    end

    after(:create) do |article, evaluator|
      evaluator.amount.times do
        create :articles
      end
    end
  end
end

# userに関連するarticlesを３つ作成する
create :user, :with_articles, amount: 3
```
[mac] rubyにbundleをインストールする

# はじめに

rubyが使える環境MacOS下でbundle initを実行するまでの流れです。

rubyのインストールは以下の記事を参考にしてください。
[[mac] brew - rbenv で rubyをバージョン指定でインストール](https://qiita.com/Knoth/items/50dc29a55bf9f13bc6f5)

# 環境

rubyのバージョンは以下の通りです。

```
$ ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-darwin17]
```

# インストール
gemコマンドでインストールしていきます。

```
$ gem install bundler
$ bundle -v
Bundler version 1.17.1
```

# bundle initを実行

```
$ cd (任意のプロジェクトフォルダ)
$ bundle init
Writing new Gemfile to /path/to/projectfile/Gemfile
```

出来ました！
Vueのライフサイクルを完全に理解した

# Vueのライフサイクルについて
今回はVueのライフサイクルについて説明したいと思います。
Vueのライフサイクルは以下のようになっております
https://jp.vuejs.org/v2/guide/instance.html#ライフサイクルダイアグラム

このようにVueではインスタンスが作られてから、削除されるまでの間で、ライフサイクルフックを実行することができます。
ここでは、インスタンスのライフサイクルごとに説明したいと思います。


## インスタンス作成時
インスタンス作成時には以下の2つのフックを実行されます
### beforeCreate
```vue:beforeCreate.vue
<script>
export default {
  data(){
    return{
      hoge:"a"
    }
  },
  beforeCreate () {
    console.log('hoge is: ' + this.hoge)
  }
}
</script>
// ->何も表示されない
```
これはインスタンスの生成前に実行できます
このタイミングでは、インスタンスは初期化前ですので、data()は呼ばれていません
### created
```vue:created.vue
<script>
export default {
  data() {
    return{
      hoge:"a"
    }
  },
  created() {
    console.log('hoge is: ' + this.hoge)
  }
}
</script>
// ->hoge is: a
```
これはインスタンスが作成された後で実行されます
個人的には`created`は一番使っている印象です！！
注意として、elementプロパティはまだここでは呼ばれていません

## マウント時
インスタンスが作成された後は、elementへのマウントがされます

### beforeMount
これは、インスタンスが作成された後、elementへのマウントされる前で実行されます

```vue:beforeMount.vue
<template>
  <div>現在{{hoge}}です</div>
</template>
<script>
export default {
  data() {
    return{
      hoge:""
    }
  },
  beforeMount() {
    this.hoge = "beforeMount"
  }
}
</script>
// ->表示されません
```
### mounted
これは、elementへのマウントがされた後に実行されます
よく、createdとの違いがわからないと言う意見が見られますが、
mountedは、elementへのマウントが行われた後処理されます。
したがって、elでelementを指定している場合、createdではタイミングとして早いと言うことになります。
また、mountedはSSRの場合は使えないので注意が必要です

```vue:mounted.vue
<template>
  <div>現在{{hoge}}です</div>
</template>
<script>
export default {
  data() {
    return{
      hoge: ""
    }
  },
  beforeMount() {
    this.hoge = "mounted"
  }
}
</script>
// ->現在mountedです
```
mountedでは子コンポーネント全てをマウントしたことは保証しません。
したがって全てのコンポーネントがマウントされるまでロードを待つには以下のようにする必要があります

```vue:mounted.vue
<script>
....
mounted() {
  this.$nextTick(function () {
    // ビュー全体がレンダリングされた後にのみ実行されるコード
  })
}
....
</script>
```

## データの更新時
データの更新時にはrerenderされるため、この前後でフックを実行することができます。

### beforeUpdate
データの更新があった時に、rerenderされる前に実行されます。
更新前の既存のDOMに対してアクセスすることができます。
また、beforeUpdateはSSRの場合は使えないので注意が必要です
### updated
データの更新があった時に、rerenderされた後に実行されます
このフックでは、状態変化を行うような処理は推奨されていません。
なぜならばそれが原因で無限ループに入ってしまう可能性があるからです。
updatedもmounted同様、子コンポーネントを全て再描画することを保証はしていないので、
mounted同様$nextTickを使うことを推奨されています。
また、updatedはSSRの場合は使えないので注意が必要です

## インスタンスの削除時
インスタンスの削除**$destroy()**が呼ばれた時にこの前後でフックを実行することができます。
### beforeDestroy
$destroy()が呼ばれた後、インスタンスが削除される前に実行されます
また、beforeDestroyはSSRの場合は使えないので注意が必要です

### destoryed
**$destroy()**が呼ばれた後、インスタンスが削除された後に実行されます
また、destoryedはSSRの場合は使えないので注意が必要です

## エラー時
### errorCaptured
`このフックはversion2.5.0以降で使用することができます`
このフックは、任意の子孫コンポーネントからのエラーが捕捉された時に、呼び出されます。
フックは、エラー、エラーをトリガーするコンポーネントのインスタンス、エラーが捕捉されたかどうかのメッセージを受け取ることができます。
また、エラー伝播を防ぐ為に、falseにすることで任意の箇所以降に広まらないようにすることも可能です

# 最後に
これらのタイミングを理解することで「なんで期待通りに動かないの！」と言うようなことが減っていくと思います！！
これであなたもVueのライフサイクルを完全に理解しましたね笑
セキュリティとリスクマネジメント

Webに限らないのですが、セキュリティの考え方として、「リスクマネジメント」が重要となってきますので、軽く解説しておきます。

## ノーリスク=何もできない

まず大前提として、あらゆる行動・選択には、リスクが付随します。極端な話、「日本に住んでいる」時点で、「地震や台風の襲来を食らうリスク」は一定程度存在しているわけです。

Webサービスを運営する上でも、リスクをゼロにするには「何も運営しない」ことしか手段はありません。ということで、存在するリスクとどのように向き合うかという**リスクマネジメント**が重要となります。

## リスクアセスメント

孫子の兵法でも「敵を知り己を知れば百戦殆うからず」と言いますが、リスクと向き合うに当たっても、どのようなリスクがどの程度あるのかという分析、評価を行うリスクアセスメントが必要となります。あるリスク要因に対して、

* （偶発的な事象の場合）それはどの程度の頻度で起きるものなのか
* （脆弱性などの場合）攻撃の容易性はどの程度なのか（リモート攻撃～マシンへの物理的アクセスが必要など）
* 提供するサービスにどのような影響が出るのか
 * 可用性への影響（速度低下、サービス停止など）
 * データの完全性への影響（データ損失、情報漏えい等）
 * 金銭的な影響（帯域消費による費用増加、アカウント不正利用による金銭被害など）
 * ビジネスへの影響（信頼低下など）

といった感じで、リスクを見積もっていきます。なお、上のリストはWebシステムを前提としています。

## リスクへの対応法

リスク要因とリスクの度合いを検討すれば、あとはどのように対応するかです。

### リスクの回避

リスクに対して得られるメリットが見合わない場合は、全く別の手段に切り替える、あるいは行動自体を取りやめることで、不必要にリスクを負うことを避けることができます。たとえば、「赤字でほとんど放置状態のようなサイトがあったけれど、サーバソフトウェアもサポート切れとなるので、それを機にサービス自体を終了することにした」などが考えられます。

### リスクの移転

金銭的、物質的なリスクに対しては、保険など契約を使うことで、他者にリスクを移転させることができます。保険以外の例としては、「自社で仮想通貨決済のシステムを開発すると、開発コストに加えてバグなどのリスク、価格変動のリスクがあるので、外部サービスと契約して日本円で入金してもらう」というような、外部システムの利用なども考えられます。

ただ、お金で買えないような、生命・名誉などに関するリスクについては、契約で移転することも難しいです。

### リスクの軽減

技術的に対応する部分はここがいちばん多いかと思いますが、考えられるリスク要因に対して、それを軽減させる方策を取る、という手段もあります。

* サーバが落ちるリスクに対応するために、複数台のサーバに分散させる
* データ消失のリスクに備えて、バックアップを取る
* パスワード漏洩のリスクを軽減するため、不可逆なハッシュ化を行って保存する
* Botによる不正投稿のリスクを軽減するために、CAPTCHAなどの認証を取り入れる

### リスクの保有

対策が経済的に引き合わないリスクについては、承知でそのまま運用するという手段もあります。たとえば、「地球に10km級の隕石が落ちてきて、大量絶滅を起こすような大変動に入るリスク」に対しては、現代の科学技術で対応可能かどうかも疑わしいです。

また、逆に「サーバがトラブルで止まる」ような日常的なリスクについても、「情報提供程度なので多少止まっても大損害に結びつくわけではない」ようなWebシステムであれば、それを承知で安いレンタルサーバで済ませる、というような選択ももちろんありです。

とはいえ、「リスクの保有」も、**リスクアセスメントした上で**というのが大前提です。俗に「サイバーノーガード戦法」と呼ばれるような、「どんなリスクもあるのかも考えずに放置する」という方法論とは全く別物です。
Androidでテザリングができなかったとき

### 結論だけ
adbコマンドで端末のテザリング設定を有効にする
`adb shell settings put global tether_dun_required 0`

---
先日買った Xiaomi Mi A2のテザリングを試したとき、なぜかPCからネットが繋がらなくて困ってた。

### 症状
1. スマホはネットに繋がる (Simは有効)
2. スマホの WiFi通信は無効化 (モバイルデータのみ有効)
3. PCからAndroidに接続はできている
4. **PCからネットに繋がらない**
  - WiFiアクセスポイント、Bluetoothテザリングともに繋がらない

### 対応
ググってみたらどうやらAndroid端末のテザリング設定が無効化されている可能性が指摘された。

adbコマンドで端末のテザリング設定を有効にしたら、PCからネットに繋げることができた。
`adb shell settings put global tether_dun_required 0`

---
特にルート化などは不要で、adbコマンドが使える環境であればすぐに対応可能です。


---
### 追記
Android 11にアップデートした際にテザリングができなくなったとき、上記のコマンドでは改善できなかった。

APN設定のAPNタイプに `dun` 設定を追加 (`,dun`文字を追記)することで改善できた。
RailsのAjax通信で任意のオブジェクトを出力する

##はじめに
Ajaxとう単語をずっとかっこいいと思っていましたが、一度も使ったことがなかったので、実際に使ってみました。
ここでは、Railsでの実装となります。

Scaffoldを使って簡単に実装していきますので、暖かく見守ってください。

##今回作るもの
今回作るものはいたってシンプルで、リンクをクリックすると既存のデータをAjaxで取り出すというもの。

![ajax_test.gif](https://qiita-image-store.s3.amazonaws.com/0/242611/c7728e71-5061-9c38-ba89-0e2a20a5f67c.gif)


##jQueryを導入

layoutファイルがあるので、headの中にscriptタグを書きます。
今回はCDNから引っ張ってきました。


```app/views/layouts/application.html.erb 

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
```


##とりあえず動くアプリを作成
Scaffoldでユーザーリストが表示されるアプリを作ります。

```
rails g ajax_test
cd ajax_test
```

```
rails g scaffold user name:string
rails db:migrate
```


##データを入れる

```db/seeds.rb 
(1..10).each do |i|
  User.create(name: "ユーザー#{i}")
end
```

データを流し込んで、しっかりデータが入っていればOKです!

```
rails db:seed
rails c
> User.count
=> 10
```

##controller

```app/controllers/users_controller.rb 
def ajax_test
  @user = User.all
  render json: @user
end
```

##root

```config/routes.rb
Rails.application.routes.draw do
  resources :users
  get "ajax_test", to: "users#ajax_test"
end
```

この時点で
`http://localhost:3000/ajax_test`にアクセスしてみてください。
<img width="1390" alt="localhost_3000_ajax_test.png" src="https://qiita-image-store.s3.amazonaws.com/0/242611/e3a2ad5a-910d-f7e6-e3cf-d49d5ad4327d.png">
すると、こんな感じにjsonデータで返ってきてるのがわかると思います。
今回はこれをviewで良い感じに出力できるようにします。

##view

`remote: true`をつけることで、Ajax通信してくれるようになります。

```app/views/users/index.html.erb
<h1>AjaxTest</h1>
<%= link_to "全てのuserを表示", ajax_test_path, {id: "ajax_test", remote: true} %>

<table id="user"></table>
```


##jsファイルを作る

```app/assets/javascripts/ajax_test.js.coffee
$ ->
  $("#ajax_test").click ->
    $.ajax
      url: '/ajax_test'
      type: 'get'  #get,postの指定
      dataType: 'json' #レスポンスのデータタイプ指定
      async: true #非同期通信フラグ
    .done (response) ->
      #処理が成功した時の処理
      $("#user").append("<tr><th>名前</th></tr>")
      for i in [0..response.length]
        $("#user").append("<tr><td>" + response[i].name + "</td></tr>")
    .fail (response) ->
      #処理が失敗した時の処理
      alert 'fail'

```

処理の流れとしては、
1. ajax_testというidをクリックすると、イベントが呼び出される　
2. `url: '/ajax_test'`で、ajax_testにアクセスするとレスポンスとしてjsonデータが返ってくる
3. 通信に成功(done)すると、指定したidに要素 + jsonデータを出力
(失敗したらアラート)

という感じでしょうか。

これで`http://localhost:3000/users`にアクセスし、リンクをクリックしてみてると、リロードされずに保存された全ユーザーが表示されたかと思います。

##まとめ
Ajaxを使うことで、いちいちリロードを待たなくて済むからユーザービリティーが上がるし、すごいなと実感。
(今回の例では逆に使いにくくしてますが)

今後も勉強していきます。
Androidノッチ端末でのキーボード高さ計算に関して

## はじめに

キーボードの真上にViewを描画する際、キーボードの高さ計算を行うことがあると思いますが、
ノッチ端末で高さの取れ方が変わっていたので、記事に残しておきます。

## 従来のコード

従来の方法では、キーボードの高さを以下のように取得していました。
**※フルスクリーン画面でのみTopを考慮しなくても動きます**

```kotlin
    // CustomView
    val customViewAboveKeyboard: View

    // キーボードの高さが変わった時に検知し、Viewの位置を調整する
    viewTreeObserver.addOnGlobalLayoutListener {
        val visibleHeight = getWindowVisibleDisplayHeight()
        val selfHeight = customViewAboveKeyboard.height
        customViewAboveKeyboard.y = (visibleHeight - selfHeight).toFloat()
    }

    fun getWindowVisibleDisplayHeight(): Int {
        val rect = Rect()
        val view = activity.window.decorView
        view.getWindowVisibleDisplayFrame(rect)
        return rect.bottom
    }
```

しかしながら、上記の通りでは、ノッチの端末において高さが下にずれてしまいました。

これは、`getWindowVisibleDisplayFrame()`関数で取得できる範囲がノッチバーの影響を受けて、`rect.top`の値にノッチの高さが追加されるためです。
**フルスクリーンの場合は、今までナビゲーションバーがなかったところに、ノッチバー分の高さが追加されるので、その分ずれます**

なので、以下のようにtopの座標を考慮すると、正常に動くようになります。

## 変更後のコード

```kotlin
    fun getWindowVisibleDisplayHeight(): Int {
        val rect = Rect()
        val view = activity.window.decorView
        view.getWindowVisibleDisplayFrame(rect)
        return rect.height() // ★ここでtopの座標も考慮し、height()を使う
    }
```

## 最後に

余談ですが、キーボード上にViewを配置する方法としては、高さ計算をせずに`android:windowSoftInputMode="adjustResize"`等を使ってViewの下端を上にずらしてしまう方法で実装することもできるかと思います。（[こちらなど参考になります](https://stackoverflow.com/questions/6220218/how-can-i-position-a-layout-right-above-the-android-on-screen-keyboard)）

自身の担当するアプリケーションでは、View階層が複雑であったため、今回のような実装方法を用いております。
もっとうまい方法をご存知の方はご教授いただけますと助かります。

以上です。

## 追記

少し気になって検証を行った結果、元々フルスクリーンでない画面で実装する場合にはtopを考慮に入れないと位置がずれることがわかりました。
自分の担当するアプリケーションでは、フルスクリーンの画面でしか実装していなかったので、気づかなかったです、、、すいません。

いずれにせよ、キーボードの高さ計算等する場合には、ナビゲーションバーやノッチの高さに注意しながら実装する必要がありました。気をつけましょう。

尚、本格的にノッチバーの切り抜きに対応するためには、Themeに`LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES`などを適用する必要があるみたいです。

* [Support display cutouts | Android Developers](https://developer.android.com/guide/topics/display-cutout/)
* [Making Notch-Friendly Apps For Android…](https://code.luasoftware.com/tutorials/android/move-layout-when-keyboard-shown/)
後日、こちらも検証できたら、まとめてみようと思います。
FirstVRで遊ぶ 指の形をキャリブレーションする

[前回](https://qiita.com/toRisouP/items/1831e9918d24a9b47b24) の続きです。

# CalibrationSampleシーン

FirstVR SDKの中に、`CalibrationSample`というシーンが同梱されています。
このシーンを選択してビルドすることで、ジェスチャー（指の形状）を記憶させるモードになります。

※OutputViewerシーンと行き来する機能はデフォルトではないので、必要なら自前で実装が必要

![image.png](https://qiita-image-store.s3.amazonaws.com/0/47146/206b3c8f-eec3-71ed-3f1c-96eb7f9c15fe.png)

# 使い方

ビルドしてスマホに転送したら、起動してFirstVRと接続します。
**接続方法にはコツがあり、スマホのBluetoothアンテナ部分とFirstVRを密着させることで接続できます。**
(Galaxy S8の場合はちょうどFelicaのアイコンが書いてあるあたりにアンテナがある)


そしてアプリを起動すると、`Set Dummy` というボタンがあるので、とりあえず押します。
するとこのような画面になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/47146/1895acb3-d26d-7986-0184-3da45fbb61cb.png)

サンプルではジェスチャーを1つだけキャリブレーションして記憶させることができます。

## 操作方法

* `Set Target` : 認識させたいジェスチャーを記憶させる
* `Set NonTarget` : 認識させたいジェスチャー**ではない**ジェスチャーを記憶させる

例えば「パー」の形を覚えさせたい場合は、

1. 指をパーの形にしてから`Set Target`を押す（数秒間計測される）
2. 指の形をパー以外にしてから、`Set NonTarget`を押す（数秒間計測される）
3.  1.と2.を何度か繰り返し、パーの形のときのみ反応するまでキャリブレーションする


何度か繰り返すと、そこそこの精度で認識するようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/47146/1c8582eb-ec89-f364-e93e-c64738b62b83.png)

（ジェスチャーを認識しているときだけ緑になる）


# 所感

「チョキ」のような、指の曲げと伸びが混ざっているようなジェスチャーはやはり認識が難しいのか、判定が結構ブレます。
アプリを作るときは、わかりやすいジェスチャーを使ったほうが良さそう。
会社のWiFiにログインする時に***.localが見つからなかった

会社に、社内LANとは別のWiFiのネットワークがあってとても便利なのですが、
linux入れてるノートPCだとブラウザーでのログイン後に、認証サーバーの名前解決（***.local）が出来なくて
タイムアウトしてしまいました。

/etc/nsswitch.confのhostsを見ると

hosts:  files mdns4_minimal [NOTFOUND=return] dns

となっていてこれで＊＊.localの名前解決できるらしいのですが、、
下記のように変更すると無事解決できました

hosts:  files  dns


あんまりよくわかんないな
ARCoreをUnityで開発（１.Unityを日本語環境でセットアップ）

# はじめに

ARCoreの開発にチャレンジしてみました。
自分がつまずいたことも含め、メモしておきます。

環境は以下のような感じです。

|カテゴリ| 内容 | 
|:--:   |:--|
|Dev OS | Windows 10 |
|ARCore | 1.5.0 |
|Device | Glaxy S8（Android 8.0.0）|

# Unityの日本語環境をインストール
試しにUnityをセットアップしたところ、
英語で苦労したので日本語化できると聞き、試してみました。

## Unity Hubのインストール

Unityを日本語化させるためには
Unity Hub経由でUnityをインストールすればいいらしい。

まず、Unity Hubをインストールしてみよう。
https://unity3d.com/jp/get-unity/download

インストールしてみたけど、あれ？
ネットワークが繋がってないとエラーが出ている・・・
そんなことはないのですが・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/24d5dfff-d211-bd9a-55da-6b3e5a2f2555.png)

この時のUnity Hub バージョンは 1.3.0。
調べてみると、Unity Hubの問題らしい。
https://forum.unity.com/threads/unity-hub-insists-im-not-connected-to-a-network.556696/

やり取りをみると、DNSの名前解決に関連した問題みたいです。
nslookupで確認したところ、
インストールされたDockerの仮想ネットワークアダプターのDNSを優先的に見ているようだ。
Dockerの仮想ネットワークアダプターを試しに無効化してみたところ、うまく動作できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/6614280a-daaf-7ac7-ffcc-80ad091b480c.png)

Unity Hubがネットワークにつながるようになったと思ったら
新バージョン 1.3.1がリリースされているとのメッセージが表示されました。
もしかしたら改善されているかもと思い早速インストールしてみて、無効化した設定を戻したら動いた！
かなりの時間を無駄にしてしまいました・・・・

![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/0165dedb-7fc3-feaa-c00a-b42ea4871452.png)

## Unity インストール

やっと本題にたどりつきました。
Unity Hubで、「Installs」をクリック、「Offical Releases」を選び、
今回は「2018.2.17f1」をDownloadボタンを押します。
  
Add components to your installが表示されたら、下へスクロール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/ad35e8b0-c1eb-e666-5c8c-7557c54a181e.png)

「Android Build Support」を追加選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/2114d618-f226-e642-5078-5d21dc8c3a45.png)

Language Packでは「日本語」も追加選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/e1309da4-d418-440a-1e91-46eff632e607.png)

あとは、インストールが終わるまでしばらく待ちます。

## Unity の環境を日本語に切替

インストールが終わったら、なにか一つプロジェクトを新規作成しましょう。
「Edit」から、「Preference」を開くと「Language」のメニューから日本語を選択して完成です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/55a148d6-1d4b-9447-796d-e193d019434c.png)

こんな感じになりました。
日本語にするとやや違和感を感じますが、これでいろいろ試してみようと思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/120824/ece3741e-c901-6129-8e23-9250aa849df1.png)
MySQLの "The server quit without updating PID file" エラーを対処する

# はじめに

MySQL起動時に
The server quit without updating PID file(/usr/local/var/mysql/[PC名].local.pid)
というエラーで起動失敗してどうしようもなくなったのでメモ。

環境はMacOSのHomebrewでMySQL5.7です。

# エラー内容

```
$ mysql.server start
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/[PC名].local.pid).
```
上記エラーが発生する。
sudoでも変わらず。

MySQL再起動を試してみる。

```
$ mysql.server restart
 ERROR! MySQL server PID file could not be found!
Starting MySQL
. ERROR! The server quit without updating PID file (/usr/local/var/mysql/[PC名].local.pid).
```
PIDファイルが無いらしい。

### 失敗1
[MySQL起動できなくなった　The server quit without updating PID file](
https://qiita.com/yuki0208/items/1d5554d98e9ec76084bd)　
を参考にPIDファイルを作成

```
$ touch /usr/local/var/mysql/[PC名].local.pid
```
エラー変わらず。

### 失敗2

[mysql起動で「The server quit without updating PID file」](https://qiita.com/mogetarou/items/e34ca51d3756d55d7800) 
を参考にmysqlディレクトリ下の権限を変更する

```
$ touch /usr/local/var/mysql/[PC名].local.pid
$ sudo chown -R _mysql:_mysql /usr/local/var/mysql
```
エラー変わらず。

### 失敗3

["Starting MySQL . ERROR! The server quit without updating PID file (/usr/local/var/mysql/**.local.pid)." エラーの対処](http://tech-outlines.hateblo.jp/entry/2015/03/24/180940) 
を参考に、 .err ファイルを削除する

```
$ touch /usr/local/var/mysql/[PC名].local.pid
$ sudo rm /usr/local/var/mysql/[PC名].local.err
```
エラー変わらず。

### 失敗4

["Starting MySQL . ERROR! The server quit without updating PID file (/usr/local/var/mysql/**.local.pid)." エラーの対処](http://tech-outlines.hateblo.jp/entry/2015/03/24/180940) 
を参考に、 プロセスをキルする

```
$ ps aux | grep "mysql"
knoth             1453   0.0  0.0  4258468    192 s001  R+    2:42PM   0:00.00 grep mysql
```
grepしか無い。

### 失敗5

PC再起動。変わらず。

### 解決策

[mysqlがどうしても起動しない](https://qiita.com/_natsu_no_yuki_/items/ae4c94187093e4ab3cdc) 
を参考に、もうどうしても起動しないので再インストールする（全部削除！）

```
$ sudo rm -rf /usr/local/var/mysql
$ brew uninstall mysql@5.7
$ brew install mysql@5.7
```

いざ起動!

```
$ mysql.server start
Starting MySQL
. SUCCESS! 
```

SUCCESS!!!

なんだったんだ…。
XAMPPをインストールした事があったからでしょうか…。
一応困った時はこの中のどれかで治るんじゃ無いでしょうか。

一先ず、無事MySQLを起動する事ができました。
【PowerShell】変な位置でカンマ区切りされたtxtに対して（区切られる前にあるべき）特定文字列の有無を確認する

## 環境
- PowerShell5.1

## 状況
- 意図しない位置でカンマ区切りされたtxtファイル達の中から、特定の文字列が含まれるファイルを列挙する
- 「意図しない位置でカンマ区切りされた」とは例えば以下のような場合を指す　"20","18/1","0/01：晴れ"
- 例として、"2018/10/01"または"good"の文字列を持つファイルを抽出する。

```powershell
# テストファイルを作成する
New-Item truecase1.txt -Value """20"",""18/1"",""0/01：晴れ"
New-Item truecase2.txt -Value """20"",""18/1"",""0/02：good"
New-Item falsecase1.txt -Value """20"",""18/1"",""0/02：bad"

# メインのロジック。
# カンマ区切りされた後の文字列の正規表現を作成し、ファイル名を出力
$td = "2018/10/01|good"
$ans = ""
$sep = "("","")*"
foreach ($c in $td.ToCharArray()) {$ans+=$c + $sep}
Select-String -Path "*.txt" -Pattern $ans | Select-Object filename | Get-Unique -AsString

# テストファイルを消去する
Remove-Item .\truecase1.txt
Remove-Item .\truecase2.txt
Remove-Item .\falsecase1.txt
```
yolo v3を使ってみたお話

#背景
最近、画像認識に興味を持ち始め色々調べていくうちに、学習済みモデルというものが結構手軽に利用できることを知る。大多数の人にとっては、初歩的すぎて役に立たないかもしれないが、自分の備忘録と文章を書く訓練として、また自分のように本当に初歩の初歩の段階にいる方向けにとりあえず書いていく。ちなみに、内容としてはほとんど[yolo公式](https://pjreddie.com/darknet/yolo/)をなぞっただけである。

#今回のゴール
yolov3を使い、画像から物体検出させる。

#やってみた
まずはgit cloneコマンドで向こうのリポジトリを丸々もらう。するとカレントディレクトリにdarknetリポジトリができる。

```
git clone https://github.com/pjreddie/darknet
cd darknet
make
```
公式には「Easy!」って書いてある。

あとは重みファイルをもってきて、実行するだけ

```
wget https://pjreddie.com/media/files/yolov3.weights
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
```

のはずだったが、自分の環境(mac)にwgetコマンドをいれていなかったのでインストールして、

```
brew install wget
```
リトライ！

```
Loading weights from yolov3.weights...Done!
data/dog.jpg: Predicted in 25.730297 seconds.
bicycle: 99%
truck: 92%
dog: 100%
```
できた！
上のコマンドの通り、darknetフォルダ配下のdataフォルダ内のdog.jpgに対して判定を実行している。そのため、他の画像で試したい時はdata/dog.jpgの部分を変更する。
ちなみに自分のカスタマイズなしのmacPC環境(CPU)では結果の表示まで15秒ほどかかった。
[yolo公式](https://pjreddie.com/darknet/yolo/)にはv3以外にもいくつかバージョンがあり、上記と同様の手続きで使うことができそう。（未確認）
次はopenCVで画像に枠と判定結果を表示させるところまで書きたい。



【追記】
一応、openCVをインストールせずとも、darknetのフォルダ内にpredictions.jpgとして枠付きで結果を出力しているようだ。![predictions.jpg](https://qiita-image-store.s3.amazonaws.com/0/319131/a2777b6b-8078-d713-7f5d-d4ec4ca86554.jpeg)
PHPで使える！便利な関数たち！

昨今、コードを書くときに避けられない

ライブラリー（関数）の使用ですが、

どのライブラリーを使えば良いのかなかなか

決められないと思います。

そこで、今回はPHPで役に立つライブラリーをご紹介したいと思います！

#memory_get_peak_usage
PHP によって割り当てられたメモリの最大値を返します。

```php
echo memory_get_peak_usage();
echo memory_get_peak_usage(true);
```

```
225472
262144
```
このように、プロセス中のメモリのピーク値と
trueを指定することでそのときに割り当てられたメモリの量を
バイト単位で表示します。

#ポインタ関連の関数
###key(), next(), prev()

```php
$cities = array('Tokyo' => 'Tokyo', 'Osaka' => 'Osaka', 'Aichi' => 'Nagoya');

echo key($cities).PHP_EOL;

next($cities);

echo key($cities).PHP_EOL;

prev($cities);

echo key($cities).PHP_EOL;
```

```
Tokyo
Osaka
Tokyo
```
key()で現在ポインターが指している配列のキーを取得します。
next()で現在ポインターが指しているキーを一つ進めます。
prev()で現在ポインターが指しているキーを一つ戻します。

###array_unique()
```php
$data = [100, 100, 200, 300, 400];

print_r(array_unique($data));
```

```
Array
(
    [0] => 100
    [2] => 200
    [3] => 300
    [4] => 400
)
```
array_unique()で配列から重複した値を削除することができます。

###array_filter()
```php
function Filter($var)
{
    return $var > 200;
}

$value_array = [100, 200, 300, 400, 500];
$value = array_filter($value_array, 'Filter');
print_r($value);
```

```
Array
(
    [2] => 300
    [3] => 400
    [4] => 500
)
```
array_filter()で特定の配列をフィルタリングすることができます。
フィルタリングの内容は第二引数に定義した関数の元、行われます。

###array_map()
```php
function Add($n)
{
    return $n - 100;
}

$value_array = [100, 200, 300, 400, 500];

$value = array_map('Add', $value_array);

print_r($value);
```

```
Array
(
    [0] => 0
    [1] => 100
    [2] => 200
    [3] => 300
    [4] => 400
)
```
array_mapで全ての配列要素に同一の処理を行うことができます。
第一引数に処理を行う関数を指定し、第二引数に処理をしたい配列を指定します。

###array_push()
```php
$value_array = [100, 200, 300, 400, 500];

array_push($value_array, 600, 700);

print_r($value_array);
```

```
Array
(
    [0] => 100
    [1] => 200
    [2] => 300
    [3] => 400
    [4] => 500
    [5] => 600
    [6] => 700
)
```
array_pushで配列の最後の要素に値を追加することができます。
第一引数に配列を指定し、第二引数に追加したい値を指定します。

###unset()
```php
$value_array = [100, 200, 300, 400, 500];

unset($value_array[1]);

print_r($value_array);
```

```
Array
(
    [0] => 100
    [2] => 300
    [3] => 400
    [4] => 500
)
```
unsetは指定した配列の要素を削除できます。

#まとめ
PHPに限らず昨今のプログラミング言語では、
ライブラリー（関数）を駆使することがどのプログラマーにも
求められます。コードの可読性を高める為にも便利な関数は
どしどし使っていきたいですね！




#参考文献
[PHPerなら知っておいて損はない10の関数](http://blog.asial.co.jp/779)
[【初心者必見！】PHPのよく使う配列操作の関数まとめ(array)](https://www.sejuku.net/blog/25512)