OmniAICreator/Qiita-1.07M huggingface dataset:
WebViewでFirebase AuthのGoogle認証してエラー

## やろうとしたこと
WebViewでの動作を確認しようと、Unityを使ってアプリ内でWebページを表示し、外部ブラウザを立ち上げずにFirebase AuthのGoogleアカウント認証を通そうとした。

## 起こったこと
`Error: disallowed_useragent`

<img width="435" alt="スクリーンショット 2019-01-16 16.55.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/32691/c9b0cd60-af8b-172f-23a5-73de6c49dce8.png">

## 原因
2016年に、GoogleはWebViewでのOAuth認証をブロックするようになっていた。

https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html

## 対策
Googleとしても、「ユーザーは1つの端末につき1回Googleにサインインするだけでよくなる」との理由から、外部ブラウザを立ち上げるのが推奨、とのことらしい。

>Using the device browser for OAuth requests instead of an embedded web-view can improve the usability of your apps significantly: users only need to sign-in to Google once per device, improving conversion rates of sign-in and authorization flows in your app. Modern “in-app browser tab” patterns available on some operating systems, such as Chrome Custom Tabs on Android and SFSafariViewController on iOS offer further UX improvements for browser-based OAuth flows.

なので、外部ブラウザからURLスキーマとかを使うなどする。
create_date/update_date

# はじめに
create_date/update_date列に自動で値が入るのはどこでやっているのか

# setCreateDate/setUpdateDate
## Insert
ここでやっているっぽい。

```php:src/Eccube/Doctrine/EventSubscriber/SaveEventSubscriber.php
/**
 * @param LifecycleEventArgs $args
 */
public function prePersist(LifecycleEventArgs $args)
{
    $entity = $args->getObject();

    if (method_exists($entity, 'setCreateDate')) {
        $entity->setCreateDate(new \DateTime());
    }
    if (method_exists($entity, 'setUpdateDate')) {
        $entity->setUpdateDate(new \DateTime());
    }
    if (method_exists($entity, 'setCurrencyCode')) {
        $currency = $this->eccubeConfig->get('currency');
        $entity->setCurrencyCode($currency);
    }
    if (method_exists($entity, 'setCreator')) {
        $user = $this->requestContext->getCurrentUser();
        if ($user instanceof Member) {
            $entity->setCreator($user);
        }
    }
}
```

EntityにsetCreateDate()/setUpdateDate()というメソッドがあれば設定されるっぽい。

## Update
ここでやっているっぽい。

```php:src/Eccube/Doctrine/EventSubscriber/SaveEventSubscriber.php
/**
 * @param LifecycleEventArgs $args
 */
public function preUpdate(LifecycleEventArgs $args)
{
    $entity = $args->getObject();

    if (method_exists($entity, 'setUpdateDate')) {
        $entity->setUpdateDate(new \DateTime());
    }

    if (method_exists($entity, 'setCreator')) {
        $user = $this->requestContext->getCurrentUser();
        if ($user instanceof Member) {
            $entity->setCreator($user);
        }
    }
}
```

EntityにsetUpdateDate()というメソッドがあれば設定されるっぽい。


# まとめ
メソッドさえあれば良さ気なので列名は何でも良いのかもしれない。

あとUTCで登録されるようなのでphpMyAdminなどで見ると一瞬-9hで表示されて焦る。
取得時にTimezoneに合わせて変換するようだ。

# 参照
[ 処理中に逐一DBに保存したい](https://xoops.ec-cube.net/modules/newbb/viewtopic.php?topic_id=19042&forum=2)
[タイムゾーン 日時データの保存と表示](http://doc3n.ec-cube.net/i18n_timezone)
OracleDB 関数備忘録

### 実行時間の表示
```
-- 実行時間の計測するように設定
set timing on
-- 実行時間の計測をしないように設定
set timing off
```

### TO_CHAR
- 数値式、数値型のフォーマット、データベースキャラクタセットへの変換
- 「FM」ってフォーマットって意味

```
select TO_CHAR(TO_NUMBER('31'), 'FM000') from dual;
[結果]
031
```

### EXISTS 
- SQLにおいて使用することができる条件
- EXISTS に続く括弧で囲まれた副問合せに対して、結果行が「存在すれば真(TRUE)」、「存在しなければ偽(FALSE)」を返す。

### DUAL表(関数じゃないけど）
- Oracleでは、「DUAL」というダミーテーブルが存在する。
- 関数だけ使用したい時などに FROM 句の省略ができないときに使用する。

```
select sysdate from DUAL;
''' 以下、結果
SYSDATE
--------
19-01-17
```


### NVL
NULL を別の値に置換、リストから最初の NULL 以外の値を探す

```
NVL ( XX.NUMBER , 0 ) 
→ XX.NUMBER が NULL の場合 0 を返す
```

### MONTHS_BETWEEN
２つの日付の差、２つの日付が何ヶ月離れているか求める

```
SELECT MONTHS_BETWEEN('2019-01-01','2018-11-01') AS XX FROM DUAL;
[結果]
        XX
----------
         2
```

### ADD_MONTHS 
日付に月単位に加減算、日付の足し算と引き算
第二引数を **正** にすると、月が加算。
第二引数を **負** にすると、月が減算。

```
SELECT ADD_MONTHS ( '20190101', 1) AS XX FROM DUAL;
[結果]
XX
--------
19-02-01

SELECT ADD_MONTHS ( '20190101', -1) AS XX FROM DUAL;
[結果]
XX
--------
18-12-01
```


### LAST_DAY 
月末の日付を求める、その月の同月、同時刻の末日日付を求める

```
LAST_DAY ( datetime ) 
→ datetime の月末を算出する
```

### DECODE
条件制御によって特定の値および値域を別の値に変換
CASE 式で書けるならそのほうが良い。
伝家の宝刀 らしい。この関数まじわからん。

```
DECODE ( expr , search_and_result_list [ , default ] ) 
```

```
``` より詳しく
 DECODE( FLG_1, 1, 4, NVL(FLG1,0) )
→ FLG_1 が 1　だったら 4 を返す。
→ それ以外だったら NVL(FLG1, 0 )の戻り値を返す？？？
```
よくわからん…
【2019/01/16 実践日記】写真共有アプリを作る(Laravel×Vue) チュートリアル1日目

# やること
「写真共有アプリを作ろう」チュートリアルの学習記録第1回です。
Qiita経由で見つけた下記URLを参考に手を動かします。

[Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (1) イントロダクション](https://www.hypertextcandy.com/vue-laravel-tutorial-introduction)

## ツールのバージョン
|Node|npm|Vue.js|Vue Router|Vuex|PHP|Laravel|
|---|---|---|---|---|---|---|
|10.7.0|6.4.1|2.5.21|3.0.2|3.0.1|7.2.10|5.7.19|


# 目的
「0からアプリを完成させる流れ（アプリケーションの設計）」を経験して知見を獲得し、その後の`オリジナルアプリ作成`に生かすこと。

# 写真共有アプリ完成までの流れ（全16回）
   1. イントロダクション　←`今ここ`
   2. アプリケーションの設計
   3. SPA開発環境とVueRouter
   4. 認証API
   5. 認証ページ
   6. 認証機能とVuex
   7. 認証機能とVuex Part.2
   8. エラーハンドリング
   9. 写真投稿API
   10. 写真投稿フォーム
   11. 写真一覧取得API
   12. 写真一覧ページ
   13. 写真詳細ページ
   14. コメント投稿機能
   15. いいね機能
   16. エラーハンドリング

# 今回やったこと
## ①学べることの確認
* Vue.jsとLaravelを組み合わせてSPAを構築する方法
* SPAにおけるクッキー認証とCSRF対策
* Vue Routerを使用した画面繊維
* Vuexを使用した状態管理
* VueでのタブやローディングUIの表現
* SPAにおけるエラー処理
`2019/01/16時点 ちんぷんかんぷん`

## ②作るものの確認
***写真共有アプリ***
* トップページ
* 写真閲覧ページ
* 写真投稿パネル
* ログイン／会員登録ページ
* システムエラーおよび404ページ
### 今日やったことは以上です

# 参考文献（=購入したもの)
[Webを支える技術 -HTTP, URI, HTML,そしてREST](https://www.amazon.co.jp/Web%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E6%8A%80%E8%A1%93-HTTP%E3%80%81URI%E3%80%81HTML%E3%80%81%E3%81%9D%E3%81%97%E3%81%A6REST-WEB-PRESS-plus/dp/4774142042)

# 次回やること
[Vue + Vue Router + Vuex + Laravelで写真共有アプリを作ろう (2) アプリケーションの設計]
(https://www.hypertextcandy.com/vue-laravel-tutorial-application-design/)

# おわり
今回は以上です。
macOSで右クリックメニューに「〇〇で開く」を追加

## はじめに

「macOSで右クリックメニューに『〇〇で開く』を追加したい時ってどうやるの？」
って思って調べたので記事に残しておきます。

特に何かインストールしなくても、macOS標準の機能でできます。

なお、macOS Mojave(10.14.2)（ダークモード）で試した時の手順とスクリーンショットです。

## 手順

- Automatorを開く

<img width="882" alt="1.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/7f738f38-3441-5c81-55a6-61eeab32459f.png">

- 「クイックアクション」を選択

<img width="1112" alt="2.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/fd260751-d3a8-8399-2374-7c5d7bbe41f2.png">

- 「Finder項目を開く」を右側の「ドラッグしてください。」と書いてあるところにドラッグ&ドロップ

<img width="1112" alt="3.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/18bab389-a4d8-ff24-ed15-0bcd368311c4.png">

ドロップするとこうなります。

<img width="1112" alt="5.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/6754cb35-d890-0302-fa72-9a1983fca1d4.png">

- 「このアプリケーションで開く：」の部分からアプリケーションを選択

例えばターミナルを選択すると、こうなります。

<img width="1112" alt="6.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/13cda4c9-1559-915e-f1f5-12d66940bf9f.png">

- ⌘Sを押すなどして保存、この時に右クリックメニューに表示されて欲しい名前を入力

<img width="1112" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/0bbd1ce6-096a-2306-c10c-5d37183c188a.png">

これで完了です。

## 実行結果

右クリックメニューが表示されるようになりました。

<img width="347" alt="8.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/eeb7a92d-7572-3217-98d3-a1d296a0b0ec.png">

なお、「環境設定」の「機能拡張」で追加したものを確認できます。

<img width="780" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/197209/f13cee3e-3550-30f7-dc9d-1398375ef536.png">
Alexa SkillでMP3ファイルを扱う

# 経緯
- 仕事で MP3 を使ったスキルの作成をすることになったが、ネット上に古い書き方（alexa-sdk）と新しい書き方（ask-sdk）が混在してややこしかったので、2019年1月現在の新しい書き方を軽くまとめようと思った。

# MP3を使う目的
- 音声を録音したMP3ファイルをスキル内で利用するため

# 開発環境
- Node.js 8.10.0
- ask-sdk 2.3.0

# やり方
- 大きく分けて2パターンのやり方が用意されている
  - ボイスや効果音、短い音楽を流す場合
  - 音楽を聞かせる場合

## ボイスや効果音、短い音楽を流す場合
- SSML の audio タグを使う

### audio タグ
- MP3の要件が決まっていて、場合によっては変換ソフトを使う必要あり
- 要件により音質は低め

### MP3 の要件
- MP3には、ユーザーに固有な情報や、その他の機密情報が含まれていてはなりません。
- MP3は、有効なMP3ファイル（MPEGバージョン2）である必要があります。
- 240秒以内
- ビットレート：48 kbps
- サンプルレート：22050Hz、24000Hz、16000Hzのいずれか

---

- 用意したMP3のビットレートとサンプルレートが違っていたみたいなので、 Amazon が勧めてた [FFmpeg](https://www.ffmpeg.org/) という変換ソフトを使いました。
  - Windowsの場合：ダウンロードしたら zip を解凍して bin フォルダ内で（あるいは環境変数設定後）コマンドプロンプトを開き、以下のコマンドを実施

```
> ffmpeg -i <input-file> -ac 2 -codec:a libmp3lame -b:a 48k -ar 16000 <output-file.mp3>
```


### 実装
- handle の中身だけ記載
- MP3が要件を満たしてないと、Alexaコンソールからテストした時にエラーになります。

```
return handlerInput.responseBuilder
    .speak('<audio src="url" />')
    .getResponse();
```


## 音楽を聞かせる場合
- AudioPlayer ディレクティブを使う

### AudioPlayer ディレクティブ
- audio タグよりも長いMP3を再生できる
- 通常のオーティオプレイヤーのように、途中で再生を止めて、また再開させるというような操作が可能
- サポートされているオーディオファイルのフォーマットは、AAC/MP4、MP3、HLSなどです。ビットレート： 16kbps～384kbps
- これらは公式の `AudioPlayerインターフェースのリファレンス` からの情報ですが、 audio タグと違い、最大秒数やサンプルレートに関する記載は今の所ありませんでした。とりあえず audio タグの制限である240秒以上の再生が可能であることは確認済みです。

### 実装
- handle の中身だけ記載
- お試しで一曲流したいだけなら上記にURLを入れれば動きます。

```
return handlerInput.responseBuilder
    .addAudioPlayerPlayDirective('REPLACE_ALL', 'url', 'token', 0, null)
    .getResponse();
```

---


- `addAudioPlayerPlayDirective` のパラメータの詳細 （[リファレンス](https://ask-sdk-for-nodejs.readthedocs.io/en/latest/Building-Response.html#available-methods)より）

```
addAudioPlayerPlayDirective(
  playBehavior: interfaces.audioplayer.PlayBehavior,
  url: string,
  token: string,
  offsetInMilliseconds: number,
  expectedPreviousToken?: string,
  audioItemMetadata? : AudioItemMetadata);
```

- 現時点でドキュメントがあまりに乏しすぎるので、 `addAudioPlayerPlayDirective` のパラメータ等に関しては詳しく知るには[クラスメソッドさんの記事](https://dev.classmethod.jp/cloud/alexa-sdk-v2-eighth/)がベストだと思います。
- `addAudioPlayerPlayDirective` の他にも AudioPlayer 関連メソッドがありますが、ここでは割愛します。

# おわり
- 今回はちょっとした音声ファイルが対象だったので、1つ目の方法である `audio タグ` を使って実装しました。
擬似ボタンの実装

#はじめに
　学校の制作を進める中で意外と多くの人から質問を受けたのでDXライブラリで疑似的にボタンを作ってみようと思います。

#処理の流れ
　まず前提として無限ループの中でキー判定を行います。わからない方は[キャラクターの移動(キー入力判定の作成)](https://qiita.com/Daisuke8251/items/f6241737f694800a7461#%E3%82%AD%E3%83%BC%E5%85%A5%E5%8A%9B%E5%88%A4%E5%AE%9A%E3%81%AE%E4%BD%9C%E6%88%90)を見てもらえればと思います。

　　　①左クリックの判定
　　　　　↓
　　　②マウスカーソルの位置を取得
　　　　　↓
　　　③画像との当たり判定

　この3ステップで処理を作っていきます。

#①左クリックの判定
　前回は`CheckHitKey()`で入力判定を行ったと思いますが、マウスの場合は`GetMouseInput()`という関数を使って入力判定を行います。

```C
  if (GetMouseInput() & MOUSE_INPUT_LEFT)
```
　ここで見落としがちなのですが、&&ではなく***&***を使っています。つまり論理積によって入力されたキーを判定しています。まぁだからどうしたというところなんですが間違えると動かないので一応。

#②マウスカーソルの位置を取得
　クリックしただけではボタンを押したのかどうか判定できませんのでカーソルの位置を取得する必要があります。ループ内で取得しておいてもいいのですがクリックしたとき以外はカーソル位置を使いませんのでクリックした後で取得するようにします。

```C
	int mouseX, mouseY;
	GetMousePoint(&mouseX, &mouseY);		// カーソルの位置を取得
```
　2つの変数に値を格納必要があるので2つのint型変数のアドレスを渡しています。これで`mouseX`と`mouseY`にそれぞれカーソルのX座標とY座標が格納されます。

#③画像との当たり判定
　ここまででマウスをクリックしたときにカーソルの位置を取得することができました。あとは画像の上でクリックしたかどうかを判定することでボタンのように見せることができます。

```C
const int posX = 220;  // 画像のX座標
const int posY = 190;  // 画像のY座標

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	SetWindowSize(640, 480);
	SetBackgroundColor(255, 255, 255);

	if (DxLib_Init() == -1)
		return 0;

	SetDrawScreen(DX_SCREEN_BACK);

	// 画像読み込みとサイズ取得
	int picX, picY;
	int picImage = LoadGraph("button.png");
	GetGraphSize(picImage, &picX, &picY);			// 画像サイズ取得

	DrawGraph(posX, posY, picImage, FALSE);
	ScreenFlip();
```
　このようにconst変数を使って画像を描画し、画像サイズを変数に読み込んでおくことで当たり判定が非常にやりやすくなりますし、変更も容易になるので少し脱線して紹介しておきます。

　あとは先ほどまでに使ってきたものを組み合わせるだけですが、当たり判定について確認しておきます。
　`posX <= mouseX < (posX + picX)`かつ`posY <= mouseY < (posY + picY)`でマウスカーソルが画像上にあることを表現できます。ただ、２つの条件式をつなげることはできないので`&&(AND演算子)`でそれぞれを結合して表現します。

```C++
#include "DxLib.h"

const int posX = 220;  // 画像のX座標
const int posY = 190;  // 画像のY座標

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	SetWindowSize(640, 480);
	SetBackgroundColor(255, 255, 255);

	if (DxLib_Init() == -1)
		return 0;

	SetDrawScreen(DX_SCREEN_BACK);

	// 画像読み込みとサイズ取得
	int picX, picY;
	int picImage = LoadGraph("button.png");
	GetGraphSize(picImage, &picX, &picY);           // 画像サイズ取得

	DrawGraph(posX, posY, picImage, FALSE);
	ScreenFlip();

	while (!ProcessMessage()) {
		if (GetMouseInput() & MOUSE_INPUT_LEFT) {
			int mouseX, mouseY;
			GetMousePoint(&mouseX, &mouseY);        // カーソルの位置を取得

			if (mouseX >= posX && mouseX < (posX + picX) && mouseY >= posY && mouseY < (posY + picY)) {
				break;
			}
		}
	}

	return 0;
}
```
　このプログラムでは表示されたボタンをクリックするとループから外れて終了します。
通常は`break;`の部分を処理や関数呼び出しに置き換えることでボタンのような実装を行っています。

#ちょっとした小技
　素材がうまく作れなかったのでソースは貼りませんが、クリックした感を出したければ

　1. `break;`をクリック後画像への張り替え処理と待ち処理に置き換える。
　2. それから処理に移る。
　
　これであたかもクリックしてから処理が行われたかのように見せられます。実際にはただのアニメーションを挟んだだけですがユーザーが**クリックした**と認識することで「当たり判定とアニメーション」から**「ボタン」**になります。

#最後に
　少し手抜きをした点はありますが、ボタンってこんな感じでも作れるんだと軽く考えてもらえればいいかと思います。`CreateWindow関数`を使わなくてもボタン"のようなもの"は作れるので初めてGUIのゲームを作成する際などはこちらのほうが触れ合いやすくいいかと思います。
Windows MatlabのMexでOpenBlasを使う

研究でC++とcBlasで書いていたコードをMatlab上でMexファイルとして呼び出せるようにする必要があり、

- OpenBLASのインストール
- Mexでcblasを呼びだす

についてまとめました。
特にOpenBLASのソースからのビルドはめんどくさかったので忘備録として残しておきます。

ちなみに、MexコンパイラはVisual Studio 2017を使用しています。
OSはWindows 10です。

#OpenBLASのインストール

cmakeを使ってOpenBlasをMake & Installします。
cmakeはMiniconda環境でインストール&実行しました。
主に[公式](https://www.openblas.net/)のドキュメントに従って行います。

### Minicondaをインストール
[公式サイト](https://conda.io/miniconda.html)からMinicondaをインストールします。

### Anaconda Promptで以下を実行

```
conda update -n base conda
conda config --add channels conda-forge
```

### Condaで以下をインストール
Fortranコンパイラではflangを使用します。

```  
conda install -y cmake flang clangdev perl libflang　git
conda install -y -c isuruf kitware-ninja
```


### バッチファイルを端末上で実行
Visual Studio 2017の場合以下の場所にバッチファイルがあるので、プロンプト上で実行します。

```
/c/Program\ Files\ \(x86\)/Microsoft\ Visual\Studio/2017/Community/VC/Auxiliary/Build/vcvars64.bat
```

### 環境変数を通す

```
set "LIB=%CONDA_INSTALL_LOCN%\Library\lib;%LIB%"
set "CPATH=%CONDA_INSTALL_LOCN%\Library\include;%CPATH%
```

### 公式からOpenBLASをgit clone

```
git clone https://github.com/xianyi/OpenBLAS.git 
```

### buildディレクトリを作成

```
cd　OpenBLAS/
mkdir build
cd build/
```

### Cmake

```
cmake ../ -G "Ninja" ^
    -DCMAKE_C_COMPILER=clang-cl ^
    -DCMAKE_Fortran_COMPILER=flang ^
    -DBUILD_WITHOUT_LAPACK=yes ^
    -DNOFORTRAN=0 -DDYNAMIC_ARCH=OFF ^
    -DCMAKE_INSTALL_PREFIX="C:\tools\OpenBLAS" ^
    -DCMAKE_BUILD_TYPE=Release
``` 

### Cmake build and install

```
cmake --build . --config Release --target install
```

# Mexでのコンパイル
以下ようにオプションをつけてコンパイルします。

### Mexでのコンパイル
`PATH_TO_OPENBLAS`はOpenBLASをインストールしたディレクトリのトップです。
インクルードライブラリの指定は`-IPATH_TO_OPENBLAS\OpenBLAS\include\openblas`のように指定しますが-`I`とパスの間にスペースは入れないで実行します。

  
```
mex -R2018a filename.cpp PATH_TO_OPENBLAS\OpenBLAS\lib\openblas.lib '-IPATH_TO_OPENBLAS\OpenBLAS\include\openblas' COMPFLAGS="/openmp /O2 $COMPFLAGS"  -v
```

`-v`はコンパイルの詳細表示です。
また`COMPFLAGS="/openmp /O2 $COMPFLAGS"`はVisual Studio CompilerへのコンパイルオプションでOpenMPと最適化オプションO2をつけてコンパイルしています。

### 実行時について
 コンパイル済みMexファイルと同じディレクトリ内に
  `PATH_TO_OPENBLAS\OpenBLAS\bin\openblas.dll`
  を配置して実行します。

Matlab2018で作成したMexファイルはMatlab2018以前では実行できないので注意が必要です。


# まとめ
以上適当にまとめたので間違いなど多いと思いますが勘弁してください。
もともとのプログラムはUbuntu + clangで実行していましたが、それよりは遅くなってしまいました。SSE命令やAVX命令を使えば[もっと早くなるらしい](https://qiita.com/mucunwuxian/items/55ec8e98cf6401bd60dc)ですがやる気が起きない。

#参考

・公式ドキュメント
https://github.com/xianyi/OpenBLAS/wiki/How-to-use-OpenBLAS-in-Microsoft-Visual-Studio
・インストールについて
https://www.kunihikokaneko.com/dblab/toolchain/openblas.html
・Ninjaのエラー
https://github.com/xianyi/OpenBLAS/issues/1424
SassをGulp4で監視して自動コンパイルする

Gulpを弄るに先立っていろいろ検索して、例文をそのままコピペしても、正常に動かない場合が多いです。その理由として、Gulp4ではそれ以前と異なる構文があるからです。なので、実際僕が試行錯誤して生み出したGulp4で動く、『Sassファイルの変更を監視して、変更があれば .css と .min.css を生成するgulpfile.js』をここに置いておこうと思います。

```shell
// 実行環境
gulp -v
CLI version 2.0.1
Local version 4.0.0
```

##Sassファイルの変更を監視して、変更があれば .css と .min.css を生成する gulpfile.js

```gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var notify = require('gulp-notify');
var rename = require('gulp-rename');
var cleanCSS = require('gulp-clean-css');

// Sassをコンパイルするタスクの設定
gulp.task("css", function () {
    return gulp.src('node_modules/bootstrap/scss/*.scss')// コンパイル対象のSassファイル
            .pipe(sass()) // コンパイル実行
            .pipe(autoprefixer()) // ベンダープレフィックスの付与
            .pipe(gulp.dest('node_modules/bootstrap/dist/css')); // 出力
});

// .min.cssを生成するタスクの設定
gulp.task("mincss", function () {
    return gulp.src('node_modules/bootstrap/dist/css/bootstrap.css')//上のタスクで出力したcssファイル
            .pipe(cleanCSS()) // cssを圧縮
            .pipe(rename({extname:'.min.css'})) // 名前を.min.cssにする
            .pipe(gulp.dest('node_modules/bootstrap/dist/css')) // 出力
            .pipe(notify({
                title: 'bootstrap.cssとbootstrap.min.cssをコンパイルしました。',
                message: new Date(),
                sound: 'Pop',
                icon: 'icon.png' // 適当なアイコンを追加してみてください
            }));
});

gulp.task("default", function () {
    // scssフォルダを監視し、変更があったらコンパイルする
    gulp.watch('node_modules/bootstrap/scss/*.scss',gulp.series('css', 'mincss'));
});
```
それぞれのプラグインは事前にインストールしておいてください。

```shell
$ npm install --save-dev gulp-sass
$ npm install --save-dev gulp-autoprefixer
$ npm install --save-dev gulp-notify
$ npm install --save-dev gulp-rename
$ npm install --save-dev gulp-clean-css
```
Gulpのインストール等は以下の記事をご参照ください。
・[Bootstrap 4のCSSコンパイルをGulpで管理する方法](https://qiita.com/tonkotsuboy_com/items/564f9bb78d177483f83e)

この記事がお役に立てれば幸いです。ご指摘等はお気軽にお願いします。
Docker を Linux 以外で使うことは幸せにならない

## Docker Toolbox

[VirtualBox](https://www.virtualbox.org/) 上で動かす...

- VirtualBox は同期フォルダのIOが遅いで有名
    - [Vagrantプロバイダの共有フォルダ性能比較 - なんたらノート第三期ベータ](http://tanakahisateru.hatenablog.jp/entry/2017/03/13/151128)
- Guest Additions めんどい
- ネットワークアダプタが不安定
- わざわざ vagrant のようなラッパーを使わざるをえないことも
    - その vagrant も中々思うように動いてくれない

## Docker for mac

[Hypervisor.framework](https://developer.apple.com/library/mac/documentation/DriversKernelHardware/Reference/Hypervisor/index.html) 上で動かす... 

[High CPU Utilization of Hyperkit in Mac · Issue #1759 · docker/for-mac](https://github.com/docker/for-mac/issues/1759)
[File access in mounted volumes extremely slow · Issue #77 · docker/for-mac](https://github.com/docker/for-mac/issues/77)

## Docker for Windows

[Hyper-V](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/about/) 上で動かす...

- Samba IO やっぱり遅い
    - [Shared Volumes Slow · Issue #188 · docker/for-win](https://github.com/docker/for-win/issues/188)
- NAT の調子が悪くなることがあるという話


---

Docker は Linux Kernel の機能を利用して動く性質上、他の OS では仮想環境なしに動かすことが出来ないものとなっています。

仮想環境にありがちな CPU Time, IO, Network 周りの問題をそのまま引っ張ってくるので、使っていて「 `VirtualBox + vagrant` 生活より良くなった！」と思うこともあれば、そうでないことも多いです。特に「普通に動かす分には動くけど、たまにおかしくなる」という一番やっかいな奴です(`npm install` などが遅いのはそれとして)。

1. Docker を利用する場合
2. 手動で仮想環境なり AWS なりに Linux(Ubuntu がいいでしょう) を立ち上げる
3. そこにネイティブ Docker をインストール
4. ファイルを同期したい場合は `rsync` を使う

がベストなんじゃないかなと。あと Docker 使いたいならホスト OS を Linux にしましょう。 Web エンジニアであればブラウザと IDE さえ動けばほとんど事足りるはずです。
ラズベリーパイでpython3.7を入れ。プログラムを動かす方法

初心者なのですが、ラズベリーパイにpython3.7をインストールしてカメラを起動させようとしてるのですが、どのサイトを参考にしてもmoduleがみつからないとなりうまくいきません。

ラズベリーパイの場合はすでに入ってる古いバージョンでないといけないなどあるのでしょうか、もしくはmoduleのインストール場所がおかしいのでしょうか
Twitterの初期プロトタイプと2019年版年版を見比べて感慨に浸ってみるテスト

Twitterの初期プロトタイプと2019年版年版を見比べて感慨に浸ってみるテスト

![image](https://user-images.githubusercontent.com/13635059/51232537-6e77f200-19aa-11e9-81fd-7729e0b3e99a.png)

![image](https://user-images.githubusercontent.com/13635059/51232611-b72fab00-19aa-11e9-835e-44891569677f.png)


[Twitterの140文字制限の由来はSMS？意外な理由が話題に | 秒刊SUNDAY](https://yukawanet.com/archives/4261947.html)
---

https://twitter.com/YumaInaura

https://github.com/YumaInaura/YumaInaura/issues








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Laravel初心者のためのエラー対応履歴

# DBへのタイムスタンプに値を設定するときの注意点
created_at に '1970-01-01 00:00:01' を設定しようとすると、
Incorrect datetime value: '1970-01-01 00:00:01' for column 'created_at' のエラーが発生した。
調査の結果、UTCを考慮した　'1970-01-01 09:00:01'　であれば解決した。

最低値がまた変動する可能性を考えて、今後は下記がよさげ。
Carbon::createFromTimestamp(1)->toDateTimeString();
[Android] zxingでQRコードを読み取る時に画面が横回転しないようにする

# 画面が横になる・・・
AndroidでQRコードを読み取るとき，`zxing-android-embedded`というライブラリを使うことがあるかと思います．

しかし問題なのが，もともとバーコード用のライブラリのためリファレンス通りの使い方ではカメラが横回転(ランドスケープモード)してしまいます．QRコードだけなら，縦のまま読み取りたいですね．

一見Activityの`android:screenOrientation`を`portrait`にするだけかと思いきや，裏で別のActivityを呼び出しているようで，これだけでは治りません．ということで，縦にしましょう．

たぶん２分くらいで終わります．

<img src=https://qiita-image-store.s3.amazonaws.com/0/181933/a03e7eb0-a0e2-fa45-82e3-f4a41350855e.png width=65%>
（こんなかんじ．つらい．）

### 依存関係
gradleに書いてない方は，書いてから始めましょう．

```build.gradle
dependencies {
    ...
    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
}
```


# CaptureActivityを継承したActivityをつくる
zxingを導入すると，`com.journeyapps.barcodescanner.CaptureActivity`たるActivityが存在することがわかります．`IntentIntegrator`の中を見ていると，この`CaptureActivity`がどうやらデフォルトで使用されているようです．ということで，これを継承したActivityを宣言しましょう．中身は空で構いません．

適当に好きなファイルに宣言してもいいですし，新しくこれ専用のファイルを作ってあげてもいいです．

```kotlin:MyCaptureActivity.kt
class MyCaptureActivity : CaptureActivity()
```

# AndroidManifestを編集する
新しくActivityを作ったので，manifestファイルに記述します．

`android:name`以外は記述しなくても縦画面になりましたが，一応書いておくと安心ですね．

```AndroidManifest.xml
<application>
    ...
    <activity
        android:name=".MyCaptureActivity"             
        android:screenOrientation="portrait"
        android:stateNotNeeded="true"
        android:theme="@style/zxing_CaptureTheme"
        android:windowSoftInputMode="stateAlwaysHidden">
    </activity>
</application>
```

# IntentIntegratorのcaptureActivityにセットする
最後に適用して終わりです．
QRコードカメラのintentを発行するときは`IntentIntegrator`を使うと思いますが，生成したインスタンスの`captureActivity`に先ほど宣言したクラスを割り当ててあげれば，画面が縦になります．

Activityから呼び出す場合とFragmentから呼び出す場合で，若干書き方が違います．

- Activityの場合

```MainActivity.kt

    val intentIntegrator = IntentIntegrator(this).apply {
        setPrompt("Scan a QR code")
        captureActivity = MyCaptureActivity::class.java
    }
    intentIntegrator.initiateScan()
```

- Fragmentの場合

```MyFragment.kt
    val intentIntegrator = IntentIntegrator.forSupportFragment(this).apply {
        setPrompt("Scan a QR code")
        captureActivity = MyCaptureActivity::class.java
    }
    intentIntegrator.initiateScan()
```


# 結果

<img src=https://qiita-image-store.s3.amazonaws.com/0/181933/a03e7eb0-a0e2-fa45-82e3-f4a41350855e.png width=75%>

こうだったのが

<img src=https://qiita-image-store.s3.amazonaws.com/0/181933/e476d385-3a12-4cab-58ac-8125dd90415a.png width=45%>

こうなりました！


# おわりに
けっこう過去に議論されていた問題みたいで，公式レポジトリのIssueやStackOverflowには情報がありましたが，日本語にはなっていないみたいですね．

> [setScreenOrientation() property for IntentIntegrator #16](https://github.com/journeyapps/zxing-android-embedded/issues/16)

> [Change QR Scanner orientation with ZXING in Android Studio](https://stackoverflow.com/questions/34983201/change-qr-scanner-orientation-with-zxing-in-android-studio)

以上です，ありがとうございました．
AWSのルートテーブルって何よ？VPCとサブネット踏まえて簡単に説明してみる

# ルートテーブルを理解するにはVPCとサブネットは理解必須

### VPCとは？
AWS上に作るプライベートな（仮想的な）ネットワーク環境のことです。このネットワーク配下でAWSの様々なリソースを管理することで、ハイセキュリティな通信の交通整理をしやすくします。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html

### パブリックサブネットとは？
外部のインターネットと直接通信できるサブネットのこと。

### プライベートサブネットとは？

VPC内部及び、VPNやDirectConnectを通じて接続しオンプレ環境等とプライベートな通信をするサブネット。（外部のインターネットとは直接通信できない）
(引用元: http://blog.serverworks.co.jp/tech/2013/05/23/vpc_beginner-2/)


実際のパブリックサブネットとプライベートサブネットがわかりやすく解説されているページはこちら
( https://go-journey.club/archives/8135 )

# 本題のAWSのルートテーブルとは？

AWSのルートテーブルとは
http://awsinfra.site/2018/05/29/post-236/

だいたいの記事に主語がないので補足すると、AWSのルートテーブルは、
サブネット内にあるインスタンス等がどこに通信にいくかのルールを定めたものです。つまり、ルートテーブルはパケットの宛先(IPアドレス)を見て、どこに通信を流すかが書かれている表です。この表をみてパケットを運ぶので、表にない宛先のものはパケットを送らないので、通信できません。サブネット毎にどこに通信ができるかを定めたものだというところがポイントです。
Archlinuxで、Notoフォント、Noto CJKフォントを使う

- Notoは、一般的なユニコード文字と記号が含まれています。
- Noto CJKは、Notoフォントの仲間で、Notoフォントに含まれていないアジア圏の漢字フォントです。
- Noto Emojiは、絵文字フォントです。Androidスマートフォンで表示される絵文字フォントになっています。

以上の3つを使うことで、英数字も、漢字も、ひらがなも、絵文字も、綺麗に表示することができます。

# インストール

```
$ sudo pacman -S noto-fonts noto-fonts-cjk noto-fonts-emoji
```
(もし、太細や大小、狭広バージョンも必要なのであれば、`noto-fonts-extra`もインストールしてください。)

# 設定

```
$ cd /etc/fonts/conf.d 
$ sudo ln -s ../conf.avail/66-noto-sans.conf .
$ sudo ln -s ../conf.avail/66-noto-serif.conf .
$ sudo ln -s ../conf.avail/66-noto-mono.conf .
$ sudo ln -s ../conf.avail/70-noto-cjk.conf .
```

> root権限がないのであれば、`~/.config/fontconfig/conf.d`を作り、その中から`/etc/fonts/conf.avail`内からシンボリックリンクを貼ったり、オリジナルのファイルを入れても大丈夫です。

# 絵文字の設定

@TsutomuNakamura さんの記事を参考にしました。
https://qiita.com/TsutomuNakamura/items/f48b9ed690cfc008acd2
「Hello ,glfw」glfwでのwindowの作成方法

GLFWライブラリーを使ってwindowを作成する。

##準備
windowsPCとvisual Studio 2017を使う場合は、こちらの記事をご覧ください。

[glfw の導入(windows VisualStudio 2017)](https://qiita.com/tositada_nakada/items/1528c7dad40f33b5e31b)

#glfwの初期化

glfwを使うには、最初に初期化する必要があります。

```cpp
int main(){
    glfwInit();
}
```
## windowを作成する

こちらがソースコードになります。

```cpp

//#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

GLFWwindow *window;
int main() {
	glfwInit();
	glfwWindowHint( GLFW_CLIENT_API, GLFW_NO_API );
	window = glfwCreateWindow(300,400, "vukan tutorial",nullptr,nullptr );

	while (!glfwWindowShouldClose(window));
	{
		glfwPollEvents();
	}
}
```

windowを作成するには、glfwCreateWindowを使います。
glfwCreateWindowの引数は、先頭から「ウィンドウの高さ」「ウィンドウの幅」「ウィンドウの名前です。」
4つめは、フルスクリーンにするときの引数。5つめは、別ウィンドウと描写を共有するときの設定です。今回は、使わないので、nullptr,またはNULLと入れておきます。

このglfwCreateWindowはGLFWwindow windowのポインターを返します。

##オプションの設定

glfwWindowHintにはオプションを設定します。今回は、ウィンドウサイズの変更機能を禁止してみました。


## 連絡先

tweeter: [tositada_nakada](https://twitter.com/nakadasanda17)
mail: nakadasanda@outlook.com

## 寄付

paypal: [tositada_nakada](https://www.paypal.me/nakadasanda)
Amazon:[欲しいものリスト](http://amzn.asia/fGpGuJo)
Spring'19：Einstein Analytics 新機能ピックアップ

Spring'19 のリリースノートを斜め読みしたので、
Einstein Analytics で即使うことになるであろう機能をピックアップしてみる。
見出しはリリースノートへのリンク。画像は引用。
## [棒、折れ線、および積み上げを使用した複合グラフのカスタマイズ](https://releasenotes.docs.salesforce.com/ja-jp/spring19/release-notes/bi_combo_charts_bars_lines_stacks.htm)
![bi_combo_chart_bars_and_lines_stacked.png](https://qiita-image-store.s3.amazonaws.com/0/153488/67807c85-ddbf-942b-1e26-bc75ffbe5d62.png)
コンボグラフ(複合グラフ)のカスタマイズ領域が増えた。
Y軸の値の積み重ねができるようになった。また、X・Y軸の項目の設定が実用的になった。

ちなみに、Winter'19 までのよくあるコンボグラフはこちら。
![Combo.png](https://qiita-image-store.s3.amazonaws.com/0/153488/6e142fc7-2808-1e37-d598-98e868296b1d.png)
MSOffice製品の素晴らしい表に慣れている人にはちょっと物足りなかったのが改善された。
## [接続の作成時のテスト](https://releasenotes.docs.salesforce.com/ja-jp/spring19/release-notes/rn_bi_integrate_connectors_test.htm)
コネクタでの接続設定時に、テストができるようになった。
![bi_integrate_connectors_test.png](https://qiita-image-store.s3.amazonaws.com/0/153488/72bc8393-1122-dc18-0ee3-79952214bdbc.png)
[S3コネクタ(Winter'19)](https://qiita.com/ipex/items/5f2e1e404f16a3c9151e) の時に欲しかった...
## [他のダッシュボードのページへのリンク](https://releasenotes.docs.salesforce.com/ja-jp/spring19/release-notes/bi_link_to_pages_in_other_dashboards.htm?edition=&impact=)

別のダッシュボードへのリンクコンポーネントに、ページの指定も併せてできるようになった。

- ダッシュボード1
    - ページ1
    - ページ2
- ダッシュボード2
    - ページ1
    - ページ2

1-2 から 2-2 に移動できるようになった。マリオのワープみたいなことができる。
ダッシュボードをコンポーネント化していけるので、デザイン次第でより直感的な操作や読み込み速度の改善に繋げられる。
git push origin masterでremote: Repository not found. fatal: repository 'https://github.com/MyRepo/project.git/' not found

```
$ git push heroku master

remote: Repository not found.
fatal: repository 'https://github.com/MyRepo/project.git/' not found
```

エラーです。。

```
$ git credential-manager uninstall

$ git credential-manager install
```

これでOK
pandas速度検証①(dfリスト追加編)

こんにちは。
pandasのDataFrameにデータを格納するとき

・1行ずつリストとして追加する方法と
・2次元リストを作ってからDataFrameを定義するのではどちらが早いのか検証しました。

結論から申し上げると、
2次元リストを作ってからのほうが圧倒的に早かったです。

##動機

pythonからsqlite3のデータを取り出す時、そのデータはジェネレータに格納されます。

つまり、1行ずつしか取り出せないのですが
どうやってdfに格納するのが早いのか気になったので検証しました。

##環境
win10
python3.7.1
jupyter labです

##実験コード

データをsqlite3から引っ張ってくるコード

```python:import_data.py
%%time
import sqlite3
import pandas as pd

conn=sqlite3.connect('1227conserva.db',isolation_level=None)
c=conn.cursor()
sup_datas=c.execute('''
select
--必要な列の抽出
category.user_id,user_name,category.pd_name,category.rv_title,anti,\
category1,category2,category3,category4,category5,star

from category
inner join conserva_review
on
category.pd_url=conserva_review.rv_url
where category.category1='本' or category.category1='DVD';
''')

```
引っ張ってきたデータの大きさは
shape(3641,11)です。  



実験コード  

```python:1dimlist.py
df=pd.DataFrame(columns=['id','username','pd_name','rv_title','anti',\
'category1','category2','category3','category4','category5','star'])

for i,sup_data in enumerate(sup_datas):
    df.loc[i]=list(sup_data)
```
結果:Wall time: 10.1 s





```python:2dimlist.py
data_list=[]
for i,sup_data in enumerate(sup_datas):
    data_list.append((sup_data))


df=pd.DataFrame(data_list,columns=['id','username','pd_name','rv_title','anti',\
'category1','category2','category3','category4','category5','star'])
```

結果:Wall time: 771 ms


##考察？
参照・代入の回数が少ないからはやいのかな？
IBM Cloudのサービスの稼働状況を確認する方法 (2019年1月現在)

皆さん、こんにちは。戸倉彩です。

IBMが提供しているパブリッククラウドサービス **「IBM Cloud」** のサービス稼働状況を確認できるサイトをご紹介いたします。IBM Cloudを利用されている方は、サイトがいくつかありますのでブックマークしておくと役立ちます。

# 1. IBM Cloudアカウントを所有している場合
## その1 - 「IBM Cloud状況」サイト(旧)へアクセスする
[https://console.bluemix.net/status](https://console.bluemix.net/status) 
オフィシャルの [「ご利用中のよくあるご質問」](https://www.ibm.com/cloud-computing/jp/ja/cloud-jp-faq/customers/) サイトでも紹介されているサイトです。
<img src="https://54m4gg.by.files.1drv.com/y4mjLFPoOL03pe3syYnVf57Z9f2buJ7ywYzJLasPFmpLolUcXhwZou7gWXBAWNOTf2simAY2xQtaA5o2F53gFs1-riEwWM9mJlrz-xbyJnUggjYGgdMdRsSnStzTtHeyly0ihbdH89OAKb89zsbXmMNKiSJy80R_Gm5yWkUjaciYhlFF_6MwCwoVSXf1VDyMyEUOqcyYHQPgS3l4wJa_QdPmg?width=1862&height=1228&cropmode=none" width="600">

## その2 - IBM Cloudダッシュボード(新)へアクセスする
[https://cloud.ibm.com/](https://cloud.ibm.com/)
新しくなったIBM Cloud ダッシュボードサイト上の「ロケーション状況」からエリア単位で稼働状況がアイコンの色で分かりやすく表示されます。「東京」は「アジア太平洋」に含まれます。  
より詳しい状況を確認したい場合は、右上の **「状況の表示」** リンクをクリックします。  
* アジア太平洋
* ヨーロッパ
* 北アメリカ
* 南米
<img src="https://54m3gg.by.files.1drv.com/y4miRRa6WmqQVadYyFt0djHjfi5fIi4iAbWQCREOvbGhhTghE8S2Gb8chgYw19BnwK1oTIQ5i3enQAVCeiIc5fkJ9Ij5ZhxLrxYVt-X013RCJnsEhymsnZlVh70aKhsO7-MdwT13Cc3XvgMhyHi8BMx4m2VW-0HC8pkHIp6JMhT3YqlaikNXcgmUTnw5wYU8FCYvdYw47AwFZzZ6Bm8UWcgaA?width=2228&height=1152&cropmode=none" width="600">

# 2. IBM Cloudアカウントを所有していない場合
## IBM Cloud(新)の「状況の表示」サイトへアクセスする
[https://cloud.ibm.com/status](https://cloud.ibm.com/status)
東京を含めた各地域ごとにIBM Cloudのサービス稼働状況が表示できます。
<img src="https://54m5gg.by.files.1drv.com/y4mz6AWP481AuCuBSblGDyYgUsC2df8oYTtcfOS-gNae4v9SePBYDGQ5tF9sJ22LhbwVZHtDYJoNWjAdS7dcGVsjYx7FWcr_lXXzVlivkomNERyYowz_o4IdFPK_jUrdIzYZkDjwTZ0aJsKCDklSaCQZSd1bjbHNDEKMzdwaAy6Y892siMwuWY2cHPOFgJYkNwwGF-VZE0X56fJ_Kq5XQPQIQ?width=1950&height=1246&cropmode=none" width="600">

Have a nice Geek Life♪　　
※Twitterで最新情報配信中 [@ayatokura](https://twitter.com/ayatokura)
Java暗号化と復号化PDF 

この文章は、JavaプログラムでPDF文書の保護を設定する方法を紹介する。私たちは、ドキュメントを参照するためのパスワードを表示することができます。すなわち、このパスワードを介してドキュメントを読むだけで、編集できない、ドキュメントの編集権限のパスワードを設定することができます。

使用ツール: [Free Spire.PDF for Java V2.0.0](https://www.e-iceblue.com/Download/pdf-for-java-free.html)

【例1】PDFドキュメントを暗号化する

```
import java.util.EnumSet;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.security.PdfEncryptionKeySize;
import com.spire.pdf.security.PdfPermissionsFlags;

public class EncryptPDF {
    public static void main(String[] args) {
        //作成するPdfDocument実例
        PdfDocument doc = new PdfDocument();
        // PDFファイルをロードする
        doc.loadFromFile("sample.pdf");

        // PDFファイルを暗号化する
        PdfEncryptionKeySize keySize = PdfEncryptionKeySize.Key_128_Bit;
        
        //ドキュメントを開くときは、ドキュメントを見るだけです。
        String openPassword = "123456";

        //ドキュメントを開いた場合、ドキュメントを編集することができます。
        String permissionPassword = "test"; 
        EnumSet flags = EnumSet.of(PdfPermissionsFlags.Print, PdfPermissionsFlags.Fill_Fields);
        doc.getSecurity().encrypt(openPassword, permissionPassword, flags, keySize);

        //ファイルを保存する
        doc.saveToFile("Encrypt.pdf");
        doc.close();             
    }
}
```
コードを完了した後、プログラムを実行し、ドキュメントを生成する。ドキュメントを開く場合、パスワードを入力して、ドキュメントの暗号化の具体的な状況を調べることができます。以下のように:

![Encrypted.png](https://qiita-image-store.s3.amazonaws.com/0/278784/259efef5-234d-3776-e9d2-f209b9a934be.png)

【例2】PDFパスワードの保護を解除

```
import com.spire.pdf.PdfDocument;
import com.spire.pdf.security.PdfEncryptionKeySize;
import com.spire.pdf.security.PdfPermissionsFlags;

public class DecryptPDF {

    public static void main(String[] args) throws Exception {
        
        //作成するPdfDocument実例
        PdfDocument doc = new PdfDocument();
        //パスワード保護のPDFファイルをロードする
        doc.loadFromFile("Encrypt.pdf", "123456");

        //ドキュメント中のパスワードの保護を解除する
        doc.getSecurity().encrypt("", "", PdfPermissionsFlags.getDefaultPermissions(), PdfEncryptionKeySize.Key_256_Bit, "test");
        
        //ファイルを保存する
        doc.saveToFile("Decrypt.pdf");
        doc.close();
    }
}
```
プログラムを実行した後、生成されたドキュメントは、もはやパスワードで保護されません.
Androidは電池残量が少ないとカメラを起動できないことがある（メーカーによって違うっぽい）

## 起きたこと

表題のとおり。
Camera2 APIをたたこうとすると`RuntimeException`が発生する機種がある。

## 原因

Camera APIの実装内でチェックして例外吐いてるっぽい。
バッテリー残量だけで判定されているようなので、充電中であってもお構いなし。

しかもこれAndroidの標準実装というわけではなく、メーカーによって実装が違うようで、エラーになるバッテリー残量がまちまち。

ええい、機種依存か。

ちょろっとインターネットを泳いでみた感じだと、

富士通のarrowsだったり
https://qiita.com/mfks17/items/ed23e7d783d5538beb19

Nokiaだったり
https://forum.xda-developers.com/showthread.php?t=1608186

Galaxyだったり
https://forums.androidcentral.com/samsung-galaxy-s3/190775-camera-app-disabled-low-battery.html

ふむむ。

## 対策

カメラ起動前に事前チェックしてあげた。

### 悩み（読み飛ばしてよい）

機種依存問題とはいえ、ほっとくとアプリごと落っこちちゃうので、何かしら対策しなくてはならない。

しかし困ったのが、これ`RuntimeException`なので、catchしてもバッテリーの問題かどうか区別がつかないこと。

一応ログを見るとエラーメッセージも設定されてるんだけど、
`camera low battery`
やら
`low battery disabled`
やら、やっぱりメーカーによって内容がまちまちなので、判断材料として使うのは微妙。
~~まぁそもそもエラーメッセージで判別すること自体アレなんだけど・・・~~

最終手段はcatchしてそのまま握りつぶしだけど、さすがにそれは気持ちが悪い。

というわけで、起きてからどうこうするのは厳しいので、事前にメッセージを出すのがユーザーには優しそう。

### やり方

Camera APIをたたく前に、BatteryManagerさんに問い合わせましょう。
むしろアプリ起動時でもいいかもしれない。

公式のドキュメントはこちら。
[バッテリー レベルと充電状態を監視する](https://developer.android.com/training/monitoring-device-state/battery-monitoring?hl=ja)

詳細は上のドキュメントのとおり。
リンク踏むのが手間な人のために、こっちにも少しサンプル書きます。
開発環境の都合でXamarinで書くけど、ほかの言語でも基本は一緒。

```c#:MainActivity.cs
    protected override void OnCreate(Bundle savedInstanceState)
    {

        // 中略

        float status = GetBatteryStatus();

        // 閾値は要件に合わせて
        // 下記は20%未満でエラーとしてる
        if (status < 0.2)
        {
            // 「バッテリー不足です」みたいなポップアップ表示するなどしてアプリ終了
        }

    }

    private float GetBatteryStatus()
    {
        // バッテリー情報を取得
        IntentFilter ifilter = new IntentFilter(Intent.ActionBatteryChanged);
        Intent batteryStatus = RegisterReceiver(null, ifilter);

        // レベルとスケールを取得して割り算したのがバッテリー残量の割合
        int level = batteryStatus.GetIntExtra(BatteryManager.ExtraLevel, -1);
        int scale = batteryStatus.GetIntExtra(BatteryManager.ExtraScale, -1);

        return (level / scale);
    }
```

BatteryManagerさんがセットしてくれる情報は、上記インテントからいつでも取得できるので、そこまで小難しい実装は不要。
他にもバッテリーに関するいろんな情報が取れるので詳細は先述の公式ドキュメント参照。
React (TypeScript): ベストプラクティス

# React Best Practices
[2017末時点での React Component 設計のベストプラクティス](https://qiita.com/mizchi/items/bcb1aef8d1f14f8d0b4a)を元に、
私の前の勤務先の開発チームで共有していたベストプラクティスの一覧です。改善案や他のベストプラクティスなどのフィードバックを頂けると幸いです。

### 1. Prettierを利用する。

```bash
npx prettier --write ＜ファイル＞
```

### 2. `React.createClass()` を使わない
Reactのv16からcore packageから削除されました。

### 3. `componentWillXXX()`を利用しない
Reactのv17でdeprecateされるので以下のlifecycleメソッドの利用を避けてください。

* componentWillMount()
* componentWillReceiveProps()
* componentWillUpdate()

[Legacy Lifecycle Methods](https://reactjs.org/docs/react-component.html#legacy-lifecycle-methods)

### 4. AJAXの呼び出しはcomponentDidMount() で行う
Axiosやwindow.fetch等でのAJAXの呼び出しはcomponentDidMount()で行なってください。 
[AJAX and APIs](https://reactjs.org/docs/faq-ajax.html)

### 5. 可能な限り、`React.FC` (Functional Component)を使う
ES6クラスやReact.createClassよりも[およそ45%パフォーマンスが良い。
[45% Faster React Functional Components, Now](https://medium.com/missive-app/45-faster-react-functional-components-now-3509a668e69f)

### 6. Class Componentを利用する際にはReact.PureComponentsを使う
propsが変わった場合のみ再レンダリングされるようになる。

### 7. 可能な限りクラスは継承しない
継承はせずに、propsに違う値を渡す。

### 8. 内部関数で子Componentをrenderしない
別Componentに切り出しましょう。

### 9. Propsに何も渡してないFunctional ComponentはReact.memoでラップしない。
Shallow Equalが実行される分だけ、React.FCよりも遅くなります。
[本当は怖いReact.memo](https://qiita.com/suzuesa/items/1bb3b1493ff526814f03)

### 10. テンプレート文字列を利用する。
可読性を上げるために、可能な限りテンプレート文字列を利用してください。

#### ES6以前の書き方

```typescript
const url = '/api/' + this.state.uri
```
#### 推奨される書き方

```typescript
const url = `/api/${this.state.uri}`
```

### 11. ES6 分割代入を利用する
JSXの可読性を上げるために、`render()`の中の`props`と`state`は分割代入してください。Functional Componentの場合は、`props`のみ分割代入してください。

#### Class Component

```jsx

public render() {
    const { header, body } = this.props
    const { value } = this.state
    return (
        <div>
           <h1>{header}</h1>
           <p>{body}</p>
           <input type="text" value={value} />
        </div>
    )
}
```
#### Functional Component

```jsx
export default SampleComponent: React.FC = props => {
    const { header, body, value } = props
    return (
        <div>
           <h1>{header}</h1>
           <p>{body}</p>
           <input type="text" value={value} />
        </div>
    )
 }
```
C#のFormの位置と寸法

![image.png](https://qiita-image-store.s3.amazonaws.com/0/264452/e0047ce4-1806-b4e7-2c8e-d726dbe714af.png)

**C#のフォームをピッタリ並べたい。でもスキマが開く。なぜだ!!**

***

FormのRectangle型のプロパティは5個くらいある。

用途によって使い分けるが、試しに2つの領域を書き重ねてみた。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/264452/720f1d12-e3c1-07c6-e675-d5afca6eeca8.png)

オレンジがDesktopBounds、ライムがDisplayRectangleをRectangleToScreenで移動したもの。

DesktopBoundsでは影のエフェクトも含む領域となり、これを使って並べると隙間が開く。
RectangleToScreen(DisplayRectangle)ではタイトルバーを含めることができず、これを使って並べると一部が重なってしまう。

***

```c#
static class MyExt
{
    public static Rectangle hoge(this Form form)
    {
        Rectangle a = form.DesktopBounds;
        Rectangle b = form.RectangleToScreen(form.DisplayRectangle);

        return (new Rectangle(b.X, a.Y, b.Width, b.Y - a.Y + b.Height));
    }
}
```

こういう感じの計算で、それっぽい矩形を得られる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/264452/4fc2897f-13cf-e63e-31cd-6ae003eb379e.png)

***

こんな感じのコードを書くと

```c#
Form a = new Form()
{
    Text = "a",
    StartPosition = FormStartPosition.Manual,
    Location = Location + new Size(this.hoge().Width, 0),
};
a.Show();

Form b = new Form()
{
    Text = "b",
    StartPosition = FormStartPosition.Manual,
    Location = a.Location + new Size(a.hoge().Width, 0),
};
b.Show();

Form c = new Form()
{
    Text = "c",
    StartPosition = FormStartPosition.Manual,
    Location = b.Location + new Size(b.hoge().Width, 0),
};
c.Show();

Form d = new Form()
{
    Text = "d",
    StartPosition = FormStartPosition.Manual,
    Location = a.Location + new Size(0, a.hoge().Height),
};
d.Show();

Form e = new Form()
{
    Text = "e",
    StartPosition = FormStartPosition.Manual,
    Location = d.Location + new Size(d.hoge().Width, 0),
};
e.Show();

Form f = new Form()
{
    Text = "f",
    StartPosition = FormStartPosition.Manual,
    Location = e.Location + new Size(e.hoge().Width, 0),
};
f.Show();
```

いい感じに並べられる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/264452/c2edee9d-ded6-438a-1905-318bd129058c.png)

ただ、影で立体感が出てしまうので、そのあたりは好みが分かれるかも。
あと無理に並べると、画面解像度が足りない場合に飛び出るので注意。
Nodeの正規表現で後読みができなかったとき

Nodeのバージョンが低く、正規表現の後読みを使用すると上記のエラーが発生してしまいました。

```js
let e = new RegExp('(?<!abc)123');

// こうすると以下のエラーが発生
// SyntaxError: Invalid regular expression: /(?<!abc)123/: Invalid group
```

肯定的後読みの場合、検索結果をどう使うかによるかもしれませんが、そのままabc123で検索すればいいと思います。
ただ否定的後読みの場合、なかなか対応が難しかったので、その際の対応を記載したいと思います。

#やりたかったこと
ファイルから文字列を1行ずつ読み出して、前方がある文字列ではない検索文字列があるかどうかをチェックしたかったのです。
(?<!abc)123
つまりは上記みたいに前方がabcではない123があるかどうか。

#どうやったか
否定的後読み対象の文字を置換してから検索しました！

```js
let t = text.replace(/abc123/g, '');
let result = t.match(/123/);
```

これでresultが取得できた場合、abcではない123があるかが判断しています。
N+1問題を実際に計測

#初めに
N+1問題なるものがあってsqlのクエリがたくさん実行されることによって速度が遅くなることのことらしい。

実際にどのくらい時間的な差があるのかrack-mini-profilerを使って検証してみた

#検証条件

検証した条件は

10件のuserが5件のblogを持っている状況と

1000件のuserが10件のblogを持っている状況

#速度計測

まず10件のuserがありそれぞれが5件のblogを持っている状況で

includesを使わない「（N+1）が実行されているとき」の速度

つかうコードはこんな感じ

```ruby 
def index
    @users = User.all
end 
```

```
time 377.2ms
time 428.8ms
time 353.1ms
```

![not_include_10user.png](https://qiita-image-store.s3.amazonaws.com/0/207921/f94eb7ea-a014-6fd6-cd56-c963f76ca105.png)



という感じ



クエリは12回実行されている


次にincludesを使った場合

```ruby 
  def index
    @users = User.all.includes(:blogs)
  end 
```

```
    time 459.5ms
    time 360.5ms
    time 376.5ms
```

![use_include_10user.png](https://qiita-image-store.s3.amazonaws.com/0/207921/08d02a16-d19d-1da9-9e70-b8170e8fb3c8.png)


正直あんま変わらない

でも恩恵を受けるのはデータの数が増えた場合だと思うので…


次に1000件のuserが10件のblogを持っている状況で

includesを使わない場合

```
    time 2406ms
    time 2320ms 
    time 2525.5ms
```


![not_include_1000users.png](https://qiita-image-store.s3.amazonaws.com/0/207921/baf0ed19-e083-160a-7a91-ed525aeb6fe8.png)

クエリが1002回実行されている。


次にincludesを使う場合

```
    time 700.2ms
    time 673.5ms
    time 775.5ms
```


![includes_1000_users.png](https://qiita-image-store.s3.amazonaws.com/0/207921/d7d27a90-bb2d-3397-e7c3-2013a563ec10.png)




だいぶ差が出た。

何の記事か忘れたけどページが表示されるまでに1秒以上かかるとユーザーは遅いと感じるらしいのでincludesを使わない場合はアウトですが

includesを使ったら1秒以内で表示されてるので良いですね



おわり:sunny:
yoloのハマった部分自分用まとめ

以下のyoloを使用する。
https://github.com/pjreddie/darknet

結構ハマったのでメモ。

[labelimg](https://github.com/tzutalin/labelImg)でアノテーション(画像の対象オブジェクトの矩形座標を割り出す)する。
lablimgでyoloに設定して、yolo用のtextファイルを生成する。

101.jpgというファイル名なら次のファイルが生成される。

```101.txt
1 0.899811 0.205313 0.172023 0.169375
0 0.734405 0.159062 0.158790 0.153125
0 0.181002 0.145937 0.072779 0.044375
0 0.322779 0.274375 0.097353 0.051250
0 0.412571 0.285313 0.091682 0.049375
1 0.397448 0.225938 0.067108 0.069375
1 0.449433 0.173125 0.067108 0.066250
1 0.222117 0.273438 0.103970 0.059375
0 0.562854 0.137187 0.114367 0.190625
```

![labelimg_ano (2).png](https://qiita-image-store.s3.amazonaws.com/0/33329/62287e28-f96d-e8a8-03bd-487e0fd569b8.png)

train.txtとtest.txtは画像のパスが書かれたファイル。

```例.txt
path_1
path_2
・・・
path_n
```

こいつとPathと同じ名前の矩形座標が書かれたファイルで対応を取っていると思われる。

train.txtを作るためのコードを書いてみた。
やっていることはカレントディレクトリの拡張子が.txtのファイルを抽出して拡張子の前の文字と同じ画像のパスをファイルにするだけ。

```zsh
python convert_yolo.py
```

```convert_yolo.py
import glob, os

if __name__=="__main__":
    text_list = [os.path.basename(r) for r in glob.glob('./*.txt')]
    text_array = []
    elements = []
    base_name = os.getcwd() 

    # 毎回新規で作成するために削除する
    if os.path.exists('train.txt'):
        os.remove('train.txt')    
    # train.txtを作成する
    for i, text_name in enumerate(text_list):
        if str(text_name) != "classes.txt":
            with open("train.txt", "a", encoding="utf-8") as f:
                if i != len(text_list)-1:
                    f.write((base_name + "/"+  text_list[i].split(".")[0] + ".jpg") + "\n")
                else:
                    # 最終行だったら改行を追加しない
                    f.write((base_name + "/"+  text_list[i].split(".")[0] + ".jpg"))
```





もしくは以下のコードで

```zsh
python convert_yolo.py /path/to/image_folder
```

```convert_yolo.py
import glob, os
import sys
import pathlib

if __name__=="__main__":
    path = sys.argv[1]
    abs_path = str(pathlib.Path(path).resolve())
    text_list = [os.path.basename(r) for r in glob.glob(abs_path + "/*.txt")]
    elements = []

    abs_path2 = str(pathlib.Path(path).resolve()) + "/train.txt"
    # 毎回新規で作成するために削除する
    if os.path.exists(abs_path2):
        os.remove(abs_path2)    
    # train.txtを作成する
    for i, text_name in enumerate(text_list):
        if str(text_name) != "classes.txt":
            with open(abs_path2, "a", encoding="utf-8") as f:
                if i != len(text_list)-1:
                    f.write((abs_path + "/"+  text_list[i].split(".")[0] + ".jpg") + "\n")
                else:
                    # 最終行だったら改行を追加しない
                    f.write((abs_path + "/"+  text_list[i].split(".")[0] + ".jpg"))
```
ES6の復習メモ

## find
```javascript
//こんなオブジェクトがあったとして
let users = [
    {name: 'jill'},
    {name: 'Alex'},
    {name: 'Bill'},
]

//Alexだけ探したい！みたいなとき従来のfor文だとこんな感じ
let user;
for(let i = 0; i < users.length; i++){
   if(users[i].name === 'Alex'){
     user = users[i];
     console.log(user)
  }
}
```
### findを使うとこうできる
```javascript

users.find((user) => {
  //retrnを忘れると動かないので注意
  return user.name === 'Alex';
})

//これがretrunされる
{name: "Alex"}
```

### findの応用例
```javascript
//投稿されたオブジェクトがあったとして
let posts = [
    {id: 1, title: 'New post'},
     {id: 2, title: 'Old post'},
]

//コメントが追加されたとする それをfindを使って見つける
let comment = { postId: 1, content: 'Create Post'};

//posts,commentを引き渡して以下の処理を実行する
function postForComment(posts, comment){
 //postsのオブジェクトの中で、post.idとcomment.postIdが一緒のものをretrunで返す
 return posts.find((post) =>{
	return post.id === comment.postId;
  })
}
//関数を実行すると
postForComment(posts, comment);

{id: 1, title: "New post"}が返ってくる
```

## filter
```javascript
//最初は古い書き方
let producets = [
 { name : 'cucmber', type: 'vegetable'},
 { name : 'banana', type: 'fruit'},
 { name : 'celery', type: 'vegetable'},
 { name : 'orange', type: 'fruit'},
]

let array = []

for(let i = 0; i < producets.length; i++){
 if(producets[i].type === 'fruit'){
  array.push(producets[i])
 }
}

//filterを使うと特定の物をフィルタリングできる
producets.filter((product) => {
 return product.type == 'fruit'
})
//これが返ってくる　0: {name: "banana", type: "fruit"}1: {name: "orange", type: "fruit"}length: 
```

### filter応用例
```javascript
//さらに応用のフィルタリング
let array = [
 { name : 'cucmber', type: 'vegetable', quantity: 0, price: 1},
 { name : 'banana', type: 'fruit', quantity: 10, price: 15},
 { name : 'celery', type: 'vegetable', quantity: 30, price: 13},
 { name : 'orange', type: 'fruit', quantity: 3, price: 5},
]
// typeが野菜で、quantityが0より大きく、priceが１０より小さいものでフィルタリング
array.filter((item)=> {
 return item.type === 'vegetable'
 && item.quantity > 0
 && item.price < 10
})

//既存のままだと野菜ではフィルタリングしても存在しないので、オブジェクトを以下のように変更するとちゃんとそれだけがフィルタリングされて値が返ってくる
 { name : 'celery', type: 'vegetable', quantity: 30, price: 9},

```

### filter活用場面的な
```javascript
//投稿された値がオブジェクトであって
let post = {id: 4, title: 'New post'};

//コメントのオブジェクトにpostIdとcontentが入っている
let comments = [
    {postId: 4, content: 'awsome post'},
    {postId: 3, content: 'it was ok'},
    {postId: 4, content: 'no!'},
]

//フィルタリングする用の関数を作って、紐づいているものを取得したいとする
function comentForPost(post, comments){
 //commentsのオブジェクトをフィルタリングして
 return comments.filter((comment)=> {
  //postIdと引数で渡されたpost.idに一致したものを返す
  return comment.postId === post.id;
 })
}
//実際に関数を実行してフィルタリングしてみると

comentForPost(post, comments)
//(2) [{…}, {…}]
//0: {postId: 4, content: "awsome post"}
//1: {postId: 4, content: "no!"}
//というように値をフィルタリングすることができる
```

#### filter問題
```javascript
//5０より大きいものだけをフィルタリングしなさい
let numbers = [15, 25, 35, 45, 55, 65, 75, 85, 95];

let filteredNumbers = numbers.filter((nums) => {
    return nums > 50
})
```
ローカル開発環境で学習を始める手順(macOS版)

今回はターミナルを起動してから、仮想マシン(vagrant)を使用した学習を再開するまでの手順を記していきます。
この記事ではmacOSで、ローカル開発環境でruby学習を行うことを想定しています。

<h4>vagrantへログインする</h4>
①ターミナルを起動します
（⌘command＋spaceでspotlightが起動できますのでターミナルと入力すれば起動します。）
②cdコマンドでホームフォルダに移動します。

```php
 cd
```

③仮想マシンをまとめたフォルダへ移動します。

```php
 cd MyVagrant
```

④仮想マシンのフォルダに移動します。

```php
 cd MyCentOS
```

⑤仮想マシンを起動します。

```php
 vagrant up
```

⑥仮想マシンへログインします。

```php
 vagrant ssh
```

<h4>学習手順</h4>
では、仮想マシンの準備が整ったので実際に学習を始めるための準備をしていきます。
ちなみにFTPソフトはcyberduckを使用しています。
CyberduckはWindowsとMacの両方に対応したFTPクライアントソフトです。日本語にも対応しているので、すぐに使いこなすことができるはずです。

cyberduckを立ち上げた後、新規フォルダを作っていきます。
ここではruby学習を想定して「ruby_lessons」としておきます。
ダブルクリックして「hello.rb」という新規ファイルを作っておきましょう。
ダブルクリックするとエディタが立ち上がるので編集します。
文面には「puts”hello”」と記入しておきます。

では、ターミナルへ戻ります。
ruby_lessonsのフォルダに移動しましょう。

```php
 cd ruby_lessons
```



```php
 ruby hello.rb
```
helloと表示されたら成功です。
学習をするときは上記の手順を繰り返すことで行うことができます。

今回は以上になります。お役に立てると幸いです