OmniAICreator/Qiita-1.07M huggingface dataset:
GPU計算とか関するポエム

## なんでこんなこと書いてるの
今書いているライブラリの一貫でマルチノードだったりGPUだったりで統一的に効率よく計算ができるようにする必要があったのでどうにかしてうまくできないかと思ってたらアイデアが出てきたので書きなぐってます。

## GPU計算の今
深層学習、とりわけ深層ニューラルネットワークの発展に伴ってGPUを使った行列計算の高速化はもはや避けて通れなくなってきました。PFNがChainerを使ってGPUクラスタで[ImageNetを15分で学習](https://www.preferred-networks.jp/ja/news/pr20171110)できるようにしたりと深層学習とGPUは切手は切れない関係にあります。ただGPUの利用には深刻な障壁があり、完全に使っているフレームワーク依存になるという大きな問題点があります。
ChainerなんかはCuPyとしてGPU計算用のロジックを切り出しているので扱いやすいんですがTensorFlowやらPyTorchはGPU計算が独自実装なのでフレームワーク間の相互運用性はほぼ無いと言っても過言ではないかと思います。かといってGPUのオンボードメモリからRAMにコピーするのは無駄だしGPU上のメモリ領域のポインタ操作をしたいかと言われればNoです。わがままなユーザ（私）はせいぜいどのGPUに乗ってるかさえ意識していれば勝手にGPU内、あるいはGPU-GPU間、CPU-GPU間の転送をしてくれる都合のいい仕組みがほしいです。nvlinkなんかの存在が一層その必要性を高めているように思います。
そもそもフレームワーク間で相互運用するケースがほぼ存在しない（あまり目につかないだけ？）ので何を喚いても無駄な感じはするんですがモデル並列でChainerのモデルとPyTorchのモデルをよしなに実行したいみたいな話とかは複合モデルを作る研究が増えれば予想できる将来図で、互換性を得るためだけに片方のモデルを書き換えてというのは正直非効率的です。複数人によるコラボレーションとなると最悪で、一人だけTensorFlowしか使えなくてあと全員Define-by-Run系のフレームワークしか使えないみたいな状況も考えられます。というか個人的にそういう経験があります。勉強せいって話なんですがTensorFlowって個人的に筋が悪いというイメージが定着してしまっているのでなかなか勉強する気になれずになあなあに時間だけが過ぎていきました。ぶっちゃけ勉強すればなんとかなるだろうとは思うんですがそのへんをエンジニアリングで解決したくなる悲しいサガの持ち主なのと仕事の都合上どうしてもフレームワークを限定して割り切ることが許されないためこんなしょうもないことを延々と考えていました。

## じゃあどうするの
私が思いつく程度のことは誰だって考えてるだろうしポエムにしかならないのでどうしようもないんですが人がなんの意味もなくポエムを書くのかと言われると感情の整理とかそういう生産性とは少しズレたところにポエムの価値はあると思ってるのでもし万に一つでもこのポエムが何かの役に立つならば自分の心中を吐露するついでにQiitaあたりに投稿してみるかと思った次第です。
個人的な理想形を言うならGPU計算を代行するブローカサービスを挟むのが一番いいんじゃないかと思ってます。ブローカに対してデータを投げつけてそのデータに対してやってほしい計算を指示すると勝手にそれをGPU上でやってくれて、あとはこの辺のブローカ呼び出しロジックを既存のCPU上で計算するインターフェースと揃えておいて行列がRAMとGPUのオンボードメモリのどっちに乗ってるかだけ指定しておけば数値演算ライブラリ側で勝手に処理を切り替えてくれるみたいな。
ある意味マイクロサービスというかそういうのに近いです。というかRPC化していいんじゃないかとも思います。マルチGPU間の転送をブローカ側で処理するならユーザが心配すべきなのはCPU-GPU間のデータ転送で、これはそもそもコストが大きいのでRPC化しても大したオーバーヘッドにならないと考えています。そういう仕組があればGPUに乗っているかどうかみたいなことを意識しなくて済むし、高級なインターフェースで計算できるし、gRPC的なもので作れば多言語対応できるしで万々歳のような気がしています。問題があるとすればCuDNN的なものがどういう扱いになるのかとかそういうところがどうなるかわからなかったりすることが挙げられますが全体的にGPU計算に対する幸福度は上がる気がします。

## 結論
人間のバイアスってすごいのでデメリットを見落としまくってるとは思います。でもポエムなので許されるとも思ってます（許されるからと言ってフィードバックがほしくないわけではない）。GPUの計算に対してもっと高級なインターフェースを提供するみたいなアプローチをしなきゃだめだよね的な議論とかもしご存知の方がいたらご教示願いたいです。とにかくGPUという特殊なハードウェアリソースを意識せずに使える枠組みはいずれ必要になる（かつPythonで実装されている以上CuPyではその役割は担えない、あるいは担える限界が来る）と思っているので関連する議論があったら参加したいなと思ってます。
firebase deploy が失敗する

## 不明なエラー

```
$ node_modules/firebase-tools/bin/firebase deploy --token ${FIREBASE_TOKEN} --only database,storage,hosting

=== Deploying to '{PROJECT_ID}'...

i  deploying database, storage, hosting
i  database: checking rules syntax...
✔  database: rules syntax for database {PROJECT_ID} is valid
i  storage: checking storage.rules for compilation errors...
✔  storage: rules file storage.rules compiled successfully
i  storage: uploading rules storage.rules...
i  hosting: preparing hosting/dist directory for upload...

i  Progress: [
Error: HTTP Error: 410, Unknown Error
```

こまった。

## 原因

`--only database,storage,hosting` こうやってまとめずに別々でデプロイしたらエラーメッセージを出してくれた。

```
$ node_modules/firebase-tools/bin/firebase deploy --token ${FIREBASE_TOKEN} --only database

=== Deploying to '{PROJECT_ID}'...

i  deploying database
i  database: checking rules syntax...
✔  database: rules syntax for database {PROJECT_ID} is valid
i  database: releasing rules...
✔  database: rules for database {PROJECT_ID} released successfully

Error: HTTP Error: 410, This version of the Firebase CLI is no longer able to deploy to Firebase. Please upgrade to a newer version (>= 4.1.0). If you have further questions, please reach out to Firebase support.
```
PHPとMariaDBのインストール(REMIレポジトリ）

# PHPとDBを触ってみる

# 前提条件
前回の記事、[さくらのVPSを使ったサーバの初期設定(一般ユーザ作成とrootアクセスの禁止)](https://qiita.com/shuthimaru/items/cecfcd0cef24979ae90b)が終了している

# 静的なページから動的なページへ(html⇒php）
前回はApacheをインストールしてWebサーバを構築し、htmlファイルを読み込ませるというところまでを行った。次はアクションに対して動作する動的なページの作成を行う。

内容をPHPに書き換えて拡張子をhtmlからphpに変える
1. ファイル名をindex.phpに変更する
2. 前回の内容を下記に変える

```
<html>
  <body>
    <?php echo "Hello World! php" ?>
  </body>
</html>
```

#remiレポジトリのインストール

```
sudo rpm --import https;//rpms.remirepo.net/RPM-GPG-KEY-remi #公開鍵を手に入れる
sudo yum install yum-utils https://rpms.remirepo.net/enterprise/remiremi-release-7.rpm

```


#phpのインストール
```
 yum install --enablerepo=remi,remi-php71 php php-devel php-mbstring php-mysqlnd php-pdo php-gd
```

その後、`systemctl restart httpd`をしてやる

IPをブラウザで叩いてphpの文が出ればOK

# PHPの設定を変えておく
```
cd /etc
cp php.ini php.ini.old
vim php.ini
```

サーバにデータを大容量のデータ送るため、「post_max_size」と「upload_max_filesize」の数字を変更します。 
escを押して/を押すと検索モードになるので上記二つを検索すると、
671行目　post_max_size = 8M
824行目　upload_max_filesize = 8M

と出てくるのでそれらをいずれも`128M`に変えておく。
後々のWordPress実装のため。

# MariaDBをインストールする
```
#yum install mariadb-server 
//Complete!
#systemctl enable mariadb
#systemctl restart mariadb
```

# MariaDBにパスワードをつける
```
mysql_secure_installation
```
MariaDBの現在のrootのパスワードを聞かれるのがなにも設定されていないのでEnterを押す

新しいパスワードを設定するか聞かれるのでyを押す。
新しいパスワードを2回入力する。パスワードはrootと同じにしないこと。
残りの質問は全てyで答える。
台風
#mariaDBにアクセスする
```
mysql -u root -p

show databases;
```

３つのデータベースが出たらアクセスできて利用可能な状態にできています。


#参考
[ネコでもわかる！さくらのVPS講座 ～第六回「無料SSL証明書 Let’s Encryptを導入しよう」 | さくらのナレッジ] (https://knowledge.sakura.ad.jp/10534_____)
[【yum入門】epel, remiなどのレポジトリをyumに追加する方法](https://uxmilk.jp/9315)
[yum installが上手く行かない時の対処法…]
(http://blog.livedoor.jp/engineercollege/archives/45087857.html)
CakePHP3でエレメント使用時の速度改善

各テンプレートでビューブロックとエレメント使いまくりになってから

対した処理もしていないのにロードだけで6.0secて遅すぎじゃない？？
と思い色々試した結果0.2secに改善した。


## エレメントの中でビューブロックを使うと重い

Templateでビューブロックを使うのは早いが
エレメント内でブロックを使うと一回につき0.5～1秒ほど遅くなるという致命的な現象
エレメント呼び出すだけでビューブロックに格納されるといいなと思ったのが間違いだった、、、

## ビューブロックの中身はエレメントにできるならしたほうが早い
エレメントキャッシュのおかげか
ビューブロックの中身はエレメントにできるならしたほうが早い
これで0.2～0.4は早くなった

```
<?php
use Cake\Routing\Router;

//タイトルをセット
$this->assign('title', 'スタッフリスト');

//ページャをセット
$this->assign('pagenator', $this->element('pagenator'));

//モーダルをセット
$this->append('modal');
echo $this->element("Vue/AddUserModal");
echo $this->element("Vue/EditUserModal");
$this->end();

//VVV各ページで違う検索ブロック
$this->append('search_block');
echo $this->element("Vue/Search");
$this->end();
?>

以下コンテンツ
```

ちなみにVueを扱う上で各エレメントを個人的にコントローラーに依存するものは
Template/{Controller}/Vue/{elememt}.ctp
に格納して以下の様に呼び出している

```
echo $this->element("../$this->name/Vue/AddUserModal");
```
リモートデスクトップ接続でログインできない


# リモートデスクトップ接続で認証ダイアログが出るのにログインできない

### そのユーザ名変更したことありませんか？

- Windowsではユーザー名とアカウント名(フルネーム)が異なる
- あちこちに表示されているのはアカウント名
- リモートデスクトップ接続ではユーザ名を聞かれる
- ディレクトリ名はまた別（これは変更困難）

### 接続できない理由：　ユーザ名が変更されていない

### ユーザ名変更方法

以下の手順でユーザー名の変更は可能。

1. [ファイル名を指定して実行]で control userpasswords2 と入力
1. [ユーザー]タブで変更したいユーザーをクリックし[プロパティ]ボタンをクリック
1. ユーザー名を変更

※コンピュータの管理のユーザーからでも変更可能
"rbenv install -list"指定したバージョンがない場合の対応手順

## Introduction

"rbenv install -list" で出力された値の中にインストールしたいバージョンがなかった際の対応方法です。
※ 因みに私は2.5.3がなくて困りましたw

## 【brew編】インストール手順

ruby-buildが古いためであると考えられます。
そのため下記コマンドでruby-buildのアップグレード行う

```

$ ruby-build --version
※　バージョン確認
※　"ruby-build 20181019"（※2018/10/30時点最新）
  ではなかったらアップデートする必要あり。

$ brew upgrade ruby-build
※ インストールコマンド

$ ruby-build --version
※表示が最新になっていればOK

$ rbenv install -list
※インストールしたいバージョンが表示されていることを確認

$ rbenv install ”インストールしたいバージョン”
Ex.  $ rbenv install 2.5.3

```

## 【plugin編】インストール手順

brewではなく、rbenvのpluginでインストールしている場合は下記コマンドでruby-buildでアップデートすることが可能です。
※ [こちらの文献を参考にさせていただきました](https://gist.github.com/mochiz/4736183 "参考文献")

```
$ cd ~/.rbenv/plugins/ruby-build 
$ git pull origin master
```

## Conclusion

ruby 2.5.3　インストールできました♫

それでは！！
docker-machineでホスト（MacOS）のUSBデバイスをDockerコンテナにマウントする

## 概要
- Docker for Macで作成したDockerコンテナからホストのUSBデバイスにアクセスできない
- Docker for Macで使われているHyperKitがUSBパススルーをサポートしていないから
  [USB Passthrough · Issue #149 · moby/hyperkit · GitHub](https://github.com/moby/hyperkit/issues/149)
- VMならマウントできる
- じゃあdocker-machineを使おう

## Docker Machineのインストール
公式ドキュメント
[Install Docker Machine \| Docker Documentation](https://docs.docker.com/machine/install-machine/)

```:terminal
$ base=https://github.com/docker/machine/releases/download/v0.14.0 &&
  curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/usr/local/bin/docker-machine &&
  chmod +x /usr/local/bin/docker-machine
  
$ docker-machine -v
docker-machine version 0.14.0, build 89b8332
```

## デフォルトのVMを作成
VMの名前はdefaultとしています。
Dockerデーモンがインストールされた軽量Linuxディストリビューションであるboot2dockerの仮想マシンが作成されます。

```:terminal
$ docker-machine create --driver virtualbox default

$ docker-machine ls
NAME      ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
default   -        virtualbox   Running   tcp://192.168.99.100:2376           v18.06.1-ce
```

## VirtualBoxからデフォルトVMにUSBデバイスを設定する
docker-machineを停止します。

```:terminal
$ docker-machine stop
```

VirtualBoxからdefaultのVMの設定を開き、USBコントローラを有効にします。
そこから、必要なUSBデバイスを追加します。
![スクリーンショット 2018-10-30 12.11.43.png](https://qiita-image-store.s3.amazonaws.com/0/124843/1ad099bb-2cf0-532f-75b8-704e5bb36c2f.png)

docker-machineをもう一度立ち上げます。

```:terminal
$ docker-machine start
```

## 現在のシェルの環境変数を書き換えて対話式でdockerの操作をできるようにする
いくつかの環境変数をshellに設定します。
必要な環境変数は以下で確認できます。

```:terminal
$ docker-machin env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/Users/tomitz/.docker/machine/machines/default"
export DOCKER_MACHINE_NAME="default"
# Run this command to configure your shell:
# eval $(docker-machine env)
```

上記の通り、`eval $(docker-machine env)`を実行します。

```:terminal
$ eval $(docker-machine env)
```

## docker-machineのコマンド

```:terminal
起動
$ docker-machine start default

再起動
$ docker-machine restart default

停止
$ docker-machine stop default

強制停止
$ docker-machine kill default

SSHで接続
$ docker-machine ssh default

マシン一覧
$ docker-machine ls

statusの確認
$ docker-machine status default

マシンのdockerを最新にアップグレード
$ docker-machine upgrade default

マシン削除
$ docker-machine rm default
```
Socket.iO-client-swiftが動かない

ハマりどころが一箇所あったのでラフに記事を書きます。

# 問題
Socket.IOのクライアントコードを書いたものの、ずっとconnectingで繋がらない。

# 結論
SocketManagerオブジェクトは、SocketIOClientの生存期間と同じ期間、強参照される必要がある。

# 問題の書き方

```swift:wrong.swift
class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        manager = SocketManager(socketURL: URL(string: "http://localhost:8000")!, config: [.log(true), .forceWebsockets(true), .forcePolling(true)])
        socket = manager.defaultSocket
        
        socket.on(clientEvent: .connect) { [weak self] data, ack in
            print("connect")
            self?.socket.emit("join", ["hoge"])
        }
        
        socket.on("message") { data, ack in
            print("Message received")
            print(data)
        }
        
        socket.on(clientEvent: .statusChange) { data, ack in
            print(data)
            print(arc)
        }

        
        socket.connect()
    }


}


```

# 正しい書き方

```swift:correct.swift

import UIKit
import SocketIO
class ViewController: UIViewController {

    var manager: SocketManager!
    var socket: SocketIOClient!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        manager = SocketManager(socketURL: URL(string: "http://localhost:8000")!, config: [.log(true), .forceWebsockets(true), .forcePolling(true)])
        socket = manager.defaultSocket
        
        socket.on(clientEvent: .connect) { [weak self] data, ack in
            print("connect")
            self?.socket.emit("join", ["hoge"])
        }
        
        socket.on("message") { data, ark in
            print("Message received")
            print(data)
        }
        
        socket.on(clientEvent: .statusChange) { data, ack in
            print(data)
            print(arc)
        }

        
        socket.connect()
    }


}

```
windows sbt. Failed to authenticate with proxy

sbt 1.2.6

sbtconfig.txtもダメ環境変数のSBT_OPTSに設定してもダメ

ちなみに何も設定していない場合のエラーは下記です
`java.net.ConnectException: Failed to connect to`

下記で解決しました
https://github.com/sbt/sbt/issues/3696#issuecomment-414518312

```
-Dsbt.gigahorse=false
-Dsbt.repository.secure=false
```
cloud9でpython3を使用する



1. PreferencesからPython VersionをPython3へ変更する
1. エイリアスを貼り直す

    ```
    $ which python
    alias python='python27'
    /usr/bin/python27
    ```

    ```
    $ alias python='python3'
    ```

1. Pythonの参照をリロードする

    ```
    sudo update-alternatives --config python
    ```

1. バージョンが書き換わっていれば完了

    ```
    $ python -V
    Python 3.6.5
    ```
Alibaba Function Compute による kintone 定期実行

kintone の定期実行をAlibaba Function Compute (node.js)で試してみました。
今回は 1時間ごとに　kintone アプリのレコード件数を取得する処理です。
基本的なしくみは、Azure Functions など他のサーバーレスと同様で簡単に定期実行が実現できます。

# 開発環境

[kintone 連携の Alibaba Function 開発メモ](https://qiita.com/rex0220/items/7bbf1c16ba14f7f49828)と同じです。

# kintone API トークン

kintone アプリ設定画面で、REST API で使用するAPI トークンを発行します。
試用するAPI によって、アクセス権を設定できます。

<img width="1125" alt="2018-10-30_11h50_32.png" src="https://qiita-image-store.s3.amazonaws.com/0/100572/caae09d0-d653-ffae-972d-a84ccdae1917.png">


# Function Compute の構成

今回は定期実行をするため、タイムトリガーを定義します

- [リージョン](https://jp.alibabacloud.com/help/doc-detail/40654.html) ：東京、上海などが選択可能
    - サービス：Function Compute のリソースを管理するための単位
        - 関数：システムのスケジューリングと操作の単位
            - トリガー：タイムトリガーはここで定義

# 作成した関数の概要

kintone のレコード数が少なければ、メモリ 128 MB, タイムアウト60秒で十分です。

<img width="1127" alt="2018-10-30_11h22_57.png" src="https://qiita-image-store.s3.amazonaws.com/0/100572/705346e5-1a09-25a8-808b-e98fef0dc619.png">


# タイムトリガー

設定時は、間隔60分を指定しましたが、保存後に見てみると Cron 式に変換されていました。
<img width="479" alt="2018-10-30_11h26_27.png" src="https://qiita-image-store.s3.amazonaws.com/0/100572/d367dabd-4585-62c1-99e5-306e3d479f15.png">


# 環境変数

環境変数を設定して、関数内で使用できます。
kintone URL, APPID, APIトークンなどを環境変数に設定して使います。

node 参照例
process.env['KINTONE_URL']

# コード

request, request-promise を使用して、[kintone REST API](https://developer.cybozu.io/hc/ja/articles/201941754) を呼び出しています。

```f_check_records.js
/*
 * Alibaba Function : kintone get records 
 * 2018.10.30 by rex0220
 */
'use strict';
const rp = require('request-promise')
module.exports.handler = function(event, context, callback) {

    // get kintone records
    var getRecords = function(query) {
        var req = {
            "method": "GET",
            "url": process.env['KINTONE_URL'] + '/k/v1/records.json',
            "headers": {
                "X-Cybozu-API-Token": process.env['KINTONE_API_KEY']
            },
            "qs": {
                app: process.env['KINTONE_APPID'],
                query: query,
                totalCount: true
            },
            "json": true,
        };
        // console.log('get record req: ', JSON.stringify(req));
        return req;
    };

    // main
    rp(getRecords('対応日時 >= "2018-06-01" limit 1')).then(function(resp) {
        console.log('get record done: ', JSON.stringify(resp));
        callback(null, 'records count: ' + resp.totalCount);
    }).catch(function(error) {
        console.log('error: ' + error.message);
        callback('Error get kintone records, ' + err.message, null);
    });
};
```

# 実行結果

１時間ごとの定期実行であれば、無料枠内で済みそうです。

課金された時間 300 ms
最大使用メモリ 128 MB
メモリ 30.71 MB

<img width="918" alt="2018-10-30_12h05_24.png" src="https://qiita-image-store.s3.amazonaws.com/0/100572/3eaab4b1-de67-de11-50a2-f8a20a4d4d40.png">


# 参考URL

[kintone REST APIの共通仕様](https://developer.cybozu.io/hc/ja/articles/201941754)
[Function Compute の概要](https://jp.alibabacloud.com/help/doc-detail/52895.htm)

# あとがき

kintone で定期実行するしくみを簡単に JavaScript で構築できるのはうれしいですね。
Google系PUSH通知サービスの変遷

# Google系PUSH通知サービスの変遷

|  年  |    C2DM    |     GCM    | FCM |          備考          |
|:----:|:----------:|:----------:|:---:|:----------------------:|
| 2010 | 2010-05-20 |            |     | Android 2.2 Froyo      |
| 2011 |      ‖     |            |  ‖  |                        |
| 2012 |      ‖     | 2012-07-09 |  ‖  | Android 4.1 Jelly Bean |
| 2013 |      ‖     |      ‖     |  ‖  | GCM for Chrome         |
| 2014 |      ‖     |      ‖     |  ‖  |                        |
| 2015 | 2015-10-20 |      ‖     |  ‖  |                        |
| 2016 |            |      ‖     |  ‖  |                        |
| 2017 |            |      ‖     |  ‖  |                        |
| 2018 |            |      ‖     |  ‖  |                        |
| 2019 |            | 2019-04-11 |  ‖  |                        |



# 参考

Android Cloud to Device Messaging - Wikipedia
https://en.wikipedia.org/wiki/Android_Cloud_to_Device_Messaging

Google Cloud Messaging - Wikipedia
https://en.wikipedia.org/wiki/Google_Cloud_Messaging

Firebase Cloud Messaging - Wikipedia
https://en.wikipedia.org/wiki/Firebase_Cloud_Messaging


プッシュ通知の遍歴（Android編） - ニフクラ mobile backend（mBaaS）お役立ちブログ
https://blog.mbaas.nifcloud.com/entry/2018/06/14/143229#2012%E5%B9%B4

プッシュ通知の遍歴（iOS編） - ニフクラ mobile backend（mBaaS）お役立ちブログ
https://blog.mbaas.nifcloud.com/entry/2018/06/14/143518

## Time to Upgrade from GCM to FCM

The Firebase Blog: Time to Upgrade from GCM to FCM
https://firebase.googleblog.com/2018/04/time-to-upgrade-from-gcm-to-fcm.html

Google Developers Japan: 今こそ GCM から FCM にアップグレードを
https://developers-jp.googleblog.com/2018/04/time-to-upgrade-from-gcm-to-fcm.html

「Googleクラウドメッセージング（GCM）」が1年後に廃止、「Firebase Cloud Messaging（FCM）」への移行が必要に：Googleのアプリメッセージング基盤が完全に交代 - ＠IT
http://www.atmarkit.co.jp/ait/articles/1804/13/news051.html

ご注意ください！プッシュ配信GCM廃止について（～2019年04月10日まで） - ニフクラ mobile backend（mBaaS）お役立ちブログ
https://blog.mbaas.nifcloud.com/entry/2018/04/11/165730
データコアサーバーVMの感度を高にする。

https://qiita.com/tsurun/items/14c9f43f10b731e44462
の続きです。

（環境依存かもしれないけど）データコアサーバーに高感度設定がちゃんと入ってなかった。
参考URL https://communities.vmware.com/thread/474604

```
#vCenter Serverにはあらかじめ接続してある前提
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.latencySensitivity = New-Object VMware.Vim.LatencySensitivity
$spec.LatencySensitivity.Level = [VMware.Vim.LatencySensitivitySensitivityLevel]::high
$vm = Get-VM -Name HVSAN-*|%{$_.ExtensionData.ReconfigVM($spec)}
```
.gitignore以外でファイルを除外する

# 概要
gitを使って開発をしていて、gitの管理対象外とするファイルを`.gitignore`で管理することがほとんどだと思う。
ただ、チームで開発している場合、`.gitignore`は全員で共有するファイルなので、個人的に含めたくないファイルやディレクトリがある場合は、毎回手動で除外するのは面倒。

## 対象のリポジトリに限定して、特定のディレクトリやファイルを除外する（しかも影響範囲は個人）
### 方法

対象のリポジトリのプロジェクトルートディレクトリで、以下を実行

```bash
$ vim .git/info/exclude
```

```git:.git/info/exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
public/uploads/  ←これでpublic/uploadsは自分の環境でのみ対象外になる
```
Windows 環境 AEGP_MemHandle で取得した文字列の使い方

AEGP_GetProjectPath でプロジェクトのフルパスを取得しようとすると、UTF16 の文字列が
指定した AEGP_MemHandle に格納されます。

このままだと文字列すら取得できないので手順を踏む必要があります。

# AEGP_LockMemHandle でメモリの先頭アドレスを取得

```c++

AEGP_MemHandle mem;
A_UTF16Char *path;
suites.MemorySuite1()->AEGP_LockMemHandle(mem, (void**)&path);
```

# UTF16 から SJIS に変換
MAC だと、デフォルトが UTF16 らしいので変換の必要が無いらしい。未確認

```c++
int    out_size;
A_char	proj_path[MAX_PATH + 16];
out_size = WideCharToMultiByte(CP_ACP, 0, (OLECHAR*)path, -1,NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, (OLECHAR*)path, -1, proj_path,out_size, NULL, NULL);
```
参考サイト
http://d.hatena.ne.jp/sirocco/20130418/1366253252

# 後片付け
```c++

suites.MemorySuite1()->AEGP_UnlockMemHandle(mem);
suites.MemorySuite1()->AEGP_FreeMemHandle(mem);
```

# その他
- 文字列の長さチェックとか、変換失敗は考慮していません
YAML を読みやすい JSON に変換する Ruby スクリプト

# やりたいこと

次の YAML を JSON に変換したい。

```girls.yml
- name: 中川夏紀
  musical_instrument: ユーフォニアム
- name: 吉川優子
  musical_instrument: トランペット
- name: 鎧塚みぞれ
  musical_instrument: オーボエ
- name: 傘木希美
  musical_instrument: フルート
```

# 方法

```yaml_to_json.rb
require 'json'
require 'yaml'

filepath = ARGV[0]

yaml = File.read(filepath)
obj = YAML.safe_load(yaml, [], [], true)

puts(JSON.pretty_generate(obj))
```

```
$ ruby yaml_to_json.rb girls.yml
```
```json

[
  {
    "name": "中川夏紀",
    "musical_instrument": "ユーフォニアム"
  },
  {
    "name": "吉川優子",
    "musical_instrument": "トランペット"
  },
  {
    "name": "鎧塚みぞれ",
    "musical_instrument": "オーボエ"
  },
  {
    "name": "傘木希美",
    "musical_instrument": "フルート"
  }
]
```

JSON モジュールに JSON.pretty_generate なんて素敵なメソッドがあるとは :heart_eyes:

# 参考

* [JSON.#pretty_generate](https://docs.ruby-lang.org/ja/latest/method/JSON/m/pretty_generate.html)
【Git】新しいブランチの作り方

良く忘れるので、メモ書きを兼ねて。
(2019/09/24 git version 2.23.0 リリースに伴い追記)
 
## **作業中のファイルがある場合**
`$ git stash save '自分がわかるメモ'`

## **master ブランチに切り替える**
`$ git checkout master`
`$ git switch master` (version 2.23.0)

## **masterブランチを更新する**
`$ git pull origin master`

## **ブランチを作成するディレクトリに移動する**
`$ cd ~/...`

## **全ブランチを確認**
`$ git branch -a`

## **ブランチを作成し、作成したブランチに切り替える**
`$ git checkout -b ブランチ名`
`$ git switch -c ブランチ名` (version 2.23.0)

## **新しいブランチを更新する(-u でデフォルト設定)**
`$ git push -u origin ブランチ名`

## **今まで使っていたブランチと差分がある場合**
`$ git cherry-pick コミットID`

## **stashした作業中のファイルを戻す**
`$ git stash pop`
tesserocrを使ってみる

# はじめに

tesserocr を利用してみた際の設定から実行についてのメモです。
tesserocr は、python用のtesseract-ocr APIのラッパーライブラリです。
https://github.com/sirfz/tesserocr 

ハマったポイントも記載しました。


# インストール

上記サイトを参考にインストールします。

* 前提条件としては、tesseract 4系 がインストール済みであることです。  
  参考: [tesseractを使ってみよう②（初心者編）](https://qiita.com/tifa2chan/items/ce3ff1565a1124eabae0)

```
$ tesseract -v
tesseract 4.0.0-rc4
```

* tesserocrのインストール

```
$ CPPFLAGS=-I/usr/local/include pip install tesserocr
```

* 依存ライブラリのPillowのインストール

```
$ pip install pillow
```

# 使ってみる

* 上記サイトにあるソースをほぼコピーして試してみて、エラーがでなければインストール成功です。

```python
import locale
locale.setlocale(locale.LC_ALL, 'C')
import tesserocr
from PIL import Image

print(tesserocr.tesseract_version())  # print tesseract-ocr version
print(tesserocr.get_languages())  # prints tessdata path and list of available languages

image = Image.open('test.png')
print(tesserocr.image_to_text(image, lang=('jpn')))  # print ocr text from image
```


# エラー対処

いくつかエラーが出てハマったので下記に記載します。

## エラー①

* 普通にpipでインストールした後に、スクリプトを実行したら下記のエラーが出たので、一旦tesserocrをアンインストール

```
    import tesserocr
ImportError: libtesseract.so.3: cannot open shared object file: No such file or directory
```

* 再インストール時は下記コマンドを実行

```
$ CPPFLAGS=-I/usr/local/include pip install tesserocr
Collecting tesserocr
  Using cached https://files.pythonhosted.org/packages/f8/6d/4e81e041f33a4419e59edcb1dbdf3c56e9393f60f5ef531381bd67a1339b/tesserocr-2.3.1.tar.gz
Installing collected packages: tesserocr
  Running setup.py install for tesserocr ... done
Successfully installed tesserocr-2.3.1
```

## エラー②

* ロケールを設定しないと下記のエラーが発生   
  詳細はこちら： https://github.com/sirfz/tesserocr/issues/137

```
!strcmp(locale, "C"):Error:Assert failed:in file baseapi.cpp, line 209
Segmentation fault (core dumped)
```
Bitbucketとcloud9を連携する最短ルート

1. [bitbucket](https://bitbucket.org)へログインする
1. リポジトリを新規作成する
1. c9でssh keyを作成する

    ```
cd ~/.ssh
ssh-keygen
```

1. 共通鍵をコピーする

    ```
cat ~/.ssh/id_rsa.pub
```

1. bitbucketのアカウント設定 -> SSH鍵 -> コピーした鍵を追加する
1. c9の該当プロジェクトディレクトリでコマンドを打つ

    ```
git remote add origin git@bitbucket.org:$user_name$_/$project_name$.git
git push -u origin master
```

以上
新人エンジニアだった僕が圧倒的成長するためにやっていたこと。自分自身で考える習慣をつける 「悩みのススメ」 。

(圧倒的成長したとは言ってない)

(良い子は真似しちゃダメかもしれない)

# Inspired by

@_kanacan_ さんの記事を読んでいると、「分かること」と「分からないこと」の整理が本当にうまいというか、地道に整理する習慣が根付いているんだなと毎回感心する。

[新人エンジニアの私が圧倒的成長するためにやっていること - Qiita](https://qiita.com/_kanacan_/items/d9d99e5bb0248584a6c5)

この記事では、自分のケースをお伝えする。(1個の道があれば、別の道もあるよっていう話)

# 悩みすぎる。質問するまでのルールを決めない。

>悩みすぎない。質問するまでのルールを決めよう

こちらの真逆。

## 圧倒的苦手分野

僕の場合は「質問するまでの時間を区切る」というやり方は自体は知っていたものの、実行できなかった。
なぜなら **人に相談する、質問することが、頼ることがそもそも圧倒的に苦手** だったからだ。

だけど、ひたすらに悩むことで、逆に得られたものもあったと思う。それが「考える癖」「深掘りする癖」だ。

## 悩むことが許された環境

自分の場合は幸運にも一時期、ひたすらに悩んだり考えたりすることが許されていた時期があった。

当時の開発リーダーから「チームが忙しいので、他の人に質問したりしてコストをかけたりせず、自分だけの力で進んでみてくれ」「コスト最小化だ！」的な指示があり、幸運なひとときを過ごすことができたのだった。

## 30分どころか1日かけて考えた

ときにはSQLのクエリの1個のGROUP BY の書き方だけで、1日ずっと考えていたことさえあった。今思うとなんて贅沢な。

それは機能的、ドメイン的に特にボトルネックなる部分ではあったのだけれど。誰にも聞かずにオセロの白黒を裏返すように、少しずつ考えのレベルを掘り下げていったことがあった。

## 成果物

そんなこんなを続けた結果、以前は「稲浦さんには物事を深掘りする習慣がない」と言われていたところを、逆の評価を受けるようになった。

「稲浦さんは自分自身で、そこまで物事を考えられるレベルにまで達したんですね」と言ってもらえた。もちろんそれは、1日2日の出来事ではなかったけれど。

自分でも「考える癖」がある程度、身についた実感がある。

# 具体的な悩み方、考え方

とにかく考えることに時間を使う。

- 絵や図を描きながら考える
- 目を閉じて考える
  - (ひとつの考えに意識を集中させて、なおかつ遊ばせる。これにはマインドフルネスのテクニックも役立つ)
  - [瞑想するエンジニア ( by 稲浦悠馬 Yuma Inaura ) —GoogleやFacebookもやっている「マインドフルネス」のススメ— - Qiita](https://qiita.com/YumaInaura/items/f1a55b0b342954224207)
- PCを触らずに考える
- たくさん考えたら少し席を外して歩いてみる (ユリーカは散歩とともに)


「考えるのってどうやるの？」という人は、考え方についてまずは考えてみてはどうだろうか。

## 途中で読みたい

[ペアプログラミングして気がついた新人プログラマの成長を加速する３つの習慣 - Qiita](https://qiita.com/KakkiiiiKyg/items/2d0920416a0e0187810d)

>よくコードを読み、理解することに時間をかける
>
>常に目の前の問題を単純化することに知恵を使う

この記事に書かれているのはコードの話だけど「考えることが大事」「何も生産していないように見える時間こそ実は大事」という話。

# あわせて読みたい？

- [エンジニアの成長には「脳内キラーフレーズ」を使いなさい。仕事の長所を伸ばし、弱点を克服する方法。メンタルモデルの作り方。 - Qiita](https://qiita.com/YumaInaura/items/1bcdd0ee4d331603a226)
- [社会人４年目エンジニアの私が圧倒的成長するためにやっていること - Qiita](https://qiita.com/k-boy/items/7f163525b4082f0738f7#_reference-3154bdd399546b9efca9)
  - `ジムとオフィスから5分圏内に住む`
  - 近いことは正義。環境も「成長レベル」を決めると思う。








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Laravel(PHP)の実行がやたら遅い

最近、Laravelでphp artisan serveしても、数秒しないとserve状態にならず？？？と思っていました。
最近、Laravel Mixを利用し始めたのでwebpackあたりがおかしいのかな？？？とか勝手に思っていました。

が、今日、たまたま

```
php -v
```

としたところ、バージョンの表示までに数秒かかるではないですか！！！

というわけで、Laravelではなく、PHPが遅いのだなと思い調べてみたところ、

[extension=imap.soの読み込みが悪さをしているらしい](https://qiita.com/koriym/items/5847823a115e2f50e429)という記事を見つけました。

以前は特に遅くなかったので「ものは試し」と読み込みをコメントアウトしたところ早くなりました。

```bash
;extension=imap.so
```

OSのバージョンアップの影響か、、、PHP（MAMP）のバージョンアップのせいか、、、根本原因はわかりませんが解決しました。
WSL+Vim+YouCompleteMe+Unityの罠

# 注意書き
Vim以外のエディタに宗教上の理由で触れません。GUIを使いたくありません。
shellの黒い画面に引きこもって開発したいです。
育ちが悪いので言葉がアレです。用法用量に注意してお読みください。

# なんでWSL?
今までMac+UnityでiOSやAndroidの開発してたんですが、仕事がVRになりました。
そう、VRの開発=Windows
Macに親しんだ人ならわかってくれると思うんですがWindowsは開発環境構築がメンドウクサイ…
まだ環境は定まっているわけではないのですが、似たような状況の人はきっといるだろうと思い、
ハマった罠についてアウトプットします。
WindowsでMacみたいな爆速zsh環境がいつか来るといいなぁ…。頑張れWSLもっと頑張れ。

# Windows+Unityで生成した.slnをUbuntuのVim+YouCompleteMeで
Unityは.slnをプロジェクトからよしなに生成してくれます。
VisualStudioで読み込んですぐバリバリ開発できますねヤッタァー
~~あんかクソ重いエディタ使えるか。テキストオブジェクト使えないとか化石~~

さてWSLをいれてUbuntu内でVim+YouCompleteMeでプロジェクトを読み込んでみましょう。
自前で作成したクラス群は補完がちゃんと効くと思いますが、
UnityEngineなどUnityEngine.dllで定義されてるクラス群が補完できませんね。
諦めてVisualStudioしないでください。訓練されたVimmerは諦めない。

Vim内で`:YcmDebugInfo`だッ！

上記コマンドを叩くと読み込んだslnのpathやlogのpathが表示されます。
今回見るべきは`OmniSharp logfile: /path/to/hogefugapiyo_stdout_hogehoge.log`になります。
そのlogを追ってみるとUnityEngine.dllがLoad Errorになっているログが吐かれています。
そのpathを見るに`C:\path\to\Unity\`になっていませんか？
WSLの設定にもよるかと思うのですが少なくとも自分はUbuntu側からのpathは
`/mnt/c/path/to/Unity`以下略にUnityEngine.dllがいなければならないはず。
犯人はこいつです。

というわけで修正です。
Unityはよしななタイミングで.slnや.csprojを更新するのでテキトーなFunctionでも作っておいて、
即座に修正できるようにしておきましょう。

``` VimScript
command! ModifyCSProjFile :call ModifyCSProjFile()
function! ModifyCSProjFile()
    :!find . -maxdepth 2 -name "*.csproj" | xargs sed -i -e 's/C:/\/mnt\/c/g'
    :!find . -maxdepth 2 -name "*.csproj" | xargs sed -i -e 's/D:/\/mnt\/d/g'
    :YcmCompleter ReloadSolution
endfunction
```

あんまりVimScript感がありませんが動いてるからイイノデス。
Vimmerのツッコミ歓迎 :sunglasses:
tesseractを使ってみよう②（初心者編）

# はじめに

前回、[tesseractを使ってみよう（初心者編）](https://qiita.com/tifa2chan/items/d2ae546804b1ce2e7277)では、tesseract 3系しかインストールができなかったので、今回は4系をインストールします。

環境は、Ubuntu 16.04 LTSです。Ubuntu 18.04 LTSなら多分4系が入るはずです。

# インストール

## 古いのを削除
すでにインストール済みのモジュールがある場合は一旦削除します。
削除をしないと後の再インストールに失敗します。

```
$ sudo apt remove tesseract-ocr
$ sudo apt remove libtesseract-dev
```

## 再インストール

* 普通にインストールをすると、また3系しか入らないので、下記のサイトを参考に実行します。  
https://launchpad.net/~alex-p/+archive/ubuntu/tesseract-ocr?field.series_filter=xenial

```
sudo add-apt-repository ppa:alex-p/tesseract-ocr
sudo apt-get update
```

* そして、改めてインストール

```
$ sudo apt-get install tesseract-ocr libtesseract-dev libleptonica-dev
```

* 確認  
  4系が入りました

```
$ tesseract -v
tesseract 4.0.0-rc4
 leptonica-1.76.0
  libgif 5.1.4 : libjpeg 8d (libjpeg-turbo 1.4.2) : libpng 1.2.54 : libtiff 4.0.6 : zlib 1.2.8 : libwebp 0.4.4 : libopenjp2 2.1.2
 Found AVX2
 Found AVX
 Found SSE
```

# 言語のインストール

* 日本語のインストールをします。二種類あります。  
  vertがついているのは縦書き用のようです。

```
$ sudo apt install tesseract-ocr-jpn  tesseract-ocr-jpn-vert
$ sudo apt install tesseract-ocr-script-jpan tesseract-ocr-script-jpan-vert
```

* 確認  

```
$ tesseract --list-langs
List of available languages (6):
Japanese
Japanese_vert
eng
jpn
jpn_vert
osd
```

# 実行

* 2種類の言語で試してみます。

```
$ tesseract -l jpn test.png out1
$ tesseract -l Japanese test.png out2
```

# 結果

[PythonのWiki](https://ja.wikipedia.org/wiki/Python)の目次のスクリーンショットを撮って試してみた結果がこちら。
両方の言語ファイルで微妙に結果が異なります。tesseract3系よりは良くなってます。

左：読み込ませた画像
中央：結果(jpn)
右：結果(Japanese)
![tesseract4.png](https://qiita-image-store.s3.amazonaws.com/0/92328/0156f307-7337-a16f-2637-5f94553c87c2.png)


# 参考

* https://blog.with-ruby.net/2018/07/12/install-tesserocr/
MacでVPN接続するときに名前解決できない時の対処

システム環境設定→ネットワーク→接続するVPN構成→詳細　で「すべてのトラフィックをVPN接続経由で送信」にチェックを入れればOKでした。

社内にイントラ用のDNSを置いたのですが、VPNに繋げたあとも社内のサーバーに名前解決できない。

`scutil --dns` すると使っているDNSが参照できます。 `/var/run/resolv.conf` を見るのでもいいです。で見てみてもDNSが変わってない・・・上記の設定を有効にすることで、できるようになりました。
exFATの落とし穴？

# ExFATの落とし穴
注意：個人的に思ったことなので、私のようなことをしないのであれば何ら問題はありません。

## 流れ
先日USB(8GB)の容量がなくなったので32GBを買いました

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">えっ、USB 32GBで2000円って安くね？<br><br>前買ったとき16GBで3000くらいしたんだけど…？<br><br>今そんなに安くなってんの？<br>まじかよ…</p>&mdash; Asa(0x41 0x73 0x61) (@a01sa01to) <a href="https://twitter.com/a01sa01to/status/1056805911589609477?ref_src=twsrc%5Etfw">October 29, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

で、スマホ(Android)からも読み取りたいなぁ...と思い、exFATでフォーマット。

## ファイルシステム比較
|    |FAT32|NTFS|exFAT|
|--:|:---:|:--:|:---:|
|最大ファイルサイズ|4GiB|16EiB|16EiB|
|Windows|○|○|○(Vista SP1以降)|
|Mac|○|△(読取のみ)|○(OS X v10.6.5)|
|Linux|○|△(読取のみ)|○(ドライバあり)|

参照：Wikipedia→[FAT32](https://ja.wikipedia.org/wiki/File_Allocation_Table#FAT32),[NTFS](https://ja.wikipedia.org/wiki/NT_File_System),[exFAT](https://ja.wikipedia.org/wiki/ExFAT)

なにこれ！めっちゃいいやん！！と思ってフォーマット、ファイルコピー。
しかしそこには私にとってある欠点が...

## mklink
**シンボリックリンク対応してない！！**

私、ルートフォルダによく使うリンクを作成しておく派なんですよ、
それで、8GB(NTFS)にはめっちゃリンクおいてたんですわ。

で、コマンドプロンプトで
`mklink aaa folder\aaa`(これは例です)
→`The device does not support symbolic link`みたいなかんじで
対応してなかったわけなんですね

そこで...

## Paste Shortcuts
シンボリックリンク対応してなくとも、コピー＆ショートカット貼り付けは対応してるのでそれでやりました。

例えば本体が`/aaa/bbb/ccc/index.html`で、
`/aaa/bbb/ccc/ddd/eee.js`があり、
`/ddd/eee.js`なんて指定している場合は
ルートフォルダのdddって作成していないディレクトリが読み込まれるので、404Error。
シンボリックリンクにしておけば`/aaa/bbb/ccc/`内の`ddd/eee.js`を参照してくれるので個人的には良かった。

わかりづらいなこれ

要は、こういうことです
![Explanation](https://qiita-image-store.s3.amazonaws.com/0/279132/ccbd8de9-19cb-5040-2ad9-d0fec94b5f9c.png)
**ただ図式化しただけ**

NTFSに再フォーマットしようか迷ったけどAndroidで読み込めるのが大きかったので
exFATのままで使用しようかと思います

## まとめ
exFATはシンボリックリンク対応してないよ。
シンボリックリンク使わないならexFATのほうがいい。
Grafana 5.3.2へアップデート Ubuntu16.04

# Grafana v5.3.2 Update
久々にGrafanaの公式を見てたら、入れた時は5.2だったのに5.3まで上がっていたので、アップデートを試してみる。

# 5.3の新機能
 * コアデータソースとしてのGoogle Stackdriver！
 * テレビモードが改善され、よりアクセスしやすい
 * 通知のリマインダによる警告
 * Postgresは新しいクエリビルダーを手に入れました！
 * GitlabのOAuthサポートが改善されました
 * テンプレート変数フィルタリングによるアノテーション
 * フリーテキストをサポートする変数

個人的に興味があるのはGitLabのOAuthサポートとフリーテキストとかかな。

本当はアラートの設定にもっと手を入れてほしいんだけど。。

# アップデート手順

入れたのがそこそこ前で特に記録していなかったからどうやってインストールしたのか覚えてませんでした。。
調べるとaptのリポジトリを追加して入れているみたいでした。

```bash
# apt-get update 
# apt cache policy Grafana
grafana:
  Installed: 5.2.2
  Candidate: 5.3.2
  Version table:
     5.3.2 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
     5.3.1 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
     5.3.0 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
     5.2.4 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
     5.2.3 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
 *** 5.2.2 500
        500 https://packagecloud.io/grafana/stable/debian jessie/main amd64 Packages
        100 /var/lib/dpkg/status
# apt-get install grafana
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be upgraded:
  grafana
1 upgraded, 0 newly installed, 0 to remove and 135 not upgraded.
Need to get 54.8 MB of archives.
After this operation, 9,661 kB disk space will be freed.
Get:1 https://packagecloud.io/grafana/stable/debian jessie/main amd64 grafana amd64 5.3.2 [54.8 MB]
Fetched 54.8 MB in 2s (23.7 MB/s)  
(Reading database ... 78163 files and directories currently installed.)
Preparing to unpack .../grafana_5.3.2_amd64.deb ...
Unpacking grafana (5.3.2) over (5.2.2) ...
Processing triggers for systemd (229-4ubuntu21.2) ...
Processing triggers for ureadahead (0.100.0-19) ...
Setting up grafana (5.3.2) ...
Restarting grafana-server service... OK

```

こう簡単だとありがたいですね。
Azure Functions (Java)をローカル実行したときに認証付きProxyを経由させる

* local.settings.jsonファイルにProxy関連情報を追加します（local.settings.jsonは.gitignoreに記載すること）

```local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "",
    "AzureWebJobsDashboard": "",
    "FUNCTIONS_WORKER_RUNTIME": "java",
    "proxyHost": "Your Proxy Host",
    "proxyPort": "Your Proxy Port",
    "proxyUser": "Your Proxy Username",
    "ProxyPass": "Your Proxy User Password"
  }
}
```

* Functionsでは以下のように記述します

```java
String proxyHost = System.getenv("proxyHost");
String proxyPort = System.getenv("proxyPort");
String proxyUser = System.getenv("proxyUser");
String proxyPass = System.getenv("proxyPass");

if (!StringUtils.isEmpty(proxyHost) && !StringUtils.isEmpty(proxyPort)) {
	System.setProperty("proxyHost", proxyHost);
	System.setProperty("proxyPort", proxyPort);
	if (!StringUtils.isEmpty(proxyUser) && !StringUtils.isEmpty(proxyPass)) {
		Authenticator.setDefault(new Authenticator() {
			@Override
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(proxyUser, proxyPass.toCharArray());
			}
		});
	}
}
```

* mvn testする場合は、local.settings.jsonを読み込まないので環境変数の設定が必要

```
> set proxyHost="Your Proxy Host"
> set proxyPort="Your Proxy Port"
> set proxyUser="Your Proxy Username"
> set ProxyPass="Your Proxy User Password"
> mvn test
```

* mvn packageでテストをスキップする方法

```
> mvn clean package -Dmaven.test.skip=true
```

* ローカル実行とAzureへのデプロイ

```
> mvn azure-functions:run
> az login
> mvn azure-functions:deploy
```
Djangoで開発したアプリをHerokuにデプロイするときにはまったこと

#この記事について
GitHubDesktopを使ってDjangoアプリをHerokuにデプロイするときにはまったことをまとめました。



#出てきたエラー

GithubDesktopで、画面上の Publish branch を押したらこんなエラーが出てきました。

![herokulogin.png](https://qiita-image-store.s3.amazonaws.com/0/206150/c35ed803-a9a7-504d-4ffe-e27aaafcb704.png)

で、もちろんUsernameとPasswordを入れたのですが、Authentication failed となりました。つまりエラーです。
heroku.comなのでherokuのUsernameとパスワードを入れましたが、念のためGithubのそれも入れてみました。が、やはりエラー。
そもそもgit.heroku.comって何ぞや、と思ってブラウザのアドレスバーに打ち込んだら
https://devcenter.heroku.com/articles/git
にリダイレクトされました。
つまり、そんなアドレスはないわけですね。
ではどこからこのgit.heroku.comが出てきたのだろう。。。
そもそも今やろうとしていることは、「Githubへのpush」のはずで、まだこの時点ではherokuは関係ないはずだが。。。
ということは、どこかのファイルに変な記述があるのかなぁ。。。

![herokugit.png](https://qiita-image-store.s3.amazonaws.com/0/206150/15d3d575-4346-11ce-86cd-398aebdbda17.png)

と思ったら、HerokuのWeb画面でこんな記述　↑　がありました。

#解決はこれ
git.heroku.comへのUsernameやパスワードは何だろうと思ってググったところ、stackoverflowで同様の質問を見つけました。

https://stackoverflow.com/questions/30737329/heroku-username-for-https-git-heroku-com-git

これにならい、コマンドプロンプトでherokuにログオン、その後に heroku auth:token とコマンドプロンプトに打ち込み、出てきた英数字（54fc・・・・）をパスワードとして使ったらこのエラーはなくなりました。

![herokuauth.png](https://qiita-image-store.s3.amazonaws.com/0/206150/de5a85f6-520d-7961-6f49-0858af023c6b.png)

しかしその後に別のエラーが出てきて、悪戦苦闘は続きます。。。
ブランチをマージする（Visual studio 2017を使用）

[こちら](https://qiita.com/misuzoo/items/c589cf678e5a83d55c6e)の続きです。
機能追加用のブランチを作成し、機能追加した後、その内容をdevelopブランチにマージしてみます。

#####1.新しく「add1」というブランチを作成

#####2.ブランチ「add1」を選択した状態で、 Mainに以下のようにコードを追加

```c#
      static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            Console.ReadKey();

        }
```

#####3.プロジェクトの[変更]を選択し、上記の変更内容をコミット


「develop」ブランチのMainは以下のコードです。3.のコミット操作を行わずに、「develop」ブランチに切り替えた場合は、「add1」のブランチの変更が反映された状態になっています。

```c#
      static void Main(string[] args)
        {

        }
```

#####4.「add1」のブランチを選択した状態で、[同期]→[プッシュ]を実行
リモートリポジトリにも「add1」ブランチが作成されました。

#####5.ブランチ一覧から「develop」を選択し、右クリックで[マージ元]を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/232585/4f36149c-abc7-2cd1-4e9f-30a2b93d5ed9.png)

#####6.マージするブランチは「add1」を選択
「マージ先となる現在のブランチ」という日本語が少し分かりずらい気もしますが、こちらが変更を取り込んでくる側のブランチになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/232585/ec363f79-be50-61f9-9d7e-1b7e1ad2484e.png)

#####7.[マージ]を実行
マージが成功すると「develop」ブランチのMainに以下のようにブランチ「add1」の変更が反映されているのが確認できます。

```c#
      static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");

            Console.ReadKey();

        }
```
#####8.「develop」を選択した状態で[同期]→[プッシュ]を実行
リモートリポジトリのブランチ（original/develop）へも反映されます。
Node.js v11.0.0でElectronウィンドウが表示されない

こんにちわ。

Node.jsを`v10.2.0 -> v11.0.0`に更新したのですが、そしたらElectronがコケるようになってしまいました。


# 事象
```:CommandPrompt
> node -v
v11.0.0

> electron
Electron 4.0.0-beta.5 - Build cross platform desktop apps with JavaScript, HTML,
 and CSS
Usage: electron [options] [path]

A path to an Electron app may be specified. It must be one of the following:
  - index.js file.
  - Folder containing a package.json file.
  - Folder containing an index.js file.
  - .html/.htm file.
  - http://, https://, or file:// URL.

Options:
  -i, --interactive     Open a REPL to the main process.
  -r, --require         Module to preload (option can be repeated).
  -v, --version         Print the version.
  -a, --abi             Print the Node ABI version.
```
この後、CMDウィンドウからフォーカスは外れるのですが、いくら待っても何も起きません。


# 原因
結論から言うと、`v11.0.0`から`child_process.spawn()`のウィンドウ表示オプションが、デフォルトで非表示モードになってしまった事によります。

Electron起動スクリプトで`child_process.spawn()`が走った際、非表示で実行されてしまう、と言った至極単純な原因でした。

どうりで、プロセス自体は元気に動いてるしエラーログも出ない訳だ...

- [child_process.spawn() - Node.js](https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options)

> [History]
v11.0.0
The windowsHide option now defaults to true.


# 解説
ターミナルからElectronを起動すると、以下のような段階を踏んで、実体の`electron.exe`に辿り着きます。

```
> electron
 node_module/electron.cmd
   node_modules/electron/cli.js
     node_modules/electron/dist/electron.exe
```

`cli.js`に注目。

```js:node_modules/electron/cli.js
#!/usr/bin/env node

var electron = require('./')

var proc = require('child_process')

var child = proc.spawn(electron, process.argv.slice(2), { stdio: 'inherit' })
child.on('close', function (code) {
  process.exit(code)
})

const handleTerminationSignal = function (signal) {
  process.on(signal, function signalHandler () {
    if (!child.killed) {
      child.kill(signal)
    }
  })
}

handleTerminationSignal('SIGINT')
handleTerminationSignal('SIGTERM')

```
`proc.spawn()`のオプションに表示モード指定がありませんね。
これだと非表示モードになってしまいます。


# 解決策(暫定)
```js:node_modules/electron/cli.js
var child = proc.spawn(electron, process.argv.slice(2), { stdio: 'inherit', windowsHide: false })
```
表示モードを指定するだけ。


# 愚痴
こんな原因の為に丸1日費やしてしまったよ！！！

-> GitHubに [Issue](https://github.com/electron/electron/issues/15467) 出しときました。速攻でプルリク出してくれたので次のリリースで修正されると思います。感謝感激。
【初心者】最初のgit pushができない問題に関して

# はじめに
僕は勉強してようやく数ヶ月、ベンチャーで開発をちょっとだけさせてもらっている初心者エンジニアです。
ブログやツイッターで発信らしい発信もしたことがないので、全てのサービスを通じてこのような記事を書くことが初めてです。
最近ずっと僕が躓いていた問題の備忘録として、投稿させて頂きます。

# git pushができない……？
bitbucketを使ってコードを管理しているのですが、最近新しく作ろうとしたコードをpushできずに、右往左往しておりました。
２週間ほど前に、問題は解決したと思われた矢先、昨晩に同じ問題が発生致しました。
夜のほぼほぼ回転しない脳では解決できないと思い、翌日に持ち越し。
しかし、電車の中で閃いたコードを打ってみたら、一瞬で解決しました！

# どういうエラーか
僕は主にrailsを使って開発をします。
rails　newで新しいアプリケーションを立ち上げ、まずはpushしようと思ってpushしました。
その結果、出たエラーがこちら
```fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.```

ん？リモートリポジトリから読み込めていない？それならbitbucketの設定を変えればいいんだ！！
そう思って、僕はbitbucktのssh鍵をいじくり始めました。
ssh鍵の設定の仕方は、また別の記事であげようかな。
というか、たくさんの分かりやすい記事があるので、それを参照に。
ここまでが２週間前の僕。

bitbucketのコードもコピペしてるし、addもcommitもしてるのに……

完全にbitbucktがおかしくなったと勘違いしていました。
会社のbitbucktリポジトリには、pushできるのに。

# そして、解決へ
これは、初心者エンジニアじゃ手に負えん！
gitを使った管理はやめて、コード製作に集中すべきだ！！っと思ってました。
しかし、実態は急転。下記のコードの打ち忘れでした。
>git init

…………はい。

恥ずかしくて、何も言えません。

ただ、同じように躓いている人がいると思うので、投稿してみました。
git initの打ち忘れでこのエラーが出る人なんて、なかなかいないと思いますが……

#　まとめ
初心者はエラーが出ても、どう対処すれば良いか分からないことが多いですよね。
そんな時は、エンジニアの方が身近にいればその人に聞く、いない場合はもう一度同じ手順をやり返す。
最初の段階のエラーって、レベル高いエラーはほぼほぼないんですよね。
自分自身最初の方を振り返って思いますが、１つ１つエラー文を因数分解して、ググってググってコードを打ってエラー出て、またコード打って………
嫌になりますが、この繰り返しですね。

ただ最後に申し上げますと、<strong>レベルの高いエラーは初期段階では発生しない</strong>
コードの打ち忘れだったり、手順を踏み違えてたりというのがほとんどだと思います。

とりあえず、エラーが出た場合、最初からやり直すというのは１つの方法かもしれませんね。


### 最後に
今後もこのように、QiitaとTwitterで初心者向けの記事やつぶやきを上げていこうかと思います。
よろしければ、意見やフィードバック頂きたいです。
僕の記事を参考にする、僕に質問する等も嬉しいです。

日本語力がないので、拙い記事になったかと思いますが、そこらへんの意見も頂けると嬉しいですね！笑

長くなりましたが、最後まで見て頂き、ありがとうございました！！
学生時代に作った学園祭のサイトのお話【フロントエンド編】

2017年当時、在学していた専門学校の学園祭特設サイトを作成したときのお話です（当時意識して作ったポイントなど含めて紹介します）。

※[学生時代に作った学園祭のサイトのお話【バックエンド編】](https://qiita.com/http_kato83/items/c65817d4ceb08ed6eb15)と併せてご覧いただけると幸いです。

# あかん、サイトが重い
ひとまずサイトは完成させてみたものの、ローカルでは読み込みが早くて気づかなかったのですが、画像を多用したサイトとなってしまい、レンタルサーバーで実際にサイトにアクセスすると5〜7秒ほど読み込みに時間がかかっていました。

GoogleのPageSpeed Insightsとにらめっこしながら当時改善させていった記憶が蘇る……

では、実際に対策を施したもの、今となってはこれをやればよかったと思っているもので分けて紹介していきます。

# 実際に行ったサイト軽量化施策
## 透過不要な画像はjpg画像に変換
pngは透過情報を持てたり、画質が劣化（可逆圧縮）しないのが特徴の反面、画像のサイズが大きくなってしまうのがネック。

透過が実際に必要な画像は殆どなかったため、Illustratorで作ってpngで保存した画像をjpgに変換等を行いました。
## 解像度が高い画像はサイズ縮小&圧縮
良い画像を使おうと思うばかり、デジカメや一眼で各ブース・出し物の写真を撮影していたのですが、`max-width`が決まっている画像は思い切ってサイズ縮小&圧縮を行いました。

下記リンクのオンライン圧縮ツールを用いました。
[JPGイメージをオンラインで圧縮する](https://compressjpeg.com/ja/)

## 撮影した画像で不要な領域はトリミング
当然といえば当然ですが、画像の余計な領域はCSSでどうにかするとかではなく、おとなしく画像編集ソフトでトリミングを行いました。

## Webp画像を利用する
PhotoshopのWebPプラグインを利用して更に軽量化を図りました。
[Telegraphics - Free plugins for Photoshop & Illustrator...and other software](http://telegraphics.com.au/sw/product/WebPFormat)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/158800/ce1be264-5c90-6dc2-36b9-ea0731a3c2be.png)
https://caniuse.com/#search=webp

相変わらずのサポート率ですが（Edge対応するの！？）、Chromeを利用している人には効果が大きいと思ったのでサイトメインビジュアルやグローバルナビの画像で採用しました。

こんなかんじでWebP画像を読み込ませる

```html
<picture>
	<source type="image/webp" srcset="/img/header.webp">
	<img src="/img/header.png" alt="">
</picture>
```

これでWebP画像に対応していないブラウザに対応しつつ、Webp画像を読み込めるブラウザはpngの方ではなくWebP画像を読み込んでくれます。

## CDNを利用する
SwiperはCDNで読み込んでいました。

## PDFファイルの圧縮・UA判定
当学園祭特設サイトではパンフレットをダウンロードできるようにしていたのですが、入稿データをそのままpdfファイルにすると数百MBとかになっていたので、pdfの圧縮も行いました。

また、モバイルブラウザではpdfファイルは開けずダウンロードが始まってしまうので、jsでユーザーエージェント判定、モバイルブラウザならリンクをpdfデータから画像データに変更する処理を書いていました。

# したと思ってたけどできてなかった施策
やったつもりなんだけどなぁ〜？

## gzipを用いる
gzipはzipなどと同じ圧縮ファイルの一種、cssやjsをgzip圧縮して.htaccessでgzipファイルを有効にすると利用できる（もちろんレンタルサーバーごとで使えるか使えないか変わってくると思うが）。

## minify化
基本中の基本とかドヤりたかったんだが、できてなかった。
学園祭中でもサイトの修正してて一々minifyするの面倒ってなったからかな…

こういうときタスクランナーを使いこなせていれば……と思う。

# まとめ
これで自分が作った2017年度学園祭特設サイトが今までで一番読み込みも早くなった。
めでたしめでたし。
祝日 (2019年、2020年の特殊なもの)

情報が錯綜していて`2019年 祝日`と検索しても古い記事のままだったりしたため書きました。
誤りがあれば教えて下さい。

## 新元号の発表時期

* 2019/4/1 とのうわさ (2018/5/17の記事)
    * [新元号公表、改元1カ月前に　システム改修対応促す　　:日本経済新聞](https://www.nikkei.com/article/DGXMZO30640720X10C18A5PP8000/)
* 11/6 朝6時のNHKラジオによると、政府は国民生活などの影響を考慮して`少なくとも1ヶ月前に発表することを想定`して準備を進めているとのこと。


## 2019年の特殊なもの

[立皇嗣の礼は20年4月19日に　19年のGWは10連休　　:日本経済新聞](https://www.nikkei.com/article/DGXMZO36403670S8A011C1MM0000/?n_cid=NMAIL007)
以下ページが正しいっぽい
[2019年の祝・休日一覧：2019年のゴールデンウイークは10連休に | nippon.com](https://www.nippon.com/ja/features/h00314/) 

* 10連休
    * 4/27 (土) -
    * 4/28 (日) -
    * 4/29 (月) 昭和の日
    * 4/30 (火) 休日
    * 5/1 (水) 新天皇即位 (改元)
    * 5/2 (木) 休日
    * 5/3 (金) 憲法記念日
    * 5/4 (土) みどりの日
    * 5/5 (日) こどもの日
    * 5/6 (月) 振替休日
* 2019年1度限りの祝日
    * 10/22 (火) 即位礼正殿の儀
* (2019年は天皇誕生日がありません)

## 2020年の特殊なもの

[国民の祝日について - 内閣府](http://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html)

* 天皇誕生日
    * 2/23
* 海の日
    * 7/20 → 7/23に移動 (オリンピック開会式の前日)
* 山の日
    * 8/11 → 8/10に移動 (オリンピック閉会式の翌日)
* 体育の日
    * 10/12 → 7/24に移動 (オリンピック開会式)
{error,eafnosupport}が出た時、erlang gen_udp:sendを使用する時の話

# 結論
ipv4で通信する時はinet optionを使いましょう

# 問題
gen_udp:send/4を使う時```{error,eafnosupport}```が出た
## Server Side

```erlang:server.erl
    {ok, Socket} = gen_udp:open(9999,
                                [binary,
                                 inet6,
                                 ]).
```

## Client Side

```erlang:client.erl
   {ok, Socket} = gen_udp:open(0, [binary, inet6]).
   {ok,Addr} = inet:parse_address("10.12.**.**"). %% ipv4 address
   Ret = gen_udp:send(Socket, Addr, 9999, <<"hi">>).
   %%{error,eafnosupport}
```

## 解決
```erlang:client.erl
   {ok, Socket} = gen_udp:open(0, [binary, inet]).
   {ok,Addr} = inet:parse_address("10.12.**.**"). %% ipv4 address
   Ret = gen_udp:send(Socket, Addr, 9999, <<"hi">>).
   %%ok.
```
## わかったこと
ipv4でudp通信する時、サーバーサイトはinet6 optionにしてもipv4通信を受け入れられますが、クライアントサイトはちゃんとinet optionにしないとダメです
PythonでCLIツールを作成するのにdocoptでパラメータのパーサー作成を自動化する

## 概要

Unity ML-Agentsを利用していて、CLIの実装にdocoptというモジュールを利用していて、パラメータのバリデーションをいい感じにやってくれて便利そうだったので、お試ししてみました。

docopt...
http://docopt.org/


## 使い方

上記サイトをみたらわかると思いますが、CLIのドキュメントをインターフェース定義として、パラメータのパーサーを自動的に定義してくれるみたいです。素敵。

>docopt helps you:
>
>- define the interface for your command-line app, and
>- automatically generate a parser for it.

試しにCLIツールを実装してみます。
仮想環境を作成するか、Dockerを利用するかなどはお好みで。

```sh
> mkdir 任意のディレクトリ
> cd 任意のディレクトリ
> python -m venv venv
> . venv/bin/activate
> pip install docopt
> touch hoge.py
```

```python:hoge.py
from docopt import docopt


if __name__ == '__main__':

  _USAGE = '''
  実行しても何もしないツール

  Usage:
    hoge run <name> [--foo=<n>]
    hoge -h | --help

  Options:
    -h --help     ヘルプを表示
    --foo=<n>     よくわからないオプション [default: 3]
  '''
  params = docopt(_USAGE)
  print(params)

```

はい。

実際に実行してみます。

```sh
> python hoge.py
Usage:
    hoge run <name> [--foo=<n>]
    hoge -h | --help
```

```sh
> python hoge.py run
Usage:
    hoge run <name> [--foo=<n>]
    hoge -h | --help
```

```sh
> python hoge.py run hoge
{'--foo': '3',
 '--help': False,
 '<name>': 'hoge',
 'run': True}
```

```sh
> python hoge.py run hoge --foo 50
{'--foo': '50',
 '--help': False,
 '<name>': 'hoge',
 'run': True}
```

```sh
> python hoge.py run hoge --foo=100
{'--foo': '100',
 '--help': False,
 '<name>': 'hoge',
 'run': True}
```

```sh
> python hoge.py --help
  実行しても何もしないツール

  Usage:
    hoge run <name> [--foo=<n>]
    hoge -h | --help

  Options:
    -h --help     ヘルプを表示
    --foo=<n>     よくわからないオプション [default: 3]
```

Usageに書いているとおりにパラメータ指定がされていないと弾いてくれます。


## まとめ

自前でパーサーを実装すると地味に手間がかかるので、ドキュメントからパーサーを自動生成してくれて、とても素敵です。

実装して確認するのが、面倒！ってときは下記URLでブラウザ上で動作検証をすることができます。ぜひお試しあれ^^

http://try.docopt.org/
fetchに渡すFormDataに key[]=value 方式で配列を詰める

配列をPOSTするとき、jQueryだと以下のように書けます。

```js
$.post('http://example.com', {
  ids: [1,2,3]
})
```

このとき、以下のようなリクエストが送信されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33450/9b7d9fcf-edde-7142-820a-0ce4f0a81032.png)

注目してほしいのはContent-TypeとForm Dataです。Content-Typeは `application/x-www-form-urlencoded` なので、Form送信時に使用されるContent-Typeで、FormDataが送られています。 `key[]=value` 形式の配列はサーバサイドでは `[1,2,3]` のような配列にパースされます。

同じ物をFetch APIを使って、書いてみます。fetchでFormのように送信したい場合、bodyにFormDataオブジェクトをセットすればOKです。したがって、以下のように書けば動きそう…ですが、このコードは↑と同じようには動きません。

```js
const data = new FormData();
data.append('ids', [1,2,3]);

fetch('http://example.com', {
  method: 'POST',
  body: data,
  mode: 'no-cors',
})
```

このとき送信されるリクエストは以下のような形になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33450/6cfb95f7-66f1-9cf1-4cde-94d8382dcc58.png)

Content-Typeはマルチパートになっていますが、フォームとして送信できているので問題ありません。問題はForm Dataで、キーは `ids` 、値には `[1,2,3]` を `toString()` したものが入っています。これはこれで、サーバサイドのプログラムでカンマ区切りをsplitしてもよいのですが、既存APIが `key[]=value` 方式を受け付けるようになっていると、このままでは上手くいきません。

多少トリッキーですが、値が配列である場合にkeyをいじる処理を追加することで、fetch + FormDataで `key[]=value` 方式のデータを送信できます。

```js
function createFormData(data) {
  const form = new FormData();

  Object.keys(data).forEach(key => {
    const value = data[key];
    if (Array.isArray(value)) {
      value.forEach(entry => {
        form.append(key + '[]', entry);
      });
    } else {
      form.append(key, value);
    }
  });

  return form;
}

fetch('http://example.com', {
  method: 'POST',
  mode: 'no-cors',
  body: createFormData({ ids: [1,2,3] }),
});
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33450/d651f959-172f-b39a-d6f4-41d9579f27bc.png)