OmniAICreator/Qiita-1.07M huggingface dataset:
CodePenとアンケートサービスを使ってQiitaの機能を拡張する - アンケートの埋め込み

百見は一ポチにしかずなのでまずはアンケートを読んでポチってみてください。



# nilへの対処法について

下記の3パターンの対処法を見て、後述のアンケートに回答をお願いいたします。

広告ブロックの拡張機能を入れていると下記の項目が表示されないようです。

* google formのアンケート結果
* survay monkeyの埋め込み


## A ネストスタイル

```ruby
def find_friend_message(name)
  unless self.user.nil?
    unless self.user.friends.nil?
      friend = self.user.friends.find_by(name: name)
      unless friend.nil?
        unless friend.message.blank?
          return friend.message
        end
      end
    end
  end
  'no message'
end
```

## B ガードスタイル
```ruby
def find_friend_message(name)
  no_msg = 'no message'

  return no_msg if self.user.nil?

  friend = self.user.friends.find_by(name: name)
  return no_msg if friend.nil?

  friend.message.blank? ? no_msg : friend.message
end
```



## C セーフスタイル
```ruby
def find_friend_message(name)
  self.user&.friends&.find_by(name: name)&.message || `no message`
end
```





# アンケート Google Form
<p data-height="500" data-theme-id="0" data-slug-hash="MVadNZ" data-default-tab="html,result" data-user="k-shimoji" data-embed-version="2" data-pen-title="Google Form" class="codepen">See the Pen <a href="https://codepen.io/k-shimoji/pen/MVadNZ/">Google Form</a> by k.shimoji (<a href="https://codepen.io/k-shimoji">@k-shimoji</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>



# 余談 - Survay Monkeyも使ってみました



<p data-height="500" data-theme-id="0" data-slug-hash="Gxpaqp" data-default-tab="result" data-user="k-shimoji" data-embed-version="2" data-pen-title="Gxpaqp" class="codepen">See the Pen <a href="https://codepen.io/k-shimoji/pen/Gxpaqp/">Gxpaqp</a> by k.shimoji (<a href="https://codepen.io/k-shimoji">@k-shimoji</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>


# 補足
google formの使い方参考：[HipSoftHub - Google formsでアンケートフォームを作ってサイトに埋め込む方法](https://youtukuru.com/google-form)

survay monkey使い方：[Survay Monley - ヘルプセンター](https://help.surveymonkey.com/)

# まとめ

アンケート機能あった方が良いっしょ！codepenマジ便利です。

google formは画像も埋め込めてその点良かったです。

~~survay monkeyは回答がすぐに見れないのが残念でした。その点を除けばこっちの方が使いたくなるような出来なんですけどね。~~

google formも同じ挙動でした。
エンジニアの進化と成功を阻む5年目病とその予防法

こんばんは。10分で生産的なミーティングができるWebサービス「[minmeeting](https://minmeeting.jp/)」を開発している伊勢川です。

<a title="minmeeting - 10分で生産的なミーティングができる会議ツール" href="https://minmeeting.jp/" target="_blank"><img width="100px" src="https://qiita-image-store.s3.amazonaws.com/0/199506/32e65577-a5bb-2c3b-4d30-4690c3c5ce0f.png" /></a>

年度の切り替わりの時期ということで、これまで2年目になるエンジニアの方々に向けて、二年目病とその予防法を取り上げてきました。なかなか好評のようなので、今度はもっと上の年次で<B>30歳も視野に入ってきたころになりやすい5年目病</B>について取り上げたいと思います。またまた余計なお世話で申し訳ありませんが、20代の大事な時期をくだらないつまづきで浪費してほしくないため、あえて書かせていただきます。

# 似非プロフェッショナリズム病
自分の<B>専門家としての成果のみを追求し、仕事の目的を見失う</B>こと。それをここでは「似非プロフェッショナル病」と呼ぶことにします。5年目にもなると、自分しかできないような専門性の高い仕事が増えてくるでしょう。しかし、そこで勘違いをすると、<B>せっかく専門性とスキルが高くても、会社としてはイマイチ使えない人</B>になってしまいます。

## 症例
品質とパフォーマンスが正義。品質=バグがないことと思っており、バグ潰しに余念がない。バグでなければなんでもよく、意味の分からないバグ的な仕様を量産している。

UX=パフォーマンスと信じており、アニメーションのガタつきや、ちょっとでも待たされるUIは親の敵よりも許せない。しかし、画面デザイン・レイアウト・色・フォントなどはデザイナーの仕事だと思っており、多少見づらい画面でも、機能が揃えば自分の仕事は終わりだと思っている。

美しいコードに人生をかけており、美しいコードが書き上がるまで、何度も書き直しをする。スケジュール管理はプロジェクトマネージャーの仕事なので、遅れたのは自分のせいではなく、書き直しをする時間を計画に入れていなかったプロジェクトマネージャーのせいだと思っている。

それどころか、コードの仕上げのプロセスをしらないプロジェクトマネージャーを、ものづくりのいろはも知らないバカだと思っている。エンジニアあがりのマネージャーならまだしも、エンジニアとしてろくな成果も出せずに脱落してマネージャーになったような人は、エンジニアの便利な小間使い程度にしか思っていない。

## 予防法
自分が担当している部分の目的が、全体の目的と同じものと勘違いすることによって、<B>余計なことにエネルギーを費やし、結果として全体の生産性を下げて</B>います。

<B>本当のプロフェッショナルは、全体の目的を達成するために自分の専門性を発揮する人</B>で、自分の専門分野の最適化のみを追求する人ではありません。

ここまで極端ではなくても、私自身も若い頃にそういう感じだった時期があったように思います。

専門性を追求したくなる気持ちはわかります。しかし、それが目的に対してどう役立つのか、<B>目的から考えて他にもっと優先すべきことはないのかを常に考え、お客様や上司に確認</B>をすることで予防することができます。
【d3.js】v3からv4とかv5にしたらいろいろ動かない

# 概要
d3.jsのバージョンを上げたらいろいろ動かなくなったのでメモ。

# 動かなくなったもの
## その１：「attr」が動かない！

```
Uncaught TypeError: Cannot read property 'attr' of null
```
もうちょっと詳しく言うと、attr自体は大丈夫なんですけど、複数の設定を書けなくなったみたいです。
v3ではattrの中に複数の値を詰め込んでいました。

```javascript

.attr({
  aaa: 'aaa',
  bbb: 'bbb',
})
```
みたいに。
それで複数の値を詰め込むためには、attrsにすればいいみたいです。
と言うことで、安直に「attr」を「attrs」にするじゃないですか。
そうしたら、

```
.attrs is not a function
```
と、言われました。
調べてみると、d3-selection-multiってのを使わないとattrsが使えないらしい!?となりました。
加えて、コミッターらしき人が
> d3-selection-multi is available but not recommended by default.

と、デフォルトでは推奨していないとのことで、どうするのが最善の策かがわからずに、とりあえずattrに複数に詰め込んでいるものをattrにするということをすることになりました。

## その２：「ease」が動かない！
そもそも私の使い方に問題があったのかもしれませんが、以下のようにtextに対してeaseを設定していました。

```
.append("text")
.ease("bounce")
```
そうしたところeaseのところでエラーが起きてました。
textではeaseは動かなかったもののrectに対してはeaseは問題なく動きました。
まぁ確かにtextにeaseって変なので、v3ではゆるーく許容されていたことがv4。v5で厳格に適切なプロパティをセットしているかをみるようになっているのかな、と感じました。

## その３：「d3.scale」がundefined！

```
var xScale = d3.scale.linear()
               .domain([0, 50])
               .range([0, 100])
               .nice();
```
ということをしようとしたら、エラーが発生。
調べてみるとv4以降はd3.scaleLinearを使うとのこと。

```
var xScale = d3.scaleLinear()
               .domain([0, 50])
               .range([0, 100])
               .nice();
```
にしたら動くようになりました。
DXLibで画像の透明部分を判定する

DXライブラリには***LoadGraph***や***DrawGraph***,***DrawExtendGraph***といった便利な関数が充実しています。
画像の表示、変形表示などを行うにはこれで十分ですが、これらの関数はピクセル単位でアクセスしたい場面で力を発揮できません。
具体的には、キャラクターの一枚絵をクリックしてリアクションを引き出したいときなどでしょうか。「艦○れ」みたいな。
背景の透過部分では判定させずに、キャラクターの身体をクリックしたときだけ反応させたいようなケースでは、マウスの座標を取得し、画像のそのピクセルのアルファ値(透過度)を調べないといけません。

今回はそんな感じのサンプルコードを作ってみました。

```cpp
#include<Dxlib.h>

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE);
	if(DxLib_Init() < 0)return -1;

	int sHandle = LoadSoftImage("img.png");
	int gHandle = LoadGraph("img.png");
	
	while (!ProcessMessage() && !ScreenFlip() && !ClearDrawScreen()){
		//DrawSoftImageは負荷が非常に高いので、DrawGraphで描画する
		DrawGraph(0, 0, gHandle, TRUE);

		int mouseX = 0, mouseY = 0;
		GetMousePoint(&mouseX, &mouseY);
		int r = 0, g = 0, b = 0, a = 0;
		GetPixelSoftImage(sHandle, mouseX, mouseY, &r, &g, &b, &a);
		//アルファ値は0(透明)～255(不透明)
		if (a > 0){
			DrawFormatString(20, 20, 0xffffff, "ON BODY");
		}
	}

	DxLib_End();
	return 0;
}
```

「img.png」には適当な透過PNG画像を用意してください。

***LoadSoftImage***で読み込んだ画像にはピクセル単位でアクセスすることができます。
***GetPixelSoftImage***の引数にハンドルと座標とRGB値、そしてアルファ値を保存するアドレスを指定します。
取得できるアルファ値は0～255の整数となり、完全に透明な座標では0になります。

気をつけるべき点として、***LoadSoftImage***で読み込んだ画像をそのまま描画する***DrawSoftImage***は**使うべきではない**ということです。理由はマシンへの負荷が非常に高いからとされています。
著者の環境で検証したところ、描画する画像が40枚を超えた辺りで露骨に処理落ちし始めました。これでは実際のゲーム作りに耐えられませんね。

今回は使い慣れている***LoadGraph***で再度画像を読み込みましたが、***CreateGraphFromSoftImage***という関数を使うと、サンプルコード中の「sHandle」から***DrawGraph***で使えるハンドルを作成することができます。ゲームのロード時間を節約したいときなどは、こちらの方が効果的かもしれません。

他にも***LoadSoftImage***は一枚の画像から色違い(2Pカラー)を作成したり、面白い使い方ができそうです。
Let's encrypt で 一時ファイルが作成できない時の対策


[Let's Encrypt ユーザーガイド](https://letsencrypt.jp/docs/using.html)
上記に次の記述があります。

```text
Webroot プラグインは ${webroot-path}/.well-known/acme-challenge に一時ファイル（ワンタイムトークン）
を作成し、Let's Encrypt の認証サーバから HTTP リクエスト（名前解決には DNS のAレコードを使用）
で取得することにより、認証を行います。
```

```text
もし、ウェブサーバの設定によって /.well-known に対して特別な扱いがされている場合には、
/.well-known/acme-challenge 内のファイルに外部からアクセス可能にするために
設定を変更する必要があるかもしれません。
```

/.well-known/acme-challenge にアクセスできるようにするには、

nginx.conf に

```text
location ^~ /.well-known/acme-challenge/ {
     default_type "text/plain";
}
```

を加えます。

nginx.conf が正しいか確認

```bash
sudo nginx -t
```

Nginx の再起動

```
sudo systemctl restart nginx
```

上記は、CentOS 7 で確認しました。

次の記述は誤りです。
>2018年3月以降のLet's Encrypt の証明書は、一時ファイルとして
/.well-known/acme-challenge
を使いません。
Python3でNEMのAPIを叩く-003-NISの状態を詳細に知る

#はじめに
[前回](https://qiita.com/oden_umai/items/390395c9ec7594eb709b)はNISが生きてるか死んでるか調べるAPIを紹介しましたが、今回はNISの状態を詳細に調べるAPIを紹介します。

#使うAPI
/status を使用します。

>![スクリーンショット 2018-03-10 22.50.25.png](https://qiita-image-store.s3.amazonaws.com/0/242994/c76b67f9-bf7b-a084-df8d-082ee1a6e59d.png)
>(解説：和訳)https://www.pr1sm.com/crypto-coin/nem-nis-api-documentation-in-japanese/#status-request

>![スクリーンショット 2018-03-10 22.51.04.png](https://qiita-image-store.s3.amazonaws.com/0/242994/42ea9d08-441a-a9a4-cfbb-e9abbf3edfdf.png)
>(解説：本家)https://nemproject.github.io/#status-request

#サンプル
##コード
実行環境が無い方はpaizaで試せます。
https://paiza.io/ja

```python:Python3
import requests
import json

r = requests.get('http://<サーバー名 or IPアドレス>:7890/status').json()

print(r)
```

##結果の例
```json:json
{"code":6,"type":4,"message":"status"}
```

##解説
前回とほぼ同じコードなので解説はありません。

#結果の値について
以下に詳細が記述されています。
https://www.pr1sm.com/crypto-coin/nem-nis-api-documentation-in-japanese/#nemRequestResult

##code
New Economy Movement(NEM) APIマニュアル和訳を引用します。
>0：不明なステータス。
>1：NISは停止しています。
>2：NISは起動しています。
>3：NISは動作しています。
>4：NISはローカルノードを起動しています(NISが実行中であることを意味します)。
>5：ローカルノードがブートされています(NISが実行中であることを意味します)。
>6：ローカルノードが同期しています(NISが実行中で、ローカルノードが起動していることを意味します)。
>7：NISローカルノードがリモートNISノードを認識しません(実行中および起動中を意味します)。
>(引用元)https://www.pr1sm.com/crypto-coin/nem-nis-api-documentation-in-japanese/#status-request

恐らく３〜６がNISが動いているということだと思います。
３〜６それぞれの違いがいまいち分からないので、サーバーサイドの知識がいるのかも。。。

##type
4：結果はステータスを示します。
つまり、statusリクエストに対する答えが返ってきたということです。

##message
statusを返したよ！ということでしょうか？
いまいちメッセージの使い方が分からんですねー。

#次回
[Python3でNEMのAPIを叩く-004-アカウントデータを取得する
](https://qiita.com/oden_umai/items/51f483e717ee306c2a5f)
ソフトマックス関数とは？＜数行で説明編＞

#一行で説明
いくつかの数字の合計を、１にする関数です。


#例え話

例えば、６００と４００があったら、０．６と０．４にします。

３００と２００の場合も、０．６と０．４にします。

#なぜTensorFlowで必要なのか？
数値を確率で表すときに向いているからです。

　

※楽に読めるように心がけると、数学的には雑な書き方になってしまいました。
※テンソルフローを使おうとして疑問に思った人向けに書いています。
truffle migrate、実は完了していない？

# 完了していなかったmigrate
以前に作ったTokenがmigrateしていたつもりでも、正しく終えていなかった事があった。
githubで共有していたので、他の人に試してもらってた所、addressを取得しようとしたところでエラーが出るそうな。

```
truffle(private)> minaToken.address

Error: minaToken has no network configuration for its current network id (3).
    at Function.getter (/usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:655:1)
    at Function.get (/usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:740:1)
    at Function.getter (/usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:658:1)
    at Function.network (/usr/local/lib/node_modules/truffle/build/webpack:/~/truffle-contract/contract.js:719:1)

truffle(private)> minaToken.deployed().then(inst =>{ tokeninst = inst })
undefined

truffle(private)> tokeninst.address
'0xd5e8************************************'

truffle(private)> minaToken.address
'0xd5e8************************************'
```

こんな感じでdeployed()を一度行うと、出来ている様子。
しかし、自分の方では出来ていたようで色々、新しく作り直してみてみると・・・同様の現象を再現できた。

```失敗例：
$ truffle migrate --network private
Using network 'private'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x050dcb4cd7d1fdf55fb37e0cc7fdd73d6400c7f0bfe6a422a5c53ab2ca9ed67a
  Migrations: 0x0d8c************************************
Saving successful migration to network...
  ... 0xb7b0cb198b37a32ea8f9aad829c2ff5e0affed9c295b22e9254516dac30dbcb2
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying minaToken...
  ... 0x2454b73807213939ed14bfcdf5c7eb9ee5b441266256e9dbaf3d90951a6d311b
  minaToken: 0xd5e8************************************
Saving artifacts...

$
```

どうにも完全にMigrateが完了していない感じ。エラーは出ていない。

```成功例：
$ truffle migrate --network private
Using network 'private'.

Running migration: 1_initial_migration.js
  Deploying Migrations...
  ... 0x42f52edc04e1427c16f79cbd50b9500beb85d0c36b6e2a46f5feac3a25b5b31c
  Migrations: 0x8cda************************************
Saving successful migration to network...
  ... 0xd7bc86d31bee32fa3988f1c1eabce403a1b5d570340a3a9cdba53a472ee8c956
Saving artifacts...
Running migration: 2_deploy_contracts.js
  Deploying minaToken...
  ... 0x16b57d9d2046cea5c90d16bba7a7ff23f14de05fcca5b2eba054161b71a9d378
  minaToken: 0x345c************************************
Saving successful migration to network...
  ... 0xf36163615f41ef7ed8f4a8f192149a0bf633fe1a2398ce001bf44c43dc7bdda0
Saving artifacts...
```

失敗の方は、後半の「Saving successful migration to network...」が出ていないこと。
正常に終了していない感じではある。エラーは出てないし、一体何が違うんだろう・・・？

# 解決したのはしたけれど

```truffle.js
module.exports = {
    networks: {
        private: {
            host: "127.0.0.1",
            port: 7545,
            network_id: "*"
        }
    }
};
```

小一時間、というかほぼ半日程度悩んだ感じで、実験を繰り返して・・・
上手くいかないものは、truffle.jsで```network_id: 3```となっていたところ。
これを”*”にする事でsuccessful migrationが出るようになりました。

Ganacheを使ってる環境だからこの辺りは、問題はないかもしれないけどTest netやMain netだとそれで大丈夫なのだろうか？
【PHP】インポートするCSVのヘッダがテーブルのカラムと同じかチェックを行う処理


# CSVインポート処理とか作るじゃないですか

作るじゃないですか。
というか作らざるを得ない場合があるじゃないですか。
そういう時、登録する前にCSVファイルをあらゆる方向からチェックする必要があると思うので、
取り急ぎ、読み込まれたCSVファイルのヘッダがまずもって想定しているフォーマット通りなのかをチェックする処理を実装してみます。

# CSVヘッダとテーブルのカラムが同じかをチェックする処理の実装

**※前提としてCSVヘッダと登録するテーブルのカラムが同じの場合を想定しています。**

引数`$csvHeaders`と`$columns`には項目名を入れた配列を渡してやる。

```php

/**
 * テーブルのカラムとCSVヘッダとが等しいかのチェック処理
 *  
 * @param array $columns
 * @param array $csvHeaders
 * @return bool
 */
public function isRegisterableThisCsvFile(array $csvHeaders, array $columns)
{
    sort($csvHeaders);
    sort($columns);
    return ($columns === $csvHeaders);
}
```

からくりとしては配列をそれぞれソートして最後に比較し、両方とも全く同じであれば`true`を返す、ということをしてます。

# おわり
- この処理以外にもデータの中身が登録値として正しいかチェックする処理も必要ですな（バリデーション）
- CSVインポート機能って、社内システムとか身内のみ使う想定ならいいけど、toCのサービスとかだと、実装時に胸焼けしそう
JSONの文字列を配列型に変換する(Presto)

## 概要
下記のようなJSON形式の文字列を配列型に変換する方法を調べたのでメモしておく。

## JSON型へキャストする
Prestoで、各値をJSON型に変換する。

```sql
SELECT 
  CAST(NULL AS JSON), -- NULL
  CAST(1 AS JSON),    -- JSON '1'
  CAST('abc' AS JSON),-- JSON '"abc"'
  CAST(true AS JSON), -- JSON 'true'
  CAST(1.234 AS JSON),-- JSON '1.234'
  CAST(ARRAY[1,2,3] AS JSON), -- JSON '[1,2,3]'
  CAST(ARRAY[1,NULL,3] AS JSON), -- JSON '[1,null,3]'
  CAST(ARRAY[ARRAY[1,2], ARRAY[3,4]] AS JSON), -- JSON '[[1,2],[3,4]]'
  CAST(MAP(ARRAY['k1','k2'], ARRAY[1,2]) AS JSON), -- JSON '{"k1":1,"k2":2}'
  json_parse('["a","b"]') -- JSON ["a","b"]
;
```

## 文字列型 > JSON型 > ARRAY<string>に変換する
Prestoに「json_parse」という関数があったので文字列をJSON型にするのに利用する。

```sql
SELECT 
  CAST(json_parse('["a","b"]') AS ARRAY(VARCHAR)) -- JSON ["a","b"]
;
```

## 参考サイト
* [Presto 0.196 Documentation - JSON FUNCTIONS AND OPERATORS](https://prestodb.io/docs/current/functions/json.html)
Jupyter Notebookを用いて、同フォーマットの異なるデータにおけるhtml分析レポートを自動出力する

アウトラインメモです。時間があるときに詳細を書くつもり。

# 概要
- 同フォーマットで複数ある異なる種類のデータに対して、Jupiter Notebookで分析レポートを自動で作成できるようにする。
- 例えば、為替レート(USD/JPY,GBP/JPY...)のような時系列データにおいて、チャートや基礎統計量等、各種指標を見れるようなレポートをそれぞれのレートで自動的に作成したい場合。
 
# 背景
- データを傾向を可視化するのにjupyter notebookを使っていた
- フォーマットは同じだが異なる種類のデータを可視化したい
- 可視化のテンプレートを作って、異なるデータに対して出力結果のhtmlを出力したい
- データ毎にJupyter notebookを実行してhtml出力するのは面倒臭いから自動化したい
- Jupyter notebookには標準入力のようなものがないので、コマンドライン等から引数を取って表示内容を変更できない

# やったこと
- notebookのテンプレートを作成
- notebookテンプレートの入力データは必ず指定フォルダの指定ファイルを参照するようにする
- シェルスクリプトで以下を繰り返す
 1. 指定フォルダのファイルを削除
 2. インプットフォルダからデータを指定フォルダにコピー
 3. nbconvertでnotebookを実行
 4. nbconvertでnotebookをhtml化
インターネットの通信がなんとなく分かるまとめ

# 書いた人と書いた理由
- ヤマシタ
 - 積木製作の新人エンジニア
 - http://tsumikiseisaku.com/
- 書いた理由
 - ネットワーク周りの調査と勉強をした結果を、社内で共有するためにまとめた文章です。
 - 非エンジニアの人ともイメージベースで通信についての知識を共有することが目的です。
- 免責
 - 一次情報が少なくて、自分が専門学校の授業で聞いたうろ覚えの内容をもとに、改めて調べたものをまとめたりしています。間違っていたら指摘してください。
 
# 通信そのものについて
通信を分類するときは「方向性」「時間」「内容」から分類する。

- 接続するとは
 - ネットワークにつながっているほかのコンピュータと通信を行う場合、IPアドレスという顔写真を使って相手がネットワークのどこにいるかを探すところから始まる。
 - これは行方不明の人探しに近い状態で、知り合いや通りすがり、交番などを頼りに、通信相手を知っている人がいないかを聞いて歩くようなもの。
 - ただし、近い過去に似たような問い合わせがあると、特に交番のおまわりさんなどは相手を覚えているので、あまり広い範囲で探し回らなくても出合わせてくれる。
 - IPアドレスが実世界の住所に相当するという説明も間違っていないものの、接続そのものについて考えるときはこういうイメージのほうが近いと思う。


## 方向性による通信の分類
- 単方向通信
 - サーバー・クライアント・モデル。
 - 情報を保存・提供する「提供者（サーバー）」が用意され、そこに「非提供者（クライアント）」がアクションします。
 - 原則的に、クライアントのアクションによってサーバーがサービスの提供を行い、サーバーが主体となってふるまうことはありません。
 - このアクションとは、通信を利用した「働きかけ」であり、この働きかけを行うための窓口として「ポート（港）」を開いておく必要があります。
 - この接続(返答)時間を工夫することで、サーバー側からも働きかけができるようにする方法もあります。詳しくは後述。
 - 他のクライアントと通信するときも間に「特定のサーバー」を挟んで通信するので、エンジニアとしてはサーバーの開発に注力することで接続全体を安定できるなどのメリットがある。
 - ただし、接続の中心になるサーバーへの負担が大きくなりやすいことも問題。
- 双方向通信（P2P式）
 - 今回の主役。WebRTCもP2P方式。
 - 基本的に、自分と相手の双方がアクションを行う通信形式。
 - それぞれがサーバーとクライアント両方の役割をもっていて、自分がアクションするときはクライアントしてふるまい、アクションを受けるときはサーバーとしてふるまいます。
 - 単方向では特定のサーバーに通信が集中したが、P2Pでは別のサーバーでも役割を果たせるように、全体に責任が分散した設計がされるため、負担がどこかに偏るということは少ないです。
 - 動画チャットなどでサービスの利用者同士が通信する場合は、間にサーバーを挟まない分だけ通信速度なども有利。
 - ただし、直接互いの機器がやりとりするため、セキュリティや接続の安定性などについては課題となりやすいです。



## 時間による通信の分類
- 使い捨ての接続
 - 前述の「接続するとは」という説明の通り、人探しをしてから接続をしているが、一時的な伝言くらいの要件なら伝えたあとは相手の居場所などは覚えないし、関係もその場で終わりになります。
 - 何かの事情で再び接続する必要ができた時には、人探しを最初からやることになります。
- 持続的な接続：ソケット
 - 電話のように一瞬で終わらないやり取りをする場合、相手がどこにいるか、自分がどこにいるかを記録して、それを使って行き来する事になります。
 -  仮想的につながっている状態になるため、サーバーの内部で情報の変化が起きた場合などに、サーバーからもアクションがおこせます。
 -  これを使うことで、実質的にクライアント同士の双方向通信ができているようにも見せられます。ニコニコ生放送などはこちら。
 -  ただしあくまで、主体として接続しているのはクライアント。
 -  詳しく調べる場合、ポーリング、ロングポーリングなどの用語から調べましょう。


## 通信の内容による分類
- 通信の工夫
 - 通信によって情報を送る場合は、自分と相手の間でバケツリレーをするような状態になります。
 - 荷物のほうから考えると、送り主から相手に対して、それぞれが個別に移動していくわけです。
 - このとき、インターネットでは荷物を受け取る相手のために「手間がかかるけど確実に順番通り届く工夫」をするかどうかを選べます。
- 早いけど不安定：UDP
 - 面倒な工夫はしません。
 - とにかく手間をかけずに最速で送信して、届いた順番に開封されます。
 - 受け取った側では届いていないものがあっても気づけません。
- 確認方法ありの安全ゆっくり通信：TCP
 - 「手間がかかるけど確実に順番通り届く工夫」をしているほうです。
 - 具体的には、何個ある荷物の何番目なのかという情報や、他の荷物と一緒に開封したときにあらわれる合言葉(Hash)を使った、順番や中抜けの確認が行われます。

 

# 参考資料(18/3/13)
- 資料名 (googleによる最終更新日)
  - 対象ページURL
- Peer to Peer
 -https://ja.wikipedia.org/wiki/Peer_to_Peer
- Polling (computer science)
 - https://en.wikipedia.org/wiki/Polling_(computer_science)
- HTTP/2における双方向通信とgRPCとこれから
 - https://qiita.com/namusyaka/items/71cf27fd3242adbf348c
Mac+Java9+UnityでAndroidビルドする時のエラーの対処法

次のようなNoClassDefのエラーが出て、Androidビルドができなくなった時の対処法です

```
CommandInvokationFailure: Unable to list target platforms. Please make sure the android sdk path is correct. See the Console for more details. 
/Users/takezoux2/Library/Android/sdk/tools/bin/avdmanager list target -c
stderr[
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.XmlSchema
	... 5 more
]
stdout[
]
exit code: 1
```

## 原因

ビルドの途中でsdkmanagerやavdmanagerのコマンド実行をする際にデフォルトのJavaが使われることになるが、Java9の場合JigSawにより、Java8までデフォルトで含まれていたクラスが含まれなくなったため発生しています。


## 対処方法

### 1. (これはやってると思いますが)UnityのSDKの設定をjava1.8にする

Unity>Preferences>ExternalToolのJavaSDKの項目でJDK1.8系を指定して下さい。

### 2. avdmanagerやsdkmanagerを修正し、XML系のモジュールを追加

```
~/Library/Android/sdk/tools/bin/avdmanager
~/Library/Android/sdk/tools/bin/sdkmanager
```
をそれぞれテキストエディターで開き、該当箇所を下のようにそれぞれ修正して下さい。

```bash:avdmanager
# Add default JVM options here. You can also use JAVA_OPTS and AVDMANAGER_OPTS to pass JVM options to this script.
#DEFAULT_JVM_OPTS='"-Dcom.android.sdkmanager.toolsdir=$APP_HOME"'
DEFAULT_JVM_OPTS='"-Dcom.android.sdkmanager.toolsdir=$APP_HOME" -XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'
```

```bash:sdkmanager
# Add default JVM options here. You can also use JAVA_OPTS and SDKMANAGER_OPTS to pass JVM options to this script.
# DEFAULT_JVM_OPTS='"-Dcom.android.sdklib.toolsdir=$APP_HOME"'
DEFAULT_JVM_OPTS='"-Dcom.android.sdklib.toolsdir=$APP_HOME" -XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'

```

以上

### 参考

https://stackoverflow.com/questions/47150410/failed-to-run-sdkmanager-list-android-sdk-with-java-9
Python3 初心者　簡単プログラム２(ファイル名前変更)  Udacity 

<目的>
営業職からIT業界転職のため、習った知識に関する感想、疑問点を記載します。
今回の投稿が、自身の更なる知識の向上、そして私と同じようにプログラミングに興味を持った人のためになれば嬉しいです。
尚、私自身初心者のため、誤った内容等がある場合がございます。ご了承ください。
訂正などがあれば、気軽にコメント頂ければ嬉しいです。


＜学んだこと＞
・特定のファイルを指定できる　os.listdir()

・指定したファイルの名前に数字が含まれている場合、数字を除外した文字だけの名前に変更できる translate関数

＜教材＞
無料
Udacity  Programming Foundation Lesson2
https://classroom.udacity.com/courses/ud036/lessons/993460168/concepts/9977893180923


講義内での変更点
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12149642442

<coding>
![rename_file.png](https://qiita-image-store.s3.amazonaws.com/0/240318/3b1a9c10-7dcc-935f-a849-47df1e1b39d4.png)

<疑問点>
アプリ開発や応用などでこれらの知識がどのように応用されるのかが気になった
cocoapodsで「fix failed to connect to github~」というエラーに遭遇した

# エラー遭遇
2018/3/13

いつもどおりpod installしようと思ったらこんな表示が...

```ruby:pod-install.rb
[!] Unable to satisfy the following requirements:

- `SwiftLint` required by `Podfile`
- `SwiftLint (= 0.25.0)` required by `Podfile.lock`

None of your spec sources contain a spec satisfying the dependencies: `SwiftLint, SwiftLint (= 0.25.0)`.

You have either:
 * out-of-date source repos which you can update with `pod repo update` or with `pod install --repo-update`.
 * mistyped the name or version.
 * not added the source repo that hosts the Podspec to your Podfile.

Note: as of CocoaPods 1.0, `pod repo update` does not happen on `pod install` by default.

```

pod repo updateすると...

```ruby:pod-repo-update.rb
Updating spec repo `master`
[!] Failed to connect to GitHub to update the CocoaPods/Specs specs repo - Please check if you are offline, or that GitHub is down
```

😵😵😵😵😵？？？？？


# 解決法
これに従ったら治りました。

https://medium.com/@ejhsu/fix-failed-to-connect-to-github-to-update-the-cocoapods-specs-specs-repo-error-6005d96c54f2
Flow逆引きReact関連タイプ３つ

注: Flow v0.68.0
注: 全部ここに書いてあることです。
https://flow.org/en/docs/react/types/


Flowは[UtilityType](https://flow.org/en/docs/types/utilities/)など便利な機能があります。
その中でもReact関連のタイプもかなり便利なのでシチュエーション別に3つ紹介したいとおもいます。


# 1. コンポーネントが受け取るプロパティの型を参照したい
> React.ElementProps<typeof Component>

```js
import MyComponent from '.....';

function getPropsForMyComponent() React.ElementProps<typeof MyComponent> {
 ....
}
```

これがないと、 `MyComponent`のプロパティの型を`export type`しなければならない。

UtilityTypeの`$Shape`と組み合わせたりすると便利な場面もあるとかないとか。

```jsx
import MyComponent from '.....';

type MyComponentProps = React.ElementProps<typeof MyComponent>;

function update(diff: $Shape<MyComponentProps>)  {
  const newProps = Object.assign({}, props, diff);
}
```
※ [$Shapeのドキュメントはまだない](https://github.com/facebook/flow/pull/5706
)みたい

# 2. プロパティの型をインターフェース的につかって抽象化したい

> React.ComponentType\<Props\>

これはマニアックなシチュエーション・・・。
こんなことしたくなること自体、なんか辛い目にあってるかもしれない。

```jsx

type CommonProps = {....};

function A(props: CommonProps) {...}
function B(props: CommonProps) {...}

function getComponent(....): React.ComponentType<CommonProps> {
  return A or B;
}

function C() {
  const props: CommonProps = {....};
  const Component = getComponent(...);
  return <Component {...props} /> ; // <- この行のためのComponentType
}
```

Reactでどんだけ複雑なUI作ろうとしてんだよっていうツッコミが聞こえてきますが、Reactで継承を使って多様性を実現するぐらいなら、CompoentTypeを使うほうがReactらしくて良いのかなと思います。



# 3. props経由でコンポーネントを指定させたいが、デフォルトはdivな変数に型を付けたい
> React.Node

```jsx
function A({component}) {
  const Component: React.Node = component || 'div';
  render (
    <Component>FooBar</Component>
  );
}
```

外からコンポーネントを渡せるような仕組みにしたいときに出番がある型ですね。
[react-transition-groupのcomponentプロパティ](https://reactcommunity.org/react-transition-group/#TransitionGroup-prop-component)みたいなケースのことです。


# まとめ
FlowはさすがにFacebookが仕切ってるだけあって、React専用の便利な機能が組み込まれています。

今回はその中から、ちょっとしたデザインパターンを適用しようとしたときに出番がありそうな、 `React.ElementProps<typeof X>`, `React.ComponentType<X>`, `React.Node` を紹介しました。

ReactつかうならやっぱFlowがいいなぁ。
micro:bitのカスタムブロック(Custom blocks)の表示方法

#micro:bitのカスタムブロック(Custom blocks)のコードの表示方法
JavaScriptモードで左下にある
　「エクスプローラー」
を選ぶと
　「custom.ts]
の中にカスタムブロックのコードが入っている。

![dess - コピー.jpg](https://qiita-image-store.s3.amazonaws.com/0/181708/2097e672-43b8-af95-06c8-ca202f190844.jpeg)


詳細説明はこちら
　　https://makecode.microbit.org/blocks/custom
『DOM』で使用できる代表的なメソッド(memo)

##要素の取得
| 式 | 意味 |
|:--|:--|
| document.getElementById(id) | 『document』から、指定『ID』の要素を取得 |
| element.getElementsByTagName(タグ名) | 指定タグ名の要素の配列を取得 |
| element.getElementsByName(nameの値) | 指定『name』属性の要素の配列を取得 |
| element.getElementsByClassName(classの値) | 指定『class』属性の要素の配列を取得 |
| element.querySelector(セレクタ) | 指定『セレクタ』の要素の配列を取得 |
| element.parentNode | 親要素を取得 |
| element.childNodes | 子要素の配列を取得 |
| element.firstChild | 最初の子要素を取得 |
| element.lastChild | 最後の子要素を取得 |
| element.previousSibling | 1つ前の要素を取得 |
| element.nextSibling | 1つ後の要素を取得 |

##要素内のHTMLやテキストにアクセス
| 式 | 意味 |
|:--|:--|
| element.innerHTML | 要素内のHTMLの文字列 |
| element.textContent | 要素内の文字列のみ |
例

```
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        aaa<div>bbb</div>ccc
 
        <script>
        alert(document.body.innerHTML);
        alert(document.body.textContent);
        </script>
    </body>
</html>
```

##要素内の属性にアクセス
| 式 | 意味 | 使い方 | 説明 |
|:--|:--|:--|:--|
| element.属性名 | 属性の参照 | a = element.id; | 変数『a』に『id』の値を入れる |
| element.id = a; | 『id』に変数『a』の値を入れる |
| element.getAttribute(属性名) | 属性の取得 | a = element.getAttribute("id"); | 変数『a』に『id』の値を入れる |
| element.setAttribute(属性名, 値) | 属性の設定 | element.setAttribute("id", a); | 『id』に変数『a』の値を入れる |

##要素の追加

|式 |	意味 |
|:--|:--|
|element.createElement(タグ名) |	『タグ名』の要素の作成|
|element.createTextNode(文字列) |	文字列要素の作成|
|element.appendChild(要素) |	要素を、子要素として追加|

例

```
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        aaa<div>bbb</div>ccc
 
        <script>
        alert(document.body.innerHTML);
        alert(document.body.textContent);
        </script>
    </body>
</html>
```



参考:https://crocro.com/write/manga_javascript/wiki.cgi?p=rewrite_web_page
アプリをArchiveするときに No accounts with iTunes Connect access というエラーが出てアップロードできない時

No accounts with iTunes Connect access have been found for "<team name>". iTunes Connect access is required for App Store Distribution.

証明書やプロビジョニングプロファイルに何も問題ないのに上記のエラーでアップロードができない時。
こういうときはマックを再起動すると直ります。
[tensorflow] CNN model構築

# tensorflowでMNISTデータセットを使った数字認識のためのCNNモデル構築
[参考 : https://github.com/tensorflow/models/tree/master/official/mnist](https://github.com/tensorflow/models/tree/master/official/mnist)

```python:python
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

class Model:

  def __init__(self, data_format):
    if data_format == 'channels_first':
      # NCHW : [入力数, チャンネル数, 高さ, 幅]
      # GPU向け、sess.run()などでsliceしたデータが見れない
      # lenaだったら[-1, 3, 512, 512], -1は入力数を意味
      self._input_shape = [-1, 1, 28, 28]
    else:
      # NHWC : [入力数, 高さ, 幅, チャンネル数]
      # CPU向け、sess.run()などでsliceしたデータが見れる
      # lenaだったら[-1, 512, 512, 3], -1は入力数を意味
      assert data_format == 'channels_last'
      self._input_shape = [-1, 28, 28, 1]

    # Neural Networkの構成要素の定義
    # hidden layer 1 : Conv2D (output : 32次元, conv窓大きさ : 5ピクセル)
    # conv mode : same (zero padding), validだとpaddingしない
    # relu : activation関数で負の入力を0にする
    self.conv1 = tf.layers.Conv2D(
        32, 5, padding='same', data_format=data_format, activation=tf.nn.relu)
    self.conv2 = tf.layers.Conv2D(
        64, 5, padding='same', data_format=data_format, activation=tf.nn.relu)
    # output 1024
    self.fc1 = tf.layers.Dense(1024, activation=tf.nn.relu)
    # output 10 (labels)
    self.fc2 = tf.layers.Dense(10)
    # 0.4の確率で入力を0にする
    self.dropout = tf.layers.Dropout(0.4)
    # (2, 2)ブロックでscanしてmaxを取る
    self.max_pool2d = tf.layers.MaxPooling2D(
        (2, 2), (2, 2), padding='same', data_format=data_format)

  def __call__(self, inputs, training):
    # inputs : (5000, 784)
    y = tf.reshape(inputs, self._input_shape)
    # (5000, 28, 28, 1)
    y = self.conv1(y)
    # (5000, 28, 28, 32)
    # if mode -> 'valid' : (5000, 24, 24, 32)
    y = self.max_pool2d(y)
    # (5000, 14, 14, 32)
    y = self.conv2(y)
    # (5000, 14, 14, 64)
    y = self.max_pool2d(y)
    # (5000, 7, 7, 64)
    y = tf.layers.flatten(y)
    # (5000, 3136)
    y = self.fc1(y)
    # (5000, 1024)
    # testingだとdropoutしない
    y = self.dropout(y, training=training)
    # (5000, 1024) : 0の数が0.4倍増える
    return self.fc2(y)
    # (5000, 10)

mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

# (5000, 784)
val_images = mnist.validation.images
val_labels = mnist.validation.labels

model = Model('channels_last')
logits = model(val_images, training=True)
```

#途中でデータを見たいとき
```python:python
with tf.Session() as sess:
   sess.run(tf.global_variables_initializer())
   tmp = sess.run(y)
   print(tmp)
   cv2.imshow('', tmp)
   cv2.waitKey(0)
```
これ知るとスッキリ!!わかるようでわからなかったFireBaseとAnalyticsの対応関係 ~ 各機能の制限とTips ~


## Event（イベント）
[ 概要 ]
ボタンを押したとか、ページが読み込まれたなどのデータです。
Google AnalyticsのWeb版でいうイベントやPV、アプリ版でいうイベント、スクリーンビューのようなものです。

開発者が設定するものと、firebaseが自動で取得してくれるものがあります。
参考: [Firebaseで自動取得されるイベント](https://support.google.com/firebase/answer/6317485?hl=ja)
`first_open` `session_start` `screen_view` はどのアプリでもよく使うイベントかと思います

[ 制限 ]
500イベントまで

[ Tips ]
webviewのurlごとなどでeventを発生させると、すぐに500を超えてしまします
urlはWebviewイベントのイベントパラメータとして設定しましょう
webview内のイベントやユーザープロパティの設定は [WebView でアナリティクスを使用する](https://firebase.google.com/docs/analytics/ios/webview?hl=ja) を参考にすると良いと思います。
[画面表示の追跡方法](https://firebase.google.com/docs/analytics/screenviews?hl=ja)を参考にすると、screen_viewに名前をつけることが可能です


## Event Parameter（イベントパラメータ）
[ 概要 ]
イベントに付与するメタ情報です。
Google Analyticsのイベントラベルやコンテンツグループのようなものです。
このイベントパラメータを管理画面上で見れるようにするには、パラメータ レポートの設定を行う必要があります。

[ 制限 ]
1イベント25パラメータまで

（パラメータレポート）
テキスト 10パラメータまで
数値 40パラメータまで

[ Tips ]
Big Queryにexportする分には1イベント25までですが、firebase analyticsで閲覧できるのは全部で50個までです
Google Analyticsのスクリーンビューページと同じように、スクリーンビューのアクセス数を一覧でみるためには、 `screen_view` の `firebase_screen_class` をパラメータレポートとして登録する必要があります


## User Property（ユーザープロパティ）
ユーザーに付与するメタ情報です。
Google Analyticsのカスタムディメンションのようなものです。

[ 制限 ]
25個まで

[ Tips ]
- イベントに紐づいて送信されるので、level2以上のユーザーは level >= 2で取得できますが、level2以下のユーザーは level != 2 などnotで検索しないといけない
- コードで設定しても、管理画面でも同じ名前で登録をしておかないと管理画面上で利用することができません。


## Audiences（オーディエンス）
ユーザーをグループしたものです。
Google Analyticsのセグメントのようなものです。
単純増加するようなプロパティxxxの回数などでグルーピングするのが好ましいです。
（増減するものは一度でもクリアした人が対象となる　という制約上難しいです）

[ 制限 ]
50個まで

[ Tips ]
条件を1度でもクリアした人が対象になるので、公開・非公開などステータスがいったりきたりするようなものには不向きです。

## Funnel（ファネル）
コンバージョンへの到達プロセスです
Google Analyticsの目標到達プロセスのようなものです。

[ 制限 ]
見つけられなかった

[ Tips ]
Open Funnelという形式らしく、A > B > Cという到達プロセスに対して、CのイベントはBを経由していなくても計上されてしまいます。
A > B > Cで、CはBを経由したことを保障したい場合は、それ専用のイベントを作成する必要があります。

参考: [Firebase Analyticsの目標到達プロセスの誤解](https://qiita.com/hinom77/items/0a7c360686337ba70fed)

## Cohorts（コホート）
アプリの継続率を示すコホートを表示できる画面です。
Google Analyticsのコホートと同様です。

[ 制限 ]
特に見つけられなかった

[ Tips ]
特になし

## Attribution（アトリビューション）
どの広告がインストールなどのコンバージョンに寄与したかがわかる画面です。
Google Analyticsの集客・キャンペーンのようなものです。

[ 制限 ]
- 対応している広告ネットワークは2018年3月現在、60個です
- first_open のアトリビューション期間は 30 日です。これ以降のアプリ内コンバージョンのアトリビューション期間はすべて 180 日です。

[ Tips ]
特になし

## 最後に
Google Analyticsとはデータの持ち方が違うので、できること・できないことありますが、ユーザープロパティやオーディエンスをpush通知でも使えたり、何かと便利です
Enjoy Firebase Life
docker-composeで ERROR: In file './docker-compose.yml', service 'ports' must be a mapping not an array. が出た時の対処

おもむろに `docker-compose up` したらエラーが出て困ったので原因を書いておく

# エラー内容

```bash
docker-compose up
ERROR: In file './docker-compose.yml', service 'ports' must be a mapping not an array.
```

# 原因
docker-compose.ymlのインデントがおかしかった

こんな感じだったんだけども、 `privileged` 以下のインデントが1個足りてない

``` 間違ったdocker-compose.yml
version: "3.3"
services:
  test-server:
  privileged: true
  build:
    context: .
  env_file: .env
  ports:
    - "8080:80"
  volumes:
    - ./src:/app:cached
  working_dir: /app/
  command: pwd
```

正しくはこう

``` 正しいdocker-compose.yml
version: "3.3"
services:
  test-server:
    privileged: true
    build:
      context: .
    env_file: .env
    ports:
      - "8080:80"
    volumes:
      - ./src:/app:cached
    working_dir: /app/
    command: pwd
```
Windows で conda install したのに ImportError: No moduleな時のメモ

自分用です。

###チェック用のスクリプトを作る

```python:check.py
import sys
print(sys.prefix)
```

###実行してみる

```
C:\> check.py
C:\Python27

C:\> python check.py
C:\Users\taro\AppData\Local\Continuum\Anaconda3
```

違う！

###それぞれのモジュールをチェック

```
C:\> conda list -p c:\Python27

C:\> conda list -p c:\Users\taro\AppData\Local\Continuum\Anaconda3
```

###パスを指定してモジュールを追加する

```
C:\> conda install -p c:\Python27 xxx

または

C:\> conda install -p c:\Users\taro\AppData\Local\Continuum\Anaconda3 xxx
```
Jenkinsのジョブ設定をExport/Importする

JenkinsのAPIを使ってジョブ設定をインポートすることができたのでそのメモです。
異なる環境に設定を移行したい場合などに使えそうです。
※ Jenkins 2.52 で動作しました。

# 移行元のジョブの設定をXMLで取得する
* (移行元ジョブのURL)/config.xml にGETリクエストすると取得できます。

# 移行先Jenkinsの"crumb"を取得する
* JenkinsにPOSTリクエストをするための情報(=crumb)を取得します。
    * CSRF対策としてcrumbを付加する必要があるようになっているようです。
    * これがないと `No valid crumb was included in the request` というエラーが返ります。
* (ユーザー名):(パスワード)@(JenkinsHost)/crumbIssuer/api/xml にGETリクエストすると以下のようなレスポンスが得られます。

```xml
<defaultCrumbIssuer_class="hudson.security.csrf.DefaultCrumbIssuer">
  <crumb>1111222233334444</crumb>
  <crumbRequestField>Jenkins-Crumb</crumbRequestField>
</defaultCrumbIssuer>
```

# 移行先Jenkinsに空のジョブを作成する
* インポートさせるジョブを作ります。

# 移行先ジョブに設定をインポートする
* (移行先ジョブのURL)/config.xml にPOSTリクエストします。
* リクエストヘッダに先ほど取得したcrumbをセットします。
    * 先ほどの例だと `Jenkins-Crumb: 1111222233334444` となります。
* リクエストボディは移行元のジョブから取得したXMLです。
* POSTリクエストが成功すると、XMLの内容がジョブの設定に反映されます。

# 参考にしたページなど
* [Jenkins \-> 403 No valid crumb was included in the request](https://github.com/spinnaker/spinnaker/issues/2067)
* [Jenkins REST API Create job](https://stackoverflow.com/questions/38137760/jenkins-rest-api-create-job)
Kubernetes 対応の分析フレームワークなど

Kubernetes でデータ分析の環境を組む流れができてきましたので、関連プロジェクトを列挙しておきます。

# Kubernetesネイティブ環境

## Kubeflow
[GitHub kubeflow - Machine Learning Toolkit for Kubernetes](https://github.com/kubeflow/kubeflow)

Tensor Flowや対応する設定が施されたJupyterノートブックまでを含むツールスタック。

## Spark on Kubernetes

[Apache Spark on k8s](https://apache-spark-on-k8s.github.io/userdocs/running-on-kubernetes.html)
Sparkプロジェクトでオフィシャルにkubernetes上での動作に対応しています。

## Apache Airflow

[Apache Airflow](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=71013666)
Pythonベースのワークフローフレームワーク。ネイティブのkubernetesエグゼキュータ（パイプライン）を提供。

## GPUs on GKE
[GPU on google kubernetes](https://techcrunch.com/2018/02/12/gpus-on-googles-kubernetes-engine-are-now-available-in-open-beta/)
GKEにてGPUノード上で機械学習などを動かすための対応


# オープンソース

## Seldon Core
[seldon-core - Machine Learning Deployment for Kubernetes](https://github.com/SeldonIO/seldon-core)
機械学習実装。

## Polyaxon
[polyaxon](https://github.com/polyaxon/polyaxon)
大規模ディープラーニング環境を構築するための実装。

# 商用

## RiseML
[RiseM L- Deep Learning Platform for Kubernetes](https://riseml.com/)
GPUクラスタ上へ展開できるシンプルなディープラーニング用実装

## ML Lambda
[ML Lambda - Machine Learning serving cluster](https://hydrosphere.io/ml-lambda/)
Spark ML, Tensor Flow, shikit Learnなどをリアルタイムなクラスタ環境で実装したもの
Rails Mountable Engineで追加したコントローラーを、本体でテストしたい

rails montable engineでrouteとcontrollerを追加したが、本体のrspecでテストしようとするとこんな感じのエラーがでる。

```
undefined local variable or method `hogehoge_path' for #<RSpec::ExampleGroups::HogeHoge::POSThogehoge:0x007f8344beaba8>
```

でもrakeコマンドで確認するとちゃんと設定できている。

```bash
bundle exec rake routes | grep hogehoge
# => hogehoge POST /hogehoge/fuga(.:format) hogehoge#fuga
```

`rails_helper.rb`でこんな風に呼んであげるとうまく動く。

```spec/rails_helper.rb
RSpec.configure do |config|
  config.include Hoge::Engine.routes.url_helpers
end
```

参考
[How to test routes in a Rails 3.1 mountable engine
](https://stackoverflow.com/questions/7691594/how-to-test-routes-in-a-rails-3-1-mountable-engine)


ちゃんと確認しては無いが、capybaraと一緒に使うとうまく動かないときがある。
そんなときは、使いたいspecファイルの`before`の中で呼ぶ。

```ruby
RSpec.describe "HogeHoge", type: :request do
  describe "POST /hogehoge/fuga" do
    before do
      RSpec.configure do |config|
        config.include Hoge::Engine.routes.url_helpers
      end
    end
    
    it { hogehoge }
  end
end
```
WordPress内でGooglemap APIを使用、記事内のmap表示速度をあげるにはどうすれば？

【質問】
WordPressを使用
プラグイン：Simple Mapを使用

マップ表示の為にGooglemap APIを使用していますが、投稿画面のマップの表示が遅く感じます。

テーマ編集の言語の変更及び、Googlemap API内で表示速度をあげる方法はないでしょうか？
分かる方いらっしゃいましたら、ご教授願います。
初心者　Python　　簡単プログラム 


Python 独学初心者です。

学習過程で、一つプログラム(?)を作れました！
Python　ダウンロードした後に、IDEを利用して簡単に作れました！
プログラムの説明を下に記載しました。

興味のある方は無料オンライン講座に沿って簡単にできますので、初心者の人は試しにチャレンジしてみてください！

参考URL
https://classroom.udacity.com/courses/ud036


完成：
指定した時間を過ぎると、設定したyoutubeにある音楽を流す
一回だけでなく、繰り返し行うことも可能
![miniproject1.png](https://qiita-image-store.s3.amazonaws.com/0/240318/08f368c6-272b-a5c4-85b5-cf9082238175.png)
[tensorflow] MNISTデータセットの分析

#tensorflowでMNISTデータセットを使う

```python:python
from tensorflow.examples.tutorials.mnist import input_data
import cv2
import numpy as np

# なかったら自動でダウンロードされる
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

# 訓練
tr = mnist.train.images
# 試験
te = mnist.test.images
# 評価
va = mnist.validation.images

# (55000, 784)
print(tr.shape)
# (10000, 784)
print(te.shape)
# (5000, 784)
print(va.shape)

# (10000, 784) -> (10000, 28, 28)
te = np.reshape(te, (-1, 28, 28))

# numpyでsave
np.save('example.npy', te)
# numpyでload
te = np.load('example.npy')

# 7が表示される
cv2.imshow('', te[0,:,:])
cv2.waitKey(0)
```
#MNISTの構成
mnist.train
mnist.test
mnist.validation
mnist.(..).images
mnist.(..).labels
開発や業務で使うために入れた便利ツール達

# Everything

高速検索ツール
超便利、結構使う

https://tonari-it.com/file_search_everything/

# DiskInfo3

ディスク解析ツール
HDDの容量が食われてるときとかに見やすくどこが食ってるのかを見れる。
ほしい時に欲しいけど普段は使わない。

https://forest.watch.impress.co.jp/library/software/diskinfo/

# WinMerge

差分表示&マージツール
たまに使うけどソースツリーとかで作業してると殆ど使わない。

http://www.geocities.co.jp/SiliconValley-SanJose/8165/winmerge.html

# ScreenToGif

デスクトップの操作をGIFアニメで録画できるソフト。
ツールの操作とか少し上げたい時に使ったりもした。
使用頻度は高くなかった。

https://freesoft-100.com/review/screentogif.html

# rapidee

環境変数をいじるためのソフト。
いじりたい時はこれ使ってたけどそもそもそこまでいじりたい頻度が高くない。
Win10使うようになれば要らない子かも

http://www.softantenna.com/wp/windows/rapid-ee/

# OBS Studio

録画録音スクリーンキャプチャ

https://www18.atwiki.jp/live2ch/pages/491.html

# MAMP

Webサイトの開発サイトとかで使ったりした。

https://techacademy.jp/magazine/5102


# FreeCommander

タブで開けて2分割で並べられるエクスプローラ
物自体の使い勝手は結構良いほうなんだけどどうしてもデスクトップとかツールで開くのはエクスプローラーだから使いにくい。
開発と本番で場所が分かれてるときとかは超便利。
2つを並べて1窓で置いておけるから。

http://digital.knot-inc.co.jp/misc/理想のファイラーfreecommander/

# Rekisa

差分表示ソフト
マージもできるやつを入れたら使わなくなった。
3つまで並べられるから複数パターンのログの流れを見たいときとかに欲しくなるときもあった気がする。

http://frozenlib.net/rekisa/
PHP5.6(Windows10)でphp_curl.dllを機能させる

とりあえずこれで動いたのでメモ

```php.ini
;extension=php_curl.dll
extension=php_curl.dll
```
Windows\system32 に以下を入れる（ファイルは phpフォルダにある）
libssh2.dll
ssleay32.dll
libeay32.dll
php_curl.dll

apache24/bin に以下を入れる
libssh2.dll
【swift】和暦→西暦、西暦→和暦に変換するStringのExtensionの書き方

和暦→西暦、西暦→和暦に直すやり方です。

## コード

```swift

import Foundation
import UIKit

extension String {
    
    // ロケーション
    static let jaLocale = Locale(identifier: "ja-jp")
    
    /// 和暦の日付文字列を西暦の日付文字列に変換する
    ///
    /// - Returns: 西暦の日付文字列
    func convertWarekiToGregorian() -> String? {
        
        let jaLocale = String.jaLocale
        let jaCalender = Calendar(identifier: .japanese)
        
        let formatter = DateFormatter()
        formatter.calendar = jaCalender
        formatter.locale = jaLocale
        let form = DateFormatter.dateFormat(fromTemplate: "GyM", options: 0, locale: jaLocale)
        formatter.dateFormat = form
        guard let date = formatter.date(from: self) else {
            return nil
        }
        return date.toString(dateFormat: "yyyy年M月", identifier: .gregorian)
    }
    
    /// 西暦の日付文字列を和暦の日付文字列に変換する
    ///
    /// - Returns: 和暦の日付文字列
    func convertGregorianToWareki() -> String? {
        
        let jaLocale = String.jaLocale
        let greCalender = Calendar(identifier: .gregorian)
        
        let formatter = DateFormatter()
        formatter.calendar = greCalender
        formatter.locale = jaLocale
        formatter.dateFormat = "yyyy年M月"
        guard let date = formatter.date(from: self) else {
            return nil
        }
        return date.toString(dateFormat: "Gy年M月", identifier: .japanese)
    }
}

extension Date {
    
    /// 指定された文字列に変換する
    func toString(dateFormat: String, timezone: TimeZone? = nil, identifier: Calendar.Identifier) -> String? {
        
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat
        if let timezone = timezone {
            formatter.timeZone = timezone
        } else {
            formatter.timeZone = TimeZone(abbreviation: "JST")
        }
        formatter.locale = Locale(identifier: "ja-jp")
        formatter.calendar = Calendar(identifier: identifier)
        return formatter.string(from: self)
    }
}

// 西暦→和暦
let seirekiDay = "1994年12月"
seirekiDay.convertGregorianToWareki() //→ "平成6年12月"
// 和暦→西暦
let warekiDay = "平成6年12月"
warekiDay.convertWarekiToGregorian() //→ "1994年12月"

```

ロケーションはjapanですが、カレンダーを.japanese、.gregorianに変える形です。
和暦→西暦変換の際に`formatter.dateFormat = "GyM"`だとうまくいきませんでしたので注意です。
tkinterでfizzbuzzを判定するGUIを作ってみた

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/240067/3a4e11ca-c8fe-1444-e3f7-bd4fc206bb6d.jpeg)


# コード

```tkfizzbuzz.py
!/usr/bin/env python
-*- coding: utf-8 -*-

from tkinter import *
from tkinter import ttk

root = Tk()
root.title(u'Fizz Buzz')

#FizzBuzzを判定する関数
def fizzbuzz(n):
    fzbz = "Fizz Buzz"
    fz = "Fizz"
    bz = "Buzz"
    try:
        n = int(n)
    except ValueError:
        return Entry1.delete(0, END)
    if n % 15 == 0:          
        resltfizbuz(fzbz)
    elif n % 3 == 0:
        resltfizbuz(fz)
    elif n % 5 == 0:
        resltfizbuz(bz)
    else:
        resltfizbuz(n)
    Entry1.delete(0,END)

#判定結果をリストボックスに書き込む
def resltfizbuz(reslt):
    Listbox1.insert(END,reslt)
    Listbox1.yview_scroll(5, UNITS)

#フレーム
frame = Frame(root,width=30)
frame.grid()

#エントリー
Entry1 = Entry(frame, width=30)
Entry1.bind("<Return>", lambda event:fizzbuzz(Entry1.get()))
Entry1.grid(row=0)

#リストボックス
Listbox1 = Listbox(frame, width=30)
Listbox1.grid(row=1, column=0)

#スクロールバー
Scroll = ttk.Scrollbar(frame, orient=VERTICAL, command=Listbox1.yview)
Listbox1['yscrollcommand'] = Scroll.set
Scroll.grid(row=1, column=1, sticky=(N,S))

#ボタン
Button1 = Button(frame,text=u'FizzBuzz',command=lambda: fizzbuzz(Entry1.get()))
Button1.grid(row=2)

root.mainloop()
```

## コードの説明
```
#FizzBuzzを判定する関数
def fizzbuzz(n):
    fzbz = "Fizz Buzz"
    fz = "Fizz"
    bz = "Buzz"
    try:
        n = int(n)
    except ValueError:
        return Entry1.delete(0, END)
    if n % 15 == 0:          
        resltfizbuz(fzbz)
    elif n % 3 == 0:
        resltfizbuz(fz)
    elif n % 5 == 0:
        resltfizbuz(bz)
    else:
        resltfizbuz(n)
    Entry1.delete(0,END)
```
数字を入力するとfizzbuzzを判定し、3の倍数ならfizz、5の倍数ならbuzz、15の倍数ならfizzbuzz、それ以外の数字はそのまま返します。
int以外は消します。

```
#判定結果をリストボックスに書き込む
def resltfizbuz(reslt):
    Listbox1.insert(END,reslt)
    Listbox1.yview_scroll(5, UNITS)
```
fizzbuzzの結果をリストボックスに挿入します。
リストボックスの高さ以上に結果が挿入された場合、スクロールが面倒なのでyview_scrollで下にスクロールさせます。


```
#エントリー
Entry1 = Entry(frame, width=30)
Entry1.bind("<Return>", lambda event:fizzbuzz(Entry1.get()))
Entry1.grid(row=0)
```
数字を入れるエントリーを一番上に作ります。
Entry1.bind("＜Return＞", lambda event:fizzbuzz(Entry1.get()))で、
エンターキーを押すと、入力した値をfizzbuzz関数が受け取るように設定します。
注：半角の＜＞だとなぜか＜Return＞が消えてしまうので全角で打ちました。


```
#リストボックス
Listbox1 = Listbox(frame, width=30)
Listbox1.grid(row=1, column=0)
```
fizzbuzzの判定結果を出力するリストボックスです。

```
#スクロールバー
Scroll = ttk.Scrollbar(frame, orient=VERTICAL, command=Listbox1.yview)
Listbox1['yscrollcommand'] = Scroll.set
Scroll.grid(row=1, column=1, sticky=(N,S))
```
リストボックスに縦のスクロールバーを設定します。
sticky=(N,S)でリストボックスと同じ高さにスクロールバーを引き延ばします。

```
#ボタン
Button1 = Button(frame,text=u'FizzBuzz',command=lambda: fizzbuzz(Entry1.get()))
Button1.grid(row=2)
```
エントリーの値をget()で受け取りfizzbuzzに渡します。
AzureにVM（Ubuntsu16.04）作ってNodejsでHTML動かす

# 手順
１：AzureにVMをインストール(OSはUbuntsu）
２：SSHで接続してrootになる（作成したユーザで、sudo suとうてばOK）
３：コマンド
$ git clone https://github.com/creationix/nvm.git ~/.nvm
$ source ~/.nvm/nvm.sh
$ nvm help
 errorがでず、helpがでればよい
$ nvm ls-remote
 奇数が安定。最新バージョンをインストールする（2018/3/13ではv9.8.0）
$ nvm install 9.8.0
$ node -v
 バージョンが表示されればよい

$ nvm alias default v9.8.0
default -> v9.8.0
$ vi ~/.bash_profile
に下記を記載（元々は０）
if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi

４：これだとrebootした場合に
＄ node -v
The program 'node' is currently not installed. You can install it by typing:
apt install nodejs-legacy
になる。
＄ node ファイル.js
 実行できない、昨日は出来た。
なんで？

5:ここ参照でよい。
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea



# 単語の意味
・NVM（Node Version Manager）
・nodeコマンドはJavascriptで書いたプログラムを実行するためのコマンド
・npm (Node Package Manager)はnodeコマンド実行時に使用するパッケージ(ライブラリ)をダウンロードしてインストールするためのコマンドだ
JavaScriptのトレンドまとめたWebアプリをPWAで作ってみた(Trend.js)

[https://trendjs.com](https://trendjs.com)
![trendjs](https://user-images.githubusercontent.com/12339312/37325464-6659aa0e-26d1-11e8-885f-a54b1ba1a062.png)

GitHubのトレンドを確認するのに不便を感じたのでJavaScriptのトレンドまとめたWebアプリを作ってみた。スマホをメインで考えているので、ホーム画面に追加するとアプリっぽく使えたりします。

## サンプル
<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/jXIubegcfv">pic.twitter.com/jXIubegcfv</a></p>&mdash; c.uehira (@hacocooo) <a href="https://twitter.com/hacocooo/status/973459237920632833?ref_src=twsrc%5Etfw">2018年3月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Firefoxのomni.jaを解析してみた。

# 前置き:オプション画面にプロ生ちゃんが召喚されなくなった…(´・ω・`)
![プロ生ちゃん行方不明.PNG](https://qiita-image-store.s3.amazonaws.com/0/172794/479eaa0c-8b1a-e373-7101-f0a87e18b5dd.png)
[以前紹介したやり方](https://qiita.com/Kazanami/items/fa85196a1cb6cf182221)だと表示されなくなってしまった。
どうやら、Stylishを最新バージョンにした際に発生したらしい。ローカルファイルを読み込めなくなっていた。
(自己推測だが、セキュリティの面からの脆弱性があったのではないかと思われる。)    


というわけでソースコードをいじって再召喚を試してみる。
幸い、アップデート後も、旧バージョン時代のCSSソースコードが残っており、それを流用すれば再現は可能と思われる。







#用意するもの

Firefox
今回はPortableappsのFirefox ESR Ver52.6.0を使用

7-zip
解凍ソフト。今回はomni.jaを触るため、必要。他のソフトは未検証

Terapad
フリーのテキストエディタ。FirefoxのソースコードはUTF-8が多く、標準のメモ帳などで開くと改行がずれる可能性がある。
使い慣れているエディタがあればそちらでも可。


#さっそくやってみる。

まずは、大元であるomni.jaの捜索から始める。
普段は、インストールした場所
(64ビット版)`C:\Program Files\Mozilla Firefox\`
(32ビット版)`C:\Program Files(x86)\Mozilla Firefox\`
が普通だと思われる。

どうやら最近は、管理者権限がなくてもインストールができるようになったらしい。


`補足`
`筆者の環境ではPortableApps.com Platformを使用しているので、フォルダ階層が異なるがその都度、置き換えてほしい。`

通常omni.jaはインストールしたフォルダの下にある、browserというフォルダに格納されている。

`補足2`
`最新バージョン(58.0.2)ではomni.jaのままでは閲覧できないが、拡張子を.zipに変更すれば閲覧できることができた。`

## ここで注意
　ファイルをいじる際は、**必ずバックアップを取っておくこと**。
　トラブルが発生した場合、再インストールする羽目になるからだ。
  `ここだけの話、筆者もファイルをいじりすぎて、Firefoxが再起不能になり、泣く泣く再インストールをした苦い思い出がある。`

---
話を戻して次に進もう。
omni.jaを7-zipなどの解凍ソフトで開いてみよう。
![ファイル構造.PNG](https://qiita-image-store.s3.amazonaws.com/0/172794/ab421f5c-56fe-8b5a-7808-2324f3ee4bd2.png)

するとこのような内容が見れるはずだ。
そこから、
`chrome -> browser -> content -> browser`
とフォルダを下っていこう。

![山のようなファイル.PNG](https://qiita-image-store.s3.amazonaws.com/0/172794/ce4e099f-1343-be09-c33f-58525d0d3c35.png)

そうすると山のようなファイルが出てくると思う。これが(多分)Firefoxの正体である。

ここから各ファイルをいじっていくのだが、
**「何か立ち絵だけじゃ物足りないから、背景を追加しちゃえ」**
と筆者の中で方針が変わった。

今日はここまでにしておこうと思う。

次回はページの背景追加をすると思う。

# あとがき

久々のQiitaの投稿です。堅苦しい文章で大変申し訳ありません。
あまりこのような場に慣れておらず、いろいろおかしな点があると思います。
暖かい目でご覧いただければと思います。

最後までありがとうございました。
だましだまし使っていたwebpack1をwebpack4にアップデート

# はじめに
約２年前に導入したwebpack1から更新していなかったプロジェクトをwebpack4リリースを機に更新しました。

v2からの仕様かどうかはおいといて、webpack4にしたらどういうエラーがでて、どういう対応したのかを記載します。

# 更新手順
アップデートではなく、まったくのインストールから行いました。

```console
$ yarn init
$ yarn add -D webpack webpack-cli #wepack-cliが必要になりました
```
webpack.config.jsをwebpack1で作成したwebpack.config.jsを元に最小の設定で新たに作成します。

```js:webpack.config.js
const path = require('path')

module.exports = {
  entry: './src/path/to/app.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  },
  root: [
    path.resolve('./src')
  ]
};
```

# 出くわしたERRORたち
## error1: `Module not found: Error: Can't resolve ...`
まず大量にでたエラーです。
`resolve.root、resolve.fallback、resolve.modulesDirectories`
これらのオプションはresolve.modulesオプションに置き換える必要がありました。以下のように変更が必要です。

```diff
  resolve: {
-   root: path.join(__dirname, "src")
+   modules: [
+     path.join(__dirname, "src"),
+     "node_modules"
+   ]
  }
```

## error2: `Module parse failed: Unexpected token (1:0)`
htmlをimportしている箇所で発生しました。
そもそも`html-loader`を`webpack.config.js`に定義していなかったので定義します。
ただ、`module.loaders` は今は `module.rules`の記述方法に変わっているので、そこを修正します。
※非推奨ですが、古い構文もそのまま使用できるようです。

```diff
 module: {
-   loaders: [
+   rules: [
      {
        test: /\.html$/,
-       loader: 'html-loader'
+       use: [
+         {
+           loader: "html-loader"
+         }
        ]
      }
    ]
  }
```

## error3: `Module parse failed: Unexpected token  in JSON at position 0`
jsonファイルをimportしている箇所で発生していました。
同様の原因かと思いきや、webpack4では`json-loader` もう必要ないとのこと
https://webpack.js.org/guides/migrating/#json-loader-is-not-required-anymore

```diff
  module: {
    rules: [
-     {
-       test: /\.json/,
-       loader: "json-loader"
-     }
    ]
  }
```

ただ今回、これはうまくいきませんでした。
普通にjson-loaderを使用してもエラー消えませんでした。

探しに探して、行き着いたのが以下のissueです。
https://github.com/webpack/webpack/issues/6572

結局webpack.config.jsでjson-laoderの設定は必要なのかは解明できなかったのですが、以下の設定で解決しました。typeをつけることでエラーが消えました。

```js
{
   type: 'javascript/auto',
   test: /\.json$/,
   use: [ { loader: 'json-loader' } ]
}
```
typeに関しては以下の記事で詳しく解説しています。
[次のリリースであるwebpack4の主な変更点 - モジュールタイプのサポート](http://abouthiroppy.hatenablog.jp/entry/2017/12/25/100004#%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%97%E3%81%AE%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88)

## error4: `The 'mode' option has not been set. Set 'mode' option to 'development' or 'production' to enable defaults for this environment.`
※これは警告でした。
実行後にコンソールにでる警告です。
`production`, `development`, `none`のモードを指定していない場合にでる警告のようです。
`webpack --mode production`のように指定して実行すると警告はでなくなります。

---
一旦ここまでで、無事バンドルされ、動作しました。

バージョン移行に関しては基本的に以下の公式サイトを参照しています。
https://webpack.js.org/guides/migrating/