OmniAICreator/Qiita-1.07M huggingface dataset:
docker + nginx + php-fpm で wordpress のリソース取得で 403 が返ってくる話

docker で wordpress 立てたいと思い、nginx + php-fpm の構成でやってみたら、全くスタイルが当たってなくてビビった。
リソース（.css、.js）の取得で 403 エラーが返ってきてる。

![スクリーンショット 2019-04-12 9.27.42.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365593/68002900-a30a-870a-bde0-60f119ff9583.jpeg)

PHP は動いているのにリソースが取れないってどういうこと？
Webは得意分野じゃないから、パーミッションの問題、ユーザーの問題（コンテナ間のユーザーの相違）を疑っていろいろ試してみたけど解決せず。

1ヶ月くらい経って改めて試してみたら、めちゃくちゃ初歩的なミスだったんだけど、docker 初心者は意外と同じミスしそうな気がしたので、メモ。

結論からいうと、docker-compose.yml で nginx からも php からも wp ルートをマウントしてあげないとダメだよって話。

ホスト側の app ディレクトリが wp ルートの場合。

＜悪い例＞

```yml
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./web/nginx/default.conf:/etc/nginx/conf.d/default.conf

  app:
    image: php:7-fpm-alpine
    volumes:
      - ./app:/var/www/html
    depends_on:
      - db

  ...
```

＜上手くいく例＞

```yml
version: '3'
services:
  web:
    image: nginx:alpine
    ports:
      - "8000:80"
    depends_on:
      - app
    volumes:
      - ./web/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./app:/var/www/html # ←追加

  app:
    image: php:7-fpm-alpine
    volumes:
      - ./app:/var/www/html
    depends_on:
      - db

  ...
```

とあるサイトで解説されていたのを参考に最初の設定にしてたんだけど、まんまとハマった。
※他にも違う解決方法があるんだろう。

これで、無事リソースが取得でき、スタイルが当たるようになりました。

![スクリーンショット 2019-04-12 9.44.13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365593/90f9eaf9-2923-b196-1006-c88fed795670.jpeg)

終わり。
【Qt】QSignalMapperは まいそうされます。

## おことわり

この記事は次のブログからの転載です。

- [【Qt】QSignalMapperは まいそうされます。 - カンテラの光の下で](https://dnaga392.hatenablog.com/entry/2019/04/12/011820)

## 概要

[![Image from Gyazo](https://i.gyazo.com/a484c53b0d66dcda81155e9f6b1f5bfc.gif)](https://gyazo.com/a484c53b0d66dcda81155e9f6b1f5bfc)

画像のような複数のUIの操作に応じて一つのUIを更新する処理は __QSignalMapper__ が担ってきました。

しかし Qt5 では QSignalMapper は非推奨とされ、 __ラムダ式__ への置き換えが推奨されます。

そこで、実際にどのように置き換えていくかをここに記録します。

## 従来の QSignalMapper を用いた手法

```cpp
    // legacy style signal mapping
    mapper = new QSignalMapper(this);
    QVector<QPushButton *> foobarButtons({
        ui.fooButton,
        ui.barButton,
        ui.foobarButton,
    });
    for (auto const &button : foobarButtons)
    {
        connect(button, SIGNAL(clicked()), mapper, SLOT(map()));
        mapper->setMapping(button, button->text());
    }
    connect(mapper, SIGNAL(mapped(QString)), this, SLOT(foobarLabelUpdate(QString)));
```

処理の流れは次の通りです：

1. QSignalMapper を作成する。
1. sender（`button`） から QSignalMapper へ connect をする。
1. `QSignalMapper::map()` が実行されるとき、 QSignalMapper から送出する内容を登録する。
1. `QSignalMapper::mappped()` から送出される内容を受け取る slot （`foobarLabelUpdate`） へ connect する。

前提として必要なことは2つ、 __QSignalMapper のインスタンス__ と __該当の操作に対応できるSlot__ そして、くじけない心です。

## ラムダ式を用いた手法

```cpp
    // qt5 style signal mapping
    QVector<QPushButton *> fizzbuzzButtons({
        ui.fizzButton,
        ui.buzzButton,
        ui.fizzbuzzButton,
    });
    for (auto const &button : fizzbuzzButtons)
    {
        auto const &text = button->text();
        connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(text); });
    }
```

処理の流れは次の通りです：

1. sender（`button`） からラムダ式へ connect をする。

もう少し言うと、`[=]` ではじまるラムダ式なので送出していた内容を変数`text`に格納するという準備をしています。

これは比較のためにQStringで揃えているだけですので、コメントで指摘いただきましたが、buttonそのものを渡すことでより簡潔に書けます。

```cpp
    for (auto const &button : fizzbuzzButtons)
    {
        connect(button, &QPushButton::clicked, [=] { ui.fizzbuzzLabel->setText(button->text()); });
    }
```

非常にシンプルになりました。
これなら気軽に書いていけますね。

## 参考資料

- [QSignalMapper Class | Qt Core 5.12.2](https://doc.qt.io/qt-5/qsignalmapper.html)
- [QObject Class | Qt Core 5.12.2](https://doc.qt.io/qt-5/qobject.html#connect-4)
- [ラムダ式 - cpprefjp C++日本語リファレンス](https://cpprefjp.github.io/lang/cpp11/lambda_expressions.html)
- [GitHub - dnaga392/signalmap](https://github.com/dnaga392/signalmap) : 上記のコードは`mappingwidget.cpp`にあります。
EC2を日本時間にする

# 現在時刻確認

```bash
$ date
Fri Apr 12 00:00:00 UTC 2019
```

## clockファイル修正

```bash
$ sudo vi /etc/sysconfig/clock
```

```bash
# ZONE="UTC"
ZONE="Japan"
```

## タイムゾーン情報にシンボリックリンクを貼る

```bash
$ sudo ln -sf /usr/share/zoneinfo/Japan /etc/localtime
```

## リブート(しなくてもOKだった)

```bash
$ sudo reboot
```

# 現在時刻確認

```bash
$ date
Fri Apr 12 09:00:00 JST 2019
```
へっ！きたねぇデプロイだ【AWS Step Functions編】

皆さん、StepFunctionsしてますか？
複数のLambdaを組み合わせてステートマシンを作り、それが順番に実行されていくあのピタゴラスイッチみたいな面白さ。
私もよく使っています。現在は多くのサービスと連携できるようになり、より簡潔にステートマシンが書けるようになって嬉しいです。

# どうやってデプロイしてますか？
さて、そのStepFunctions、どうやってデプロイしてますか？StepFunctionsは単体ではなく、Lambdaを組み合わせて使います。
となると、StepFunctionsのデプロイとは、

- 処理を行うLambdaのデプロイ
- 処理の流れを定義するステートマシンのデプロイ

となります。場合によってはIAMロール周りも必要です。どうやってLambdaやステートマシンをデプロイしてますか？

## 直弄り
Lambdaやステートマシンはそれぞれコンソールから直接編集が可能ですので、やっている人も多いです。
しかしこの場合、デプロイ＝保存になるので、もし戻したくなった場合は戻せません。非常にきたねぇデプロイです。

## コピペデプロイ
はい。出ました。きたねぇデプロイ代表「コピペデプロイ」です。
ローカルにあるコードをコピーして、AWSのLambdaコンソールを開いてペーストするやつです。ローカルでソース管理しているだけ直弄りよりマシですが、まだまだ汚いです。コミットしたタイミングならまだしも、編集中にコピペして保存した場合、いつのタイミングの物がLambdaに適用されているのか分からなくなります。

## 属人的デプロイ
はい、これもきたねぇデプロイですね。特定の人しかデプロイできない！これは非常に問題です。リリース当日にその人が休んだら？電車が止まって来れなくなったら？考えただけで背筋がゾワゾワしますね。

# きれいなデプロイを目指して
では、きれいなデプロイとは何でしょう。いろいろあると思います。

- developブランチにマージされたら検証環境のLambdaにデプロイ
- masterブランチにマージされたら本番環境のLambdaにデプロイ

特にStep Functionsの場合、複数のLambdaが同時に最新になっている必要があります。これが単一Lambdaと違って難しい所で、複数のLambdaと同調するのでデプロイ抜けがあると動かなくなります。
「コピペデプロイ」や「直弄り」だと、この問題が多発します。 **このLambda更新したっけ？** とか、 **あ、こっちのLambda更新してなかった！** とかで失敗し、そのたびにLambdaコンソールを開いて編集・・・非常によくないです。

その問題を解決する為、私は「serverless framework」を使うようになりました。

# Serverless Frameworkとは？
複数のAWSリソースを一撃でデプロイしてくれます。はい、この一撃というのがポイントで、コマンド一つで

- Lambda
- IAM
- StepFunctions

を一撃でデプロイしてくれます。StepFunctionsの場合はプラグインを入れる必要があります。Lambdaを新規にデプロイする場合はIAMも設定する必要があるので、一撃でデプロイできるのは非常に便利です。

## 設定のポイント

### Cloud Watch Logsの保存期間を設定しておこう。

```serverless.yml
provider:
  name: aws
  runtime: python3.7
  logRetentionInDays: 30
```

`logRetentionInDays`という所が設定箇所です。これを設定しないとずっとLogが残り続けて課金額が増えていきます。値は環境によって調整しましょう。

### Lambdaの世代管理を設定しておこう。

Serverless FrameworkでデプロイしたLambdaは、問題発生時のロールバック用に過去の世代が保存されるのですが、これがどんどん溜まっていきます。そうなるとコード保存容量が上限となり、デプロイできなくなるので、何世代まで残すかの設定をしておきましょう。

```serverless.yml
plugins:
  - serverless-step-functions
  - serverless-prune-plugin

custom:
  prune:
    automatic: true
    number: 3
```

`serverless-prune-plugin`というプラグインをインストールし、`custom`に設定を記述します。`number`とは世代を表し、この場合だと3世代まで残す設定になっています。

## きたねぇデプロイから、きれいなデプロイへ
Serverless Frameworkを使う事で何が解決できるのか？

コマンドによりデプロイが開始されるので、Lambdaコンソールを開く必要がなくなります。「直弄り」や「コピペデプロイ」がなくなります。
Serverless Framework環境を整えれば、ソースコードをcloneしてコマンド実行するだけで誰でもデプロイできるようになります。

私もServerless Frameworkを使う前は前に挙げたようなドロドロのきったねぇデプロイをしてました。何が問題かというと、コードの更新漏れで動かないとかそんなもので時間を取られるようになったんですね。そこじゃなくてコードを書くのに時間を使うべき。あとこういう作業は繰り返しなので絶対に自動化できる！そう考えて調べた結果、「Serverless Framework」に出会いました。

きたねぇデプロイは皆さんからコードを書く時間をどんどん奪っていきます。コードを書くのが好きなら、こんなきたねぇデプロイを駆逐して、楽しいコーディングライフを送りましょう！
初心者Pythonistの日記 Day2

さて、Day2です。

ちなみに、Day2といっても、いつも二日連続するわけじゃないですので悪しからず。

https://a2c.bitbucket.io/flask/index.html
昨日、これをやりかけたわけですが、ちょっとそもそもPythonのPの字も知らなかったんで、関数がそもそも知らない。
ということで、

ちょっと以前から、憧れてた、こう、左側にコード書いて、右側にそのアウトプットがでるGUIのような開発環境、コード学習環境のやつ、やってみたかったんですよね。
https://prog-8.com/dashboard
で、プロゲートのこれのPythonをしてみました。10分ほど・・・

そしたら、簡単すぎて、ちょっと学習スピード遅くなるな、、と感じで、飽きたので辞めました。

で、今日はこちらをざっと読むことにしました。
今日は外のミーティングで、移動時間もあったんで、
https://docs.python.org/ja/3/tutorial/index.html
ざっと、8章まで読了。

__main__ 
の、__が2つ_がるのって、なんなんですかね？　面白い特徴
あと、半角スペースを4つあける、という記述ルールの、PEP8とか。
4つって面白い。
と、変なところで、関心しました。

本日1時間
合計3時間

昨日、記事1つ目で、コメントいただいたようで、ありがとうございます。いいねもありがとうございます。
あと、アイコンももらっちゃいましたので、更新します。アイコン、ありがとうございます。

>Qiitaで勉強した方が早いのでは？
https://qiita.com/search?utf8=%E2%9C%93&sort=&q=tag%3Apython+flask+入門

こんなコメントもらったので、Day3は、このリンクを見てみたいと思います！ありがとうございます
Amazon S3 Select利用 (AWS SDK for PHP)

#概要
S3バケット内に保存したオブジェクトに対して簡単なSQL文でクエリができるサービス、[S3 Select](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/s3-glacier-select-sql-reference-select.html)を利用する機会がありまして、その内容を軽く共有しようと思います。今回に初めて利用してみましたが、とても簡単で便利だったので、色んなところで利用できると感激しました。

#背景
ウェブページユーザーが操作した内容をロギングする必要がありました。そして、操作ログを閲覧、様々な検索が可能なページも用意する必要がありました。
このような仕様で、まず、検索するログを入れて置くAWSサービスを選ぶことになりました。DynamoDB, RDS、Kinesis Firehose＆Elasticsearch、CloudWatch Logs Insights、などなどの方法で悩んでましたが、結局は仕様と費用などのため、ログを貯めておくストレージをS3にして、Athenaより安いS3 Selectを利用することになりました。
 ※ スキャンデータ1GB当たり(東京) S3 Selectは0.005USD、Athenaは0.00225USD

#注意
 - Athenaと違って複数のオブジェクトでクエリはできません。
 - 対象オブジェクトはCSV形式とJSON形式だけ可能です。
 - SQLはSELECT,FROM,WHERE,LIMITしかできません。
 - サブクエリや結合はサポートされていません。
 - SQL式の最大長は256KBです。
 - 結果のレコードの最大長は1MBです。
 - など

#利用
PHP版のAWS SDKでささっと利用してみます。
※ https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-s3-2006-03-01.html#selectobjectcontent
※ https://github.com/aws/aws-sdk-php/pull/1627

## サンプルjsonデータを用意してテスト用のS3バケットに入れる

```json
{id:1,name:"lee",stauts:3,created:"2018-02-2819:38:54"}
{id:2,name:"hoge",stauts:3,created:"2018-03-2819:38:54"}
{id:3,name:"lee",stauts:1,created:"2018-04-2819:38:54"}
{id:4,name:"hoge",stauts:2,created:"2018-05-2819:38:54"}
{id:5,name:"lee",stauts:1,created:"2019-06-2819:38:54"}
{id:6,name:"hera",stauts:3,created:"2018-07-2819:38:54"}
```

```php
$s3 = \App::make('aws')->createClient('s3');

$result = $s3->selectObjectContent([
    'Bucket' => 'lee-dev',
    'Key' => 's3-select/test.json',
    'ExpressionType' => 'SQL',
    'Expression' => "SELECT * FROM S3Object S WHERE S.name = 'lee'",
    'InputSerialization' => [
        'JSON' => [
            'Type' => 'Lines',
        ],
    ],
    'OutputSerialization' => [
        'JSON' => [
            'RecordDelimiter' => '\n',
        ],
    ],
]);

foreach ($result['Payload'] as $event) {
    if (isset($event['Records'])) {
        echo (string) $event['Records']['Payload'] . PHP_EOL;
    }
}
```

```
{"id":1,"name":"lee","stauts":3,"created":"2018-02-2819:38:54"}
{"id":3,"name":"lee","stauts":1,"created":"2018-04-2819:38:54"}
{"id":5,"name":"lee","stauts":1,"created":"2019-06-2819:38:54"}
```
DashboardのテンプレートAdminLTEをElectronで動かす


# 概要
**Electron**でデスクトップアプリとしてDashboardを作ってみようと思います。Dashboardのテンプレートを探して**AdminLTE**が良さそうなのでこれをElectronで動かしてみました。

# 実行環境
- Windows10
- Node.js  v10.15.3

# AdminLTEのダウンロード
[AdminLTEのサイト](https://adminlte.io/)からAdminLTE 2.4.10をダウンロードして解凍します。

# Electronのインストール
解凍したAdminLTEのフォルダに移動して**electron**のインストール

```shell
AdminLTE-2.4.10> npm install electron --save-dev
```

# package.jsonの変更

**main**項目の変更、**script**項目の追加

```json:package.json
  "main": "main.js",
  "scripts": {
    "start": "./node_modules/.bin/electron ."
  },
```
# main.jsの追加

**electron**のmainのテンプレートである**main.js**を追加します。コードのコメントは全て削除しました。

```javascript:main.js

const { app, BrowserWindow } = require('electron')

let mainWindow

function createWindow() {
  mainWindow = new BrowserWindow({show:false, backgroundColor: '#FFF', width: 800, height: 600, frame:true})

  mainWindow.loadFile('index.html')

  mainWindow.once('ready-to-show', () => { mainWindow.show() })
  mainWindow.on('closed', function () {
    mainWindow = null
  })
}

app.on('ready', createWindow)

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function () {
  if (mainWindow === null) {
    createWindow()
  }
})
```

# 実行、しかしエラーでした
次のコマンドで実行します

```shell
AdminLTE-2.4.10> npm start
```

しかし、`Sales`のグラフなど画面の一部が表示されませんでしたので、Developer Toolsで確認しますと次ようなエラーが確認できました。これは**jQuery**に関してエラーになっているようです。調べるとQIITAに「[ElectronでjQueryがundefinedになる](https://qiita.com/pirosikick/items/72d11a8578c5c3327069)」があり、[ElectronのFAQ](https://electronjs.org/docs/faq#i-can-not-use-jqueryrequirejsmeteorangularjs-in-electron)にもありました。
![adminlte1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/6c5db89d-934c-9203-614c-f5f8db378122.png)

# main.jsを修正して再度実行
今回は**new BrowserWindow**で`nodeIntegration: false`を追加しました。

```javascript
  mainWindow = new BrowserWindow({
    show: false, backgroundColor: '#FFF', width: 800, height: 600, frame: true,
    webPreferences: {
      nodeIntegration: false
    }
  })
```

再度実行

```shell
AdminLTE-2.4.10> npm start
```

今度はちゃんと表示されました。

![adminlte2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258007/c827f5d3-d4f6-35e6-5642-6cb2a2d1c0f6.png)

# 最後に
とりあえず、**jQuery**問題はありましたが簡単に動いてしまいました。今度は**Charts**と**Tables**のメニューのところをデータベースからデータを取ってきて表示してみようと思います。ただし、`nodeIntegration: false`としたので**Rendererプロセス**から**Node.js**のコードがそのままでは使えません。**preload**で**ipc**を使えるようにして**Mainプロセス**側でデータベースにアクセスしてデータを**ipc**経由で受け取るか、あるいはデータベースのドライバを**preload**で使えるようにしないといけないようです。
経営戦略 応用情報技術者試験 対策日記@21

##M&A
M&Aの手法
**TOB(公開買い付け)** あらかじめ株式の価格などを公開し、市場外で一括して買い付ける。上場企業を買収するときなど。
**LBO(Leveraged Buy Out)** 借入金を用いた買収方法
**MBO(Management Buy Out)** 子会社などにおいて、経営陣が株式を買い取って経営権を獲得する。

##分析手法
###プロダクトポートフォリオマネジメント
https://kigyotv.jp/news/ppm/
###SWOT分析
https://www.innovation.co.jp/urumo/swot/
###ファイブフォース分析
競合他社、新規参入社の脅威、代替製品の脅威、売り手の交渉力、買い手の交渉力
###製品・市場マトリクス
https://www.sbbit.jp/article/cont1/30111
###PEST
Political, Economical, Sociocultural, Technologicalのマクロ環境

##マーケティング
###4P
Product, Place, Price, Promotion
###3C
Customer, Company, Competitor
##RFM
Recency,Frequency, Monetary
###AIDMA
Attention, Interest, Desire, Memory, Action

##バランススコアカード
BSC(バランススコアカード)は企業の業績評価システム。財務、顧客、内部プロセス、学習と成功の4つの視点で評価する。KGIを決めて、それに決定的な影響を与えるCSFを決定する。 

##イノベーション
プロダクトイノベーション、プロセスイノベーション、インクリメンタルイノベーション、ラディカルイノベーション
Git超初心者~Gitを知ろう~

##  はじめに
はじめまして、初投稿です。
学習したことの備忘録置き場として投稿していきたいと思います。本日は、現在もっとも苦労している`Git`について。

最後の目標として、同じようにGit初心者のかたが見ても理解しやすいよう随時、修正と追加をしていきたいと思います。

## Git ってなに？
- もともと[Linuxカーネル](https://ja.wikipedia.org/wiki/Linux%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB開発用に作られた)開発用に作られたもの
- オープンソースの分散化[バージョン管理システム](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)の１つ
（バージョン管理とは、変更履歴の管理）

- 多くの開発者が利用している

＊書き換えたと言われてもどこがか分からない。
＊前のほうが良かった。
＊同じような名前のデータが複数できている。
　
こんな事態を解消してくれるのがGitです！

## Git を使うとこんな利点が
- 変更履歴を記録することができる
- 誰が、いつ、どこで、何のためにどこを変更したか管理できる
- 以前の状態に少ない作業で戻ることができる
- ソース内の[コメントアウト](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)#%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%A2%E3%82%A6%E3%83%88)が不要になり見やすい
- 余計なファイルを増やす必要がなくなる

最高ですね。
そして`GitHub`は、このgitの仕組みを利用して、世界中の人たちがプログラムコードなど保存できるWebサービスです。

## ３つのデータ領域
- 作業ディリクトリ
→ git 管理下で実際に作業をするディリクトリ


-  Git ディリクトリ
→`リポジトリ`のすべての変更履歴を保持する場所


- インデックス
→次回の`コミット`対象となるファイルを記録する場所


## 用語メモ
`ワーキングツリー`：作業をしているディレクトリ

`リポジトリ`：変更履歴を管理する場所（データの貯蔵庫）
- ローカルリポジトリ：自分のパソコン上のリポジトリ
- リモートリポジトリ：GitHubのリポジトリ(サーバに配置して複数人で共有できます)

`インデックス`：ワーキングツリーで編集をしてローカルリポジトリに保存する前に登録する場所。リポジトリへ追加する前にこの作業を挟まないといけません。

`コミット` ：編集したファイルをローカルリポジトリに記録すること（予約内容の実行）

`プッシュ`：ローカルリポジトリにあるものをリモートリポジトリに送ること。

`クローン`：リモートリポジトリの内容をそのままローカルリポジトリとして複製でき、自分の手元で作業ができます。変更履歴も複製されているので途中から参加した人にも有り難いですね。

`プル`：複数人で作業すると皆それぞれリモートリポジトリにプッシュします。他の人がプッシュした変更内容を自分のローカルリポジトリに更新する際に行う操作です。プルをすると、リモートリポジトリから最新の変更履歴が取り込まれます。

`ブランチ`：分岐して個別に作業ができるディレクトリ。他からの影響を受けないため同じリポジトリのなかで複数の変更を同時進行することができます。
jQueryで後から追加した要素にイベントを設定させる方法

jQueryを使っていて、あれ？、なぜイベントを設定したのに動作しないんだ？ と少し
ハマったことがあったので、アウトプットしたいと思います。

#前提
jquery-3.4.0.min.jsを読み込んで動作確認をしています。

#Example
単純に以下のように、ボタンを押すとp要素が追加されていく例を見ていきます。

```html:example.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>jQueryの練習</title>
</head>
<body>
    <p>jQueryの練習</p>
    <button>Add!</button>
    
    <script src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
    <script>
        $(function() {

            $('button').click(function() {
                // テキストが"add!!!"で"add"クラスを持つp要素をボタンの直前に追加する。
                var p = $('<p>').text('add!!!').addClass('add');
                $(this).before(p);
            });

            // 追加された"add"クラスを持つp要素をクリックすると削除される処理
            // 実はこの処理の書き方が問題あり！
            $('.add').click(function() {
                $(this).remove();
            });
                        
        });
    </script>
</body>
</html>
```

実はこのように書くと、追加された"add"クラスを持つp要素にイベントが設定されず、
うまいこと消えてくれない。。。

#onメソッドを使いましょう！

後から追加された要素にイベントを設定させたい場合は、onメソッドを使うことで解決できます！

```html:example.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>jQueryの練習</title>
</head>
<body>
    <p>jQueryの練習</p>
    <button>Add!</button>
    
    <script src="https://code.jquery.com/jquery-3.4.0.min.js"></script>
    <script>
        $(function() {

            $('button').click(function() {
                // テキストが"add!!!"で"add"クラスを持つp要素をボタンの直前に追加する。
                var p = $('<p>').text('add!!!').addClass('add');
                $(this).before(p);
            });

            // このように書いてあげれば、うまく動作します！
            // jQueryオブジェクトの中は、$('body')ではなく$(document)としてもokです。
            $('body').on('click', '.add' , function() {
                $(this).remove();
            });
                      
        });
    </script>
</body>
</html>
```

上記のように、

```
jQueryオブジェクト.on('イベントの種類', 'セレクタ' , function() {
});
```
とすれば、問題なく動作します。
かなり初歩的なことみたいです。

#参考

[ドットインストール](https://dotinstall.com/)
jQuery入門
\#15 onメソッドを使ってみよう
IBM Cloudに慣れるためにハンズオンしたメモ (LBとAZ)

### 背景
自分が真剣にクラウドと向き合ったのはAWS。ITアーキテクトとしてよく研究したし、実際に操作した時間も長く、技術認定もSA Professionalまでは取った。
しかし今月から業務としてIBM Cloud、特にIaaS部分を触る機会というか、それが必要な仕事となり、仮想サーバー周りを触ってみたので作業メモを残しておくことにした。

### 今回やったこと
- この前の投稿で作ったIBM Cloud上のWebサーバーとDBサーバー ([前回の投稿](https://qiita.com/Mino_Il1/items/fb3b76454bd651aa8adc,"前回の投稿"))
- 「ここまで作れば後は、Webサーバーの前にLoad Balancerをおいて、Webサーバーを複数台で構成しよう！」ということで、
１台目のイメージをとって、そこからそして２台目のWebサーバーを作成。

- 作成にあたっては、「１台目がTOK2だから、２台目はTOK４にしてみる。マルチゾーンなんだし別のAZで」と意気込んで作成。
- ２台目のサーバーができて、ロードバランサーも作って構成完了。
- 疎通テストとして、ロードバランサーのURLへHTTPアクセスし、なんとかWordpressは出るようになった。

### 遭遇した課題
- しかしロードバランサーのコンソールを見ると２台目のWEBサーバーのステータスはLB上でUnhealthy。繋がっていない。
- ２台目のWEBサーバーへはログインできた。しかしそこから、DBサーバーへ繋がらない。

### 解決
- しばし考え、解決。
- ここはIBM Cloudだった。TOK2とTOK4は別のプライベートVLANだから、デフォルトでは繋がらないのだった。
- で、VLAN SpanningをONにして無事解決。(参考： [VLAN Spannning]("https://qiita.com/testnin2/items/ba56070568221536fdfb","VLAN Spannning) )
- ロードバランサーからTOK２、TOK４にそれぞれ配置したWEBサーバーへの振分成功。TOK4からTOK2へのDBアクセスもOKに。

### 今後やること
今回は試しにということで、何気なくロードバランサーにローカルを使っていたことに改善の余地がありそう。
これだとロードバランサーが片方のゾーン（今回はTOK2)に配置されているので、
TOK2がダウンしているとWEBサーバーを複数のAZに配置している意味が半減してしまう。
グローバルロードバランサーを使えば解決しそうなので、今度試す。
GitHub - Pull Requestの内容確認 #5

### 簡単な修正の確認
送られたきたPull Requestのコードレビューを行う
確認でき大丈夫だったら、
「Merge pull request」ボタンを押して、完了

### Pull Requestの内容を手元で確認する

```terminal
// 1. 確認する前に自分のローカルリポジトリをcloneやfetchで最新にする
// 2. Pull Request送信側のリモートリポジトリを取得する
$git remote add {送信側ユーザ名} git@github.com:{送信側ユーザ名}/{ブランチ名}
$git fetch {送信側ユーザ名}

// 3. 確認用のブランチを作成して、マージする
$git checkout -b {ブランチ名}
$git merge {送信側ユーザ名}/work
```
[Swift] Handle unknown values using "@unknown default" がわかった件

`Xcode 10.2`がリリースされてから`Swift 5`に移行した方も多いと思います。
`enum`のcaseで分岐する`Switch文`を書いたとき、
以下のように`Handle unknown values using "@unknown default"`と
警告が`出る`ときと`出ない`ときがありました。
![SS2019-04-11-20.14.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/0b041488-864c-3e6f-f95a-20450b3c15b1.png)
この違いは何なのか調査しました。

**警告出る**
![SS2019-04-12-6.20.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/a2ce4b5a-90f0-c11a-c253-1f7eeae78379.png)
**警告出ない**
![SS 2019-04-12-6.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/dba7708c-d7d0-12dc-b5d5-a6ad3e1d6d4d.png)


##Frozen enumとnon-frozen enum
・`frozen enum`を使ったときは警告が出ない。
・`non-frozen enum`を使うと`@unknown default`を使いなさいと警告が出る。

`non-frozen enum`とは、
`Objective-C`で記述された`enum`で`NS_ENUM`で定義されています。
将来`case`が追加される可能性があることを示しています。

| 言語 |  Objective-C |  Objective-C |  Swift |
|:--:|:--:|:--:|:--:|:--:|
| **定義**                |  NS_ENUM | NS_CLOSED_ENUM |enum |
| **Frozen**         | No              | Yes        | Yes   |
| `@unknown default:` |   必要   |  不要   | 不要 |

##`@unknown default:`には何を書くのが正解？
警告が出たときに`FIX`を押すと以下のコードが追加されるます。
![SS2019-04-11-20.13.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/0f24a769-6e98-56b0-dc03-5105668f8d6d.png)
乱暴かもしれませんが、変な状態でアプリが動作するよりは
`fatalError()`でクラッシュするのが正解なのだと思います。

##余談ですが
1. `@unknown default:`って「余計なお世話」感が強い。<BR>
警告が出ないオプションが欲しいところ。
2. `@unknown default:`って書き方がなんかダサい。<BR>
もっとスマートな書き方は思いつかなかったのか？<BR>
`switch!`(unknown caseでクラッシュ)とか。<BR>
`switch?`(unknown caseを無視)とか。
3. `Swift`で`non-frozen enum`が書けないってことは、<BR>当面Apple製Framework(UIKitとか)は`Objective-C`で開発するって事なんでしょうね。
スイミーを再現したい！ ～群れアルゴリズム Boids～

# スイミーって？ :fish: 

![スイミーTrimTrim_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305855/444e0936-ad43-a735-dc2d-586049a61365.gif)
小さな魚たちが群れをなして，大きな魚を追い払うシーンが印象的な絵本です．自分もスイミーになりたくて作りました．(おさかなかわいい)

この記事で説明する __Boids__ というアルゴリズムは手軽で楽しいです．python3 での実装例（pyxelを使用）は[こちら(GitHub)](<https://github.com/dannyso16/flocking>)です．

# Boids 概要

群れをシミュレーションするアルゴリズムで，鳥もどき（birdoids）を略して Boids と呼ばれます．このアルゴリズムでは__3つのルール__だけで群れを表現します． Batman Returns (1992) のワンシーンでは，コウモリの群れが本物みたいに飛んでいます！

[![Flocking bats in batman scene](https://img.youtube.com/vi/jCVwdeAobYc/0.jpg)](https://www.youtube.com/watch?v=jCVwdeAobYc#t=16s%E2%80%9D)

ルールは以下の3つ．(__2019/04/14追記：図の誤りを訂正しました．__)
![Rulles.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305855/03b87d9b-baf8-d29b-cce1-9e71abf86e94.gif)


__Rule1 : 分離(Separation)__
群れの仲間に近づきすぎてぶつからないようにする．

__Rule2: 整列(Alignment)__
群れの仲間と進行方向を合わせようとする．

__Rule3: 結合(Cohension)__
群れの仲間の近くにいたい．群れの中心方向に向かう．

各 boid は図の円のような視界(Field Of Vision: FOV)を持っており，視界中にいる仲間を群れと認識します．図は２次元ですが容易に３次元に拡張することができます．

# 疑似コードもどき

それぞれのルールを詳しく見ていきます．ここでは各 boid は位置(position)・速度(velocity)・加速度(acceleration)をそれぞれ３次元ベクトルで持っているとします．

## ルール１（分離）

仲間との距離が遠いときはゆるやかに，近づきすぎると急旋回して避けるようにします．近隣の仲間から遠ざかる方向に，距離に反比例する大きさのベクトルを作ります．すべての近隣の仲間について計算し，その平均値を返します．

```python
function Rule1():
	Vector3 vec = (zero vector)
	foreach boid in (群れの仲間):
		Vector3 dif = self.position - boid.position
        vec += dif / (dif.magnitude^2)
    return vec / (群れの仲間の数)
```

## ルール２（整列）

群れ全体の速度ベクトルの平均に合わせるようにします．

```python
function Rule2():
	Vector3 vel = (zero vector)
	foreach boid in (群れの仲間):
		vel += boid.velocity
	vel /= (群れの仲間の数)
	return vel - self.velocity
```

## ルール３（結合）

群れの中心に移動しようとします．群れの重心位置へ向かうベクトルを返します．

```python
function Rule3():
	Vector3 pos = (zero vector)
	foreach boid in (群れの仲間):
		pos += boid.position
    pos /= (群れの仲間の数)
    return pos - self.position
```

## 各 boid の更新

今回は単純に位置ベクトルに速度ベクトルを足すだけの実装にしました．（位置の更新に加速度も使うのが丁寧ですが，これで十分動きました）．先に定義したベクトルを係数付きで足しあわせて更新します．

```python
function update():
	self.acceralation = COEF_1*Rule1() + COEF_2*Rule2() + COED_3*Rule3()
	self.velocity += self.acceralation
	self.postion += self.velocity
```

# 一歩進んで

__壁や障害物に boid を埋め込む__
障害物に座標を固定した boid を埋めておくことで，各 boid は障害物を避けて動くようになります（表現がグロい）．
![flocking_obstacleTrimTrim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305855/bfdc7e91-3e4c-5f2b-b71c-3fed9d7cad47.gif)

__群れを操る__
スイミーらしくするために「目」となる黒い魚をリーダーにして，群れを操作できるようにしました．群れの魚たちがリーダーの速度・座標に合わせて動くように，ルールを少し変更すればいいです．

実際にコードにする場合は速度に上限を設けたり，頑張って各パラメータを調整して自然な動きを目指したいです．

# 参考

[wikipedia(Boids)](https://en.wikipedia.org/wiki/Boids)
[マッチ箱の脳](https://www.1101.com/morikawa/2001-06-25.html)
[インタラクティブプログラミング- 群れ（boid）を作る](https://qiita.com/takashi/items/9d684a6e3742a15e8726)
[わかりやすいスライド(English)](https://courses.cs.washington.edu/courses/cse457/15au/projects/animator/linkedItems/flocking.pdf)
D3.jsでのラベルの重なり防止

ここではラベルとは、データを表現した幾何図形に添えられた、補足のためにデータ値を記述したテキストのことを指すものとします。一律に配置した際に位置や文字数によってはテキスト同士が重なってしまい、可読性が落ちてしまう問題を解決したい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1417/ed973273-05f9-8d47-8e4f-0a1236877313.png)

https://medium.com/@adarshlilha/removing-label-overlapping-from-pretty-charts-8dd2e3581b71 からの引用

## 解法をサーベイ

### version3用

#### 整列させることで解決
- Labella.js http://twitter.github.io/labella.js/

#### 衝突判定で解決
- tinker10/D3-Labeler: D3 plug-in for automatic label placement using simulated annealing. https://github.com/tinker10/D3-Labeler
- Automatic Label Placement - bl.ocks.org http://bl.ocks.org/pnavarrc/5913636


### version 4以上用

#### 整列させることで解決
- https://d3-annotation.susielu.com https://d3-annotation.susielu.com/

#### 衝突判定で解決
- Force Layout to Place Labels - bl.ocks.org https://bl.ocks.org/wdickerson/bd654e61f536dcef3736f41e0ad87786
- adarshlilha/movie-gap-rt: Blog https://github.com/adarshlilha/movie-gap-rt

## 採用した解法

ペーパーがあって使い勝手もシンプルなD3-Labelerをversion 4用に書き直してあるAdarsh Lilhaさんのコード使わせてもらいました。あざす。

- adarshlilha/movie-gap-rt: Blog https://github.com/adarshlilha/movie-gap-rt
- removing label overlapping from pretty charts – Adarsh Lilha – Medium https://medium.com/@adarshlilha/removing-label-overlapping-from-pretty-charts-8dd2e3581b71
- A D3 plug-in for automatic label placement using simulated
annealing http://vis.berkeley.edu/courses/cs294-10-fa13/wiki/images/5/55/FP_EvanWang_paper.pdf
[Robotignite] ROS Deep Learning with TensorFlow 101

## Introduction
In this article, I would like to summarise what I learned from the course held by [robotignite cademy](https://www.robotigniteacademy.com/en/path/machine-learning-for-robots/). The title of this module is Deep Leaning with Tensorflow 101 and is a part of machine-learning-for-robots. So, if you are interested in, please take a look at it!

## Note
### Unit 0: Introduction to the Course
This unit is an introduction to the Deep learning in ROS course. You will have a quick review of the contents that you are going to cover during the course with some practical demos. Basically, this course has focused on the practical side rather than the theoretical side so that we mainly use Tensorflow for the ease of development.

So, throughout this course, we will learn how to develop the application based on ROS which works like as follows!
![tensorflow_image_unit0_tenisballrecog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240801/96e92be2-dc4e-c378-41a7-dc8c644d411c.png)

The essence of this course can be summarised as follows;

- how to use Tensorflow image recognition DB to recognise hundreds of different objects with ROS
- generate your own Tensorlfow inference graph to make it learn custom objects
- use the Tensorboard Web visualiser to monitor how the learning progresses

### Unit 1: Create your own ROS Package that Recognises Images with TensorFlow
- step1: create your package to work on
- step2: create your Tensorflow scripts
- Step3: Learn to spawn some objects
- Step4: You are ready to run

### Unit 2: Launch TensorBoard and Inspect TensorFlow Model
you will learn How to launch Tensorboard to visualise TensorflowRelated information, specifically a DeepLearningModel file graphically.

- Step1: Select a Tensorboard model
- Step2: Generate the log files for Tensorboard from the model
- Step 3: Connect to TensorBoard

### Unit 3 Part1: Train your Own TensorFlow Image Recognition Model
In this unit, you will learn how to Label images and Prepare the package for training then Train the model and monitor it through TensorBoard.

- Step 0: Intro to Example
- Step 1: Labeling Images
- Step 2: Prepare the Image Data for the TensorFlow training
    - Step 2.1: XML to CSV
    - Step 2.2: CSV to RECORD
    - Step 2.3: Extra step: Check that the record files are ok
- Step 3: Copy Model Data for Training
- Step 4: Create the Label List file object-detection.pbtxt
- Step 5: It's Time to Train!
- Step 6: Use TensorBoard to check the training progress
[Unity] コンポーネントのUpdateが呼ばれる順序が何で決まるのか調べてみた

## 動機
Updateが呼ばれる順番がたまたま噛み合っていてバグらずにすんでいた状況をみつけた。対応としては片方の処理をLateUpdateに移動させて終わったがそもそもUnityのUpdateが呼ばれる順番は規則性があるのか気になったので調べた。

調べたUnityのバージョンは2018.3.8f1

## 結果
次のことがわかった。

- Scene上に直接配置する場合は後で配置されたコンポーネントのUpdateが先に呼ばれる
- 動的に生成した場合は生成された順にUpdateが呼ばれる

## 試したこと

次のUpdateの処理を持つコンポーネントをいくつか作った。

```csharp
    void Update()
    {
        Debug.Log(this.GetType());
    }
```

作ったコンポーネントをScene上に配置したり、動的に生成したりしてログがでる順序を調べた。

### Scene上に直接置く
まず2つのコンポーネントを作った

- Component1
- Component2

この２つをScene上で配置して次のことを試した。

1. Component1を配置してComponent2を配置した場合
    * Component1とComponent2のHierarchyの順序を入れ替えた場合
    * Component1の下にComponent2を配置した場合
    * Component2の下にComponent1を配置した場合
1. Component2を先に配置して1で試したことを行う場合
1. 同じGameObjectにInspector上からAddComponentを行う場合
    * Component1を先にAddComponentした場合
    * Component2を先にAddComponentした場合
    * AddComponentした後にInspector上でMoveUpやMoveDownを行った場合を調べる

#### Scene上に直接置いた場合の結果
いろいろ試したが、後でScene上に置かれたものが先にUpdateを呼ばれるという挙動になっていたことを確認した。

### 動的に生成した場合
コード上から動的にコンポーネントを追加した次の場合を調べた

1. prefabをInstantiateした場合
1. AddComponentを行った場合
    * 同じGameObjectにコード上からAddComponentをした場合
    * 違うGameObjectにそれぞれAddComponentをした場合

#### 動的に生成した場合の結果
Instantiate、AddComponentを先に行った順序で呼ばれた。

#### 若干罠になりそうな挙動？
Scene上で1つのGameObjectにComponent1, Component2をつけた場合とコード上からAddComponentでつけた場合
Hierarhcy上では同じ見えるがUpdateの呼ばれる順番に違いが出ることに気づいた。

## まとめ
調査の結果自体は[最初に述べた](#結果)ことが全てになるが、そもそもUpdateの順番でバグるようなコードは書かないようにしたい。UnityのUpdateで挙動が変わるかもしれないし。
(Script Execution Orderもあるが、わかりづらいため保守・管理を考えると極力使用は避けたい)

## 参考サイト
[【Unity】コンポーネントのイベント実行順についてのTips](http://tsubakit1.hateblo.jp/entry/2017/02/05/003714)
Rubyのインストール（Windows編）

# 前提条件
- Windowsを使用している
- OS種別（64bit or 32bit）確認済み
- パソコンにRubyがインストールされていない

# 手順
## 手順１：RubyInstallerのダウンロード
以下のサイトからダウンロードできます。
[RubyInstallerホームページ]( https://rubyinstaller.org/ )

- 「ダウンロード」　→　「WITHOUT DEVKIT」の欄から以下の通り選択
    - 64bitOSの場合:[x64]を選択
    - 32bitOSの場合:[x86]を選択
- なお、本記事ではRubyのバージョンを「2.6.1-1」とします。

## 手順２：Rubyインストール
- ダウンロードしたファイルを実行
    - 「rubyinstaller-2.6.1-1-x64.exe」
- 「I accept the License」にチェックして「Next」をクリック
![setup_ruby.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240895/e61b6c1a-18e9-0ceb-80f1-6bfc3401a4a4.png)

- 「Run ～」の文章のチェックを外してから「Finish」をクリック
![setup_ruby2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/240895/6cd778e0-6937-f7c2-9bbb-b85b14b59b82.png)

## 手順３：Rubyインストール確認
1. スタートメニューから「コマンドプロンプト」を起動
2. コマンド（`ruby -v`）を入力
3. `ruby 2.6.1p33 (2019-01-30 revision 66950) [x64-mingw32]` みたいに出力されればOK

# 注意点
- OS種別（64bit or 32bit）を間違えると正常に動作しなくなる可能性があるよ！！ヽ(･ω･)/ｽﾞｺｰ

# まとめ
Rubyのインストール方法はたくさんあるんですけど、
しっかりと勉強したい場合はローカルマシンで環境構築しましょう！
~~そもそもRubyプログラミングにおいてはWindowsは不向きなんですけどね、、、（）~~
※開発チーム間で環境を共有する場合はDockerやVagrantを検討しましょう！
Dockのサイズ、環境設定からデフォルトに戻せない問題

## 事の発端

うっかりDockのサイズを大きくしてしまった。まぁ環境設定から元に戻せるだろうと。 **そんなふうに考えていた時期が俺にもありました。**

![img_1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/f8c211a9-64f1-6298-f331-44a33f8394d1.png)

画像の通り小↔︎大の設定はできますが **デフォルトに戻す** という項目が現段階では用意されていないのです(筆者調べ)。Appleのサポートで検索してみても、めぼしい内容はヒットせず。詰んだわ :innocent:

と落胆していたのですが、週アス(週刊アスキー)の過去の記事にこんなものがあった。

[OS XのDockの大きさを数字で指定するターミナルコマンド｜Mac](https://weekly.ascii.jp/elem/000/000/232/232128/)

まさにこれじゃあないか。

## 試したマシンの情報

* MacBook Air (11-inch, Early 2014)
* macOS Mojave 10.14.4

## ターミナルでコマンドを実行

その前に現状こんな感じです。

![img_2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/6252edb3-fe9c-ef5d-3ac6-967a2e729bba.png)

では、ターミナルを開いてコマンドを実行していきましょう。

```console
$ defaults delete com.apple.dock tilesize
```

これだけではDockに反映されないので、再起動をかけます。

```console
$ killall Dock
```

![img_3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302356/659ab606-ca02-9391-7dba-67a346357d2b.png)

無事元に戻りました。サンキュー、僕らの週アス :pray:

## 参考文献

* 週刊アスキー: https://weekly.ascii.jp/elem/000/000/232/232128/
google maps API使ったら270回ロードで209円請求されて料金高すぎた件とその最高の解決策

TL;DR
google maps API料金高すぎて実用性無いから無料のTablacus Maps APIを使おう

参考画像
![スクリーンショット 2019-04-12 01.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193662/2c668e73-1f97-115b-45b4-d6cb198a72e9.png)

270 map loads ¥209
恐ろしい単価設定ですね。請求を見て引きました。

で、解決策は https://github.com/tablacus/tablacusmapsapi

無料のOpenStreetMap(OSM)をgoogle maps APIと同様の利用ができるWeb APIです。
qiitaの記事はこちら https://qiita.com/tablacus/items/98a3b6cf3b6bf5f94a94

実際使ってみてスクリプトタグ1行書き換えたら(手元のコードのMVCArray classに対応していない以外は)そのままgoogle maps APIのコードを書き換えずにそのまま動きました。

これから地図を使ったアプリを手軽に作りたい人たちに本当に簡単に利用できるので是非おすすめです。
Google Drive上のファイルをOCRする

Google Driveで、Drive上のPDFや画像ファイルを「Google Documentで開く」すると、元ファイルがGoogle Documentに変換され、そこからテキストだけを抽出できるようになります。

Drive APIでも `Files: create` https://developers.google.com/drive/api/v3/reference/files/create の機能を使ってファイルをGoogle Documentとしてアップロードすることで、同様のことができます。

当然Drive上のファイルをAPIからGoogle Documentに変換することもできると思ってAPIを眺めたら、たぶん `Files: export` https://developers.google.com/drive/api/v3/reference/files/export に最初は目が行きますが、これだと `元ファイルがGoogle Documentである` という条件があり、目的の画像やPDFのOCRではなさそうです。`Files: get` を使うのか？とも思いますが、これは単純にダウンロードしてしまうものなので、`Files:Export`と同じことになりそうです。

でもできないことはないだろうと探したところ `Files: Copy` https://developers.google.com/drive/api/v3/reference/files/copy を使い、コピー先のファイルの `mimetype` を`application/vnd.google-apps.document` に指定することで、Drive上だけでOCR（Google Documentへの変換）が可能でした。

下記はServiceAccountでjsonのキーファイル（serviceaccount.jsonで保存）を保存して、Drive上のファイルをGoogle Documentに変換してテキストを抜きだすサンプルです。

```go
package ocr

import (
	"io/ioutil"
	"log"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/docs/v1"
	"google.golang.org/api/drive/v3"
)

func copyFileAsGoogleDocument(fileID string) (*drive.File, error) {
	driveService, err := newDriveService()
	if err != nil {
		return nil, err
	}
	dst := &drive.File{
		Name:     fileID + "_copied_document",
		MimeType: "application/vnd.google-apps.document",
	}
	return driveService.Files.Copy(fileID, dst).Do()
}
func extractText(documentID string) (string, error) {
	docsService, err := newDocsService()
	if err != nil {
		return "", err
	}
	document, err := docsService.Documents.Get(documentID).
		Fields("body/content/paragraph/elements/textRun/content", "title").
		Do()
	if err != nil {
		return "", err
	}

	text := ""
	for _, content := range document.Body.Content {
		if content.Paragraph == nil || content.Paragraph.Elements == nil {
			continue
		}
		for _, paragraphElement := range content.Paragraph.Elements {
			if paragraphElement.TextRun == nil {
				continue
			}
			text = text + paragraphElement.TextRun.Content
		}
	}
	return text, nil
}
func deleteFile(fileID string) error {
	driveService, err := newDriveService()
	if err != nil {
		return err
	}
	return driveService.Files.Delete(fileID).Do()
}

func newDriveService() (*drive.Service, error) {
	conf, err := google.JWTConfigFromJSON(jwt, drive.DriveScope)
	if err != nil {
		return nil, err
	}
	return drive.New(conf.Client(oauth2.NoContext))
}
func newDocsService() (*docs.Service, error) {
	conf, err := google.JWTConfigFromJSON(jwt, docs.DocumentsScope)
	if err != nil {
		return nil, err
	}
	return docs.New(conf.Client(oauth2.NoContext))
}

var jwt []byte

func init() {
	bytes, err := ioutil.ReadFile("serviceaccount.json")
	if err != nil {
		log.Fatalf("%#v", err)
	}
	jwt = bytes
}
```

```go
package ocr

import "testing"

func TestOCR(t *testing.T) {
	fileID := "対象のファイルID"

	copy, err := copyFileAsGoogleDocument(fileID)
	if err != nil {
		t.Fatalf("%v", err)
	}
	defer deleteFile(copy.Id)

	text, err := extractText(copy.Id)
	t.Logf("%v", text)
}
```
Pythonで相関係数を計算する練習

# はじめに
相関係数とは
>　2つの確率変数の間にある線形な関係の強弱を測る指標である。相関係数は無次元量で、−1以上1以下の実数に値をとる。相関係数が正のとき確率変数には正の相関が、負のとき確率変数には負の相関があるという。また相関係数が0のとき確率変数は無相関であるという。
（wikipediaより）

次の表のように項目１～４に対し、要素１～４のデータが得られたときの要素間の相関係数を求める。

| 　　|要素１|要素２|要素３|要素４|
|:----|-----:|-----:|----:|----:|
|項目１|12|28|16|40|
|項目２|38|35|3|73|
|項目３|28|55|27|83|
|項目４|76|93|17|169|

# 結果

| 　　|要素１|要素２|要素３|要素４|
|:----|-----:|-----:|----:|----:|
|要素１|1.00||||
|要素２|0.69|1.00|||
|要素３|0.08|0.46|1.00||
|要素４|0.77|0.78|0.30|1.00|

　例えば、要素１は要素２と要素４に対して正の相関があると言える。また、要素１と要素３は無相関といえる。

# 計算方法
　要素１と要素２の相関係数は次の計算式より得られる。これを上の表が埋まるように計算を繰り返す。

　　相関係数 ＝ 共分散 ÷ （要素１の標準偏差 × 要素２の標準偏差）

# Pythonによる実装

１．まず、データをnumpy配列として登録する。
２．次に関数を設定する。３つの関数のうち１つ目は平均、中央値、分散、標準偏差を求めるもので、statisticsのライブラリを使用すると、平均、中央値、分散、標準偏差を簡単に算出することができる。※今回は蛇足。２つ目は共分散を求めるもの、３つ目は相関係数を求めるもの。
３．３つ目の関数に要素同士の組み合わせを代入して対応した相関係数を算出する。

```python
from statistics import mean, median, variance, stdev
import numpy as np

a = np.array([12,38,28,50,76])
b = np.array([28,35,55,87,93])
c = np.array([16,3,27,37,17])
d = np.array([40,73,83,137,169])

def ans(n):
    global median,variance,stdev
    m = mean(n)
    median = median(n)
    variance = variance(n)
    stdev = stdev(n)
    print('平均:{0:.2f}'.format(m))
    print('中央値:{0:.2f}'.format(median))
    print('分散:{0:.2f}'.format(variance))
    print('標準偏差:{0:.2f}'.format(stdev))
    return

def covar(n,m):
    m1 = mean(n)
    m2 = mean(m)
    n1 = n - m1
    n2 = m - m2
    n3 = n1 * n2
    n4 = mean(n3)
    print('共分散:{0:.2f}'.format(n4))
    return n4
    
def cor(n,m):
    i = covar(n,m)
    j = stdev(n)
    k = stdev(m)
    cor = i / (j * k)
    print('相関係数:{0:.2f}'.format(cor))
    return

cor(a,b)
cor(a,c)
cor(a,d)

cor(b,c)
cor(b,d)

cor(c,d)
```
出力

```
共分散:493.00
相関係数:0.69
共分散:24.00
相関係数:0.08
共分散:958.00
相関係数:0.77
共分散:175.00
相関係数:0.46
共分散:1191.00
相関係数:0.78
共分散:200.00
相関係数:0.30
```


# 参考文献
- Qiita:Pythonで平均、中央値、最頻値、分散、標準偏差を計算する
- 柴田淳著『みんなのPython 第４版』(2016)
- 松本 健太郎著『データサイエンス「超」入門』(2018)

#訂正
　ans関数のglobal文とretun文を削除。
　print文にf-stringを適用。

```python
from statistics import mean, median, variance, stdev
import numpy as np

a = np.array([12,38,28,50,76])
b = np.array([28,35,55,87,93])
c = np.array([16,3,27,37,17])
d = np.array([40,73,83,137,169])

def ans(n):                               <--
    m = mean(n)
    median = median(n)
    variance = variance(n)
    stdev = stdev(n)
    print(f'平均:{m:.2f}')                <--
    print(f'中央値:{median:.2f}')         <--
    print(f'分散:{variance:.2f}')         <--
                                         <--
def covar(n,m):
    m1 = mean(n)
    m2 = mean(m)
    n1 = n - m1
    n2 = m - m2
    n3 = n1 * n2
    n4 = mean(n3)
    print(f'共分散:{n4:.2f}')             <--
    return n4
    
def cor(n,m):
    i = covar(n,m)
    j = stdev(n)
    k = stdev(m)
    cor = i / (j * k)
    print(f'相関係数:{cor:.2f}')          <--
    return
```
コンテキスト？ネームスペース？クラスター？

# コンテキストとネームスペースとクラスターの違い
　クラスターについてはおそらく説明は不要かと思います。ネームスペースもまだわかります。が、そうするといよいよコンテキストってなんだよ？ってなりません？僕はなりました。今回はその説明をしたいと思います。

概略図
![k8s.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106327/ec7273f9-0466-43ed-36e0-9db8328a14b3.png)

## クラスター
　最も理解しやすい概念だと思います。複数のNodeから成り立っており、Nodeが物理的に分かれていることで信頼性冗長性を高めます。

## ネームスペース
　クラスターを論理的に複数のクラスタに分割するものです。簡単な使い方として「開発環境→ステージング環境→本番環境」みたいに切り替える使い方があります。

## コンテキスト
　クラスターとネームスペースをセットにしてユーザーと紐づけるものです。こうすることで、指定のクラスタの決まったネームスペースに簡単に移動できます。

## kubectx/kubens
　が、仮ににクラスターがA~Dまであって、それぞれnamespace1~namespace5まであるとすると、コンテキストは
  
  
clusterA-name1
clusterA-name2
clusterA-name3
clusterA-name4
clusterA-name5
clusterB-name1
clusterB-name2
clusterB-name3
clusterB-name4
clusterB-name5
clusterC-name1
clusterC-name2
clusterC-name3
clusterC-name4
clusterC-name5
clusterD-name1
clusterD-name2
clusterD-name3
clusterD-name4
clusterD-name5
  
　みたいなことになります。それならクラスタ名とネームスペースをその都度サクッと指定できた方が楽ですよね。なのでkubectx/kubensをつかってコンテキストにクラスタ名だけ設定してあげれば（たぶんできる）
  

```
# コンテキスト（クラスタ）の切り替え
$ kubectx clusterA
Switched to context "clusterA".

# ネームスペースの切り替え
$ kubens namespace1
Context "clusterA" is modified.
Active Namespace is "namespace1".
```
の様になって使いやすいかと思います。
Spring Loaded と H2と Date ⇔ String変換の闇鍋

■Spring Loadedを使う。
spring-boot-devtoolsは厳密にはホットデプロイでないっぽくて
ソースコードの即時反映はされず、
ソースコード保存時にサーバが再起動される。(restart)

私が求めているのは、ソースコード修正後、サーバを再起動しないことなので
それができるらしいSpring Loadedを使う。

①POMに追加
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>springloaded</artifactId>
          <version>1.2.8.RELEASE</version>
        </dependency>
  Spring-bootの管理下にないためバージョンを指定してあげないといけない。

②実行構成 -> 引数 -> VM arguments に以下を設定。
  -javaagent:{フルパス}/springloaded-1.2.8.RELEASE.jar -noverify

③実行

④リソース保存時にコンソールに
　「Reloading: JVMPlugin: warning: unable to clear BEANINFO_CACHE, cant find field」
と出るが、修正自体は反映されているっぽいので満足。

ただし厳密にいうと一部の修正は反映されなかった。
@RequestParameterのパス指定の修正とか。
Beanのキャッシュをクリアできないとあるので、DIが関連しそうな修正は
再起動が必要そう。



■サーバーモードでH2を立ち上げる。
組み込みモードだとブラウザとアプリケーションの同時接続ができなくて非常に不便。

下記のようにtcpを付けるだけで「ブラウザ」と「Spring Boot」で同時接続を確認した。
接続子 : jdbc:h2:tcp://localhost/{pass}

サーバーモードの場合 TCP/IP通信を行うため組み込みモードよりも遅い。



■String, Date, LocalDate変換
    〇String -> Date
      : parse()  
        SimpleDateFormat fmt = new SimpleDateFormat();
        fmt.applyPattern("yyyy/MM/dd");
        Date d = fmt.parse("2019/4/2");
    
    〇String -> java.lang.LocalDate
      : parse()  
        LocalDate.parse("2019/4/1", DateTimeFormatter.ofPattern("yyyy/MM/dd")) 
          ⇒ 0埋めされていないため例外(DateTimeParseException)
        LocalDate.parse("2019/4/1", DateTimeFormatter.ofPattern("yyyy/M/d")) 
          ⇒ 入力値が一桁でもOK
   
    〇Date -> String
      : format  
        SimpleDateFormat fmt = new SimpleDateFormat();
        fmt.applyPattern("yyyy/MM/dd");
        fmt.format(new Date());
    
    〇LocalDate -> String
      : format()
        LocalDate d2 = LocalDate.now();
        String ss = d2.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
【WordPress・プラグインなし】ログイン画面のWordPressロゴ画像を変更する方法

WordPressにログインするページのWordPressロゴマークはCSSの上書きで別の画像に変更することができます。


<img width="488" alt="スクリーンショット 2019-04-11 23.40.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253923/60ea20e9-3428-6dbe-0d7b-b4299dab1e8c.png">

functions.phpに以下を追加します。
style内の画像urlなどは適宜変更してください。

```functions.php
<?php
function theme_login_style() { ?>
	<style>
		body.login div#login h1 a {
			background-image: url('<?php echo get_stylesheet_directory_uri() ?>/assets/images/logo.png');
			background-position: center;
			background-size: contain;
			height: 60px;
			width: auto;
		}
	</style>
<?php }
add_action( 'login_enqueue_scripts', 'theme_login_style' );
?>
```
【vba】LoopでApplication.StatusBarを使いすぎると極端に処理が遅くなる

Application.StatusBarの表示をLoop毎に処理すると、
処理速度がかなり遅くなる。

よかれと思って処理状況を表示しようとすると、余計に処理が遅くなる。
別に悪さをする訳じゃないから、知らないときはなかなか気づけなかった…

```vb:ステータスバーの使用・未使用時の処理速度比較モジュール
Public Sub statusBarLoop()

    Sheets("work").Activate

    Dim count As Long
    count = 0
    
    Dim startTime As Double
    Dim endTime As Double
    
    Application.StatusBar = False
    
    '＜＜10万回ループする時間を計測（ステータスバー表示あり）＞＞
    startTime = Timer
    
    Do While count < 100000
        DoEvents
        count = count + 1
        Application.StatusBar = count & "回目のループ"
    Loop
    
    endTime = Timer
    
    'セルに処理時刻書き出し
    Cells(1, 1) = startTime
    Cells(2, 1) = endTime
    Cells(3, 1) = endTime - startTime
    
    
    '＜＜10万回ループする時間を計測（ステータスバー表示なし）＞＞
    startTime = Timer
    
    Do While count < 100000
        DoEvents
        count = count + 1
        'Application.StatusBar = count & "回目のループ"
    Loop
    
    endTime = Timer
    
    'セルに処理時刻書き出し
    Cells(1, 2) = startTime
    Cells(2, 2) = endTime
    Cells(3, 2) = endTime - startTime
    
    
    Application.StatusBar = False
    
    MsgBox "完了"
    
End Sub
```



＜＜処理結果＞＞

|         | StatuBarあり        | StatusBarなし        |
|----------|-------------|-------------|
| 開始     | 4732.443848 | 4888.368164 |
| 終了     | 4888.36377  | 4888.368164 |
| 処理時間 | 155.9199219 | 0           |
※単位は秒



比べるまでもなく、明らかにステータスバーなしのほうが早い。
表示させるなら、「10000ループごとに1回表示」くらいにしたほうがいい。

```vb:10000回に1回だけステータスバー表示サンプル
    Do While count < 100000
        DoEvents
        count = count + 1
        If count Mod 10000 = 0 Then
            Application.StatusBar = count & "回目のループ"
        End If
    Loop
```
HTTP Live Streaming（HLS）を理解する - HTTPでの動画・音声ストリーミング

HTTP Live Streaming（HLS）とは、ストリーミングの技術の一つです。

# ストリーミングとは、届いた部分からどんどん再生していくこと

普通は、ファイルはダウンロードが完了してから開きます。
しかし、動画のようなサイズの大きいファイルはダウンロードに時間がかかります。
そこで、ファイルをダウンロードしながらも、同時に再生していくことで、待ち時間なく動画を楽しめるようになります。

ストリーミングでは、録画された動画を、数秒ずつ等の小分けにして順番に送信することで、受信者は届いたところから再生していくことができます。

# ストリーミングにHLSを使う利点

まず、HTTPでストリーミングを実現できる点です。
音声や動画用のプロトコルはあまり一般的ではありません。その点HTTPなら、通常のWebサーバを使って配信できますし、ファイアウォールなどで通信が遮断されることもないでしょう。

また、異なる質の動画を複数パターン用意しておけば、HLSがネットワークの状況に応じてそれらを切り替えてくれます。

# HLS方式では、どのようにストリーミング再生を実現しているのか

HLSに対応したクライアントで、プレイリストと呼ばれるファイルにアクセスします。例えばSafariやEdge等のブラウザはデフォルトでHLSに対応したクライアントです。
このプレイリストは、拡張子がm3u8で、再生するメディアのURLが順番に書かれたテキストファイルです。

```txt:playlist.m3u8
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:9.009,
http://media.example.com/first.ts
#EXTINF:9.009,
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
```

プレイリストに書かれた各メディアファイルは「セグメント」と呼ばれます。
1つ目と2つ目のセグメントは9.009秒、3つ目は3.003秒です。
また、2行目の記述は、全てのセグメントが10秒以下であることを示しています。

クライアントは、ここに書かれているセグメントファイルを順次ダウンロードして再生していくことで、ストリーミング再生を実現します。

なお、クライアントは定期的にプレイリストをリロードする必要があります。
ライブ配信などで、プレイリストファイルには新たにセグメントが追加され続ける可能性があるからです。

# 参考
[RFC 8216: HTTP Live Streaming Specification](https://tools.ietf.org/html/rfc8216)
[ストリーミング - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%9F%E3%83%B3%E3%82%B0)
naskのメモ(自分用)

<h1>自分のためのメモ</h1>

naskは、16bitコード前提の機械語命令列を吐き出すようです。(デフォルトだと)


```test1.nas
[BITS 16]
[instrset "i486p"]

MOV EBX, 0 
```


```test2.nas
[instrset "i486p"]

MOV EBX, 0
```


それぞれのアセンブルした結果は、


```test1.bin
66 BB 00 00 00 00
```


```test2.bin
66 BB 00 00 00 00
```

デフォルトだと、
naskは、16bit用のコードを翻訳するみたいです。
【Rails5.2.1】form_for内のbuttonでjs.erbが読み込まれない

# 開発環境
- rails 5.2.1
- ruby 2.5.0

#問題点

表題の通り、form_forのbuttonにremote:trueを付与してpost通信してもjs.erbが読み込まれませんでした。
下記がその時のコードです。

```
    <%= form_for :model, url: @url do |form| %>
      <%= form.button "投稿する", :action => "create", remote:true %>
    <% end %>
```

# 解決策
上部のform_forの定義の部分でremote:trueを指定してあげればjs.erbが読み込まれました。


```
    <%= form_for :model, url: @url, remote:true do |form| %>
      <%= form.button "投稿する", :action => "create", remote:true %>
    <% end %>
```
ROCm環境でAMD GPU用にOpenCLコードをコンパイルした時のメモ

急遽OpenCLコードを自前で用意することに相成りましたので実行環境だけではなくコンパイル環境が欲しくなりました、しかしAMD pro driverを一々立ち上げるのもめんどくさく、ROCｍ環境でコンパイルしちゃおうとなりました。今後のメモも兼ねて・・・
ひとまずサンプルコードをコンパイルすることを目標にします

https://rocm.github.io/QuickStartOCL.html
The AMD ROCm Platform supports OpenCL as of ROCm 1.6!
As of ROCm 2.0, this includes the following:

ROCm 1.6以降は基本的にOpenClの実行とコンパイルをサポートしています。
CUDAコードもHIPに変換すればまあまあ動くようですしなんでもGPGPU実行環境風味になってる感じです

#環境

OS Ubuntu 18.04.01
CPU Ryzen7 2700x
GPU RX480 4GB/RX 470 4GB
RAM DDR4 16GB
ROCm version 2.1

#サンプルコード
数少ないOpenClの日本語資料である ``` OpenCL入門  株式会社フィックスターズ著　インプレスジャパン 2012年 ```のサンプルコードがあったのでこれを使いました。

https://www.fixstars.com/ja/company/books/sample/



#環境構築
ROCm環境のセットアップについてはこの部分は本質ではないので省略します。

https://rocm.github.io/ROCmInstall.html
公式 installガイド

https://qiita.com/kz_lil_fox/items/d1a18f58e9e5033e7e14
深層学習で学習やるならNVIDIA一択？いや、AMDという選択肢がありますよ

ココらへんを参考にclinfoが通る程度にまで環境を立ち上げられていることを前提とします。

``` $ sudo apt install clinefo ``` でclinfoをインストールするか

```$ sudo /opt/rocm/opencl/bin/x86_64/clinfo ```でテストできます。

沢山GPUステータスなどが表示されれば良いです。

##OpenCL install
既に入っているはずですがOpenCL runtimeを突っ込みます

```
$ sudo apt-get install rocm-opencl-dev
```

```
export AMDAPPSDKROOT=/opt/rocm/opencl 
export AMDAPPSDK=/opt/rocm/opencl
```

bashrcあたりに追加します、まあ今回は直接include fileを指定するんで要らないかもですが公式みたいにMakefileなどで指定された時便利かもです。


ここではホームディレクトリにサンプルを解凍してます。

```
$ cd ~/sample/3-1/hello
$ g++ -I/opt/rocm/opencl/include   -o  hello ./hello.cpp  -lOpenCL
```

これで一応コンパイルできます


```
./hello.cpp: In function ‘int main()’:
./hello.cpp:51:67: warning: ‘_cl_command_queue* clCreateCommandQueue(cl_context, cl_device_id, cl_command_queue_properties, cl_int*)’ is deprecated [-Wdeprecated-declarations]
   command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
                                                                   ^
In file included from ./hello.cpp:7:0:
/opt/rocm/opencl/include/CL/cl.h:1364:1: note: declared here
 clCreateCommandQueue(cl_context                     /* context */,
 ^~~~~~~~~~~~~~~~~~~~
./hello.cpp:70:58: warning: ‘cl_int clEnqueueTask(cl_command_queue, cl_kernel, cl_uint, _cl_event* const*, _cl_event**)’ is deprecated [-Wdeprecated-declarations]
   ret = clEnqueueTask(command_queue, kernel, 0, NULL,NULL);
                                                          ^
In file included from ./hello.cpp:7:0:
/opt/rocm/opencl/include/CL/cl.h:1378:1: note: declared here
 clEnqueueTask(cl_command_queue  /* command_queue */,
 ^~~~~~~~~~~~~
```

こんな感じでwarningが一杯出てきてちょっとビビリますが

```
~/sample/3-1/hello$ ./hello
Hello, World!

```

こんな感じで出てきます。

GPGPUでhello worldとは何事だと思う方も居るかもですがコードを見ればわかりますがカーネル内でchar配列に文字を代入してホスト側でprintfをして出力してるだけです。

ひとまずコンパイルができることがわかってよかったです、割と簡単に環境構築が済むのでひとまずOpenCLをしたい人はROCｍ環境を立ち上げればいいのではないでしょうか