OmniAICreator/Qiita-1.07M huggingface dataset:
matplotlibでヒストグラムの左側の縦軸を度数、右側の縦軸を相対度数にする（邪道なやり方かも）

# この記事で行うこと

この記事の続編です→[「matplotlibでヒストグラムの縦軸を相対度数（柱の高さの合計=1）や相対度数密度（ヒストグラム全体の面積=1）にする」](https://qiita.com/kanedaq/items/1e7a0e52363224c08980)

matplotlibで、ヒストグラムを

- 左側の縦軸を度数（matplotlibのデフォルト）
- 右側の縦軸を相対度数（柱の高さの合計=1）

にして描画します。ただし、邪道なやり方かもしれません。

## 参考ページ（感謝します）

[[python]matplotlibで左右に２つの軸があるグラフを書く方法](https://qiita.com/supersaiakujin/items/e2ee4019adefce08e381)

## ソースコード（Jupyter Notebook）と描画結果

データ件数は7500件で、平均値50、標準偏差10の正規乱数にしました。
まず以下のPythonコードを実行してみます。

```py

#%%

import numpy as np
import matplotlib.pyplot as plt


#%%

# データ作成
μ = 50
σ = 10
data = [ np.random.normal(μ, σ) for i in range(7500) ]


#%%

# 階級数
num_bins = 20

# グラフ描画
fig = plt.figure(figsize=(12, 8))
plt.legend()
plt.xlabel('x', fontsize=18)
plt.title('null', fontsize=18)

# (1) 縦軸を度数にしたヒストグラム
ax1 = fig.add_subplot(111)
ax1.set_ylabel('frequency', fontsize=18)
ax1.grid(True, color="dimgray")
ax1.set_axisbelow(True)    # gridを最背面に移動
ax1.hist(data, bins=num_bins, rwidth=0.5, align="mid")

# (2) 縦軸を相対度数にしたヒストグラム
ax2 = ax1.twinx()
ax2.set_ylabel('relative frequency', fontsize=18)
ax2.grid(True, color="lightgrey", linestyle="--")
ax2.set_axisbelow(True)    # gridを最背面に移動
weights = np.ones_like(data) / len(data)
ax2.hist(data, bins=num_bins, weights=weights, rwidth=0.5, align="right", color="red")
```

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/b92262ed-d6ff-d545-8fca-d35bde3f842d.png)

縦軸=度数の柱をデフォルトの色で、縦軸=相対度数の柱を赤で、左右に並べて描画しました。
この両者の高さが同じに見えることを<font color="Red">人が確認します</font>（邪道たる所以．．）

度数と相対度数の柱の高さが同じに見えたら、柱の色を一致させます。
「color="red"」を指定せずに、ax2.hist()を呼び出します。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/d24782e2-8ec3-1995-5031-fc07afcbdd37.png)

ax2のGrid線が、ax1の柱より手前に表示されてしまいました。
この横線を見えなくするために、以下のコードを追加してax1と同じグラフを上書き描画することにしました。

```py

# (3) (1)の見栄えを調整
ax3 = ax1.twinx()
ax3.set_yticklabels([]) 
ax3.hist(data, bins=num_bins, rwidth=0.5, align="mid")
```

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327312/3651c8c2-6e6b-4b56-8b1d-5f8348c48a90.png)


完成版のコード全体は以下の通りです。

```py

#%%

import numpy as np
import matplotlib.pyplot as plt


#%%

# データ作成
μ = 50
σ = 10
data = [ np.random.normal(μ, σ) for i in range(7500) ]


#%%

# 階級数
num_bins = 20

# グラフ描画
fig = plt.figure(figsize=(12, 8))
plt.legend()
plt.xlabel('x', fontsize=18)
plt.title('null', fontsize=18)

# (1) 縦軸を度数にしたヒストグラム
ax1 = fig.add_subplot(111)
ax1.set_ylabel('frequency', fontsize=18)
ax1.grid(True, color="dimgray")
ax1.set_axisbelow(True)    # gridを最背面に移動
ax1.hist(data, bins=num_bins, rwidth=0.5, align="mid")

# (2) 縦軸を相対度数にしたヒストグラム
ax2 = ax1.twinx()
ax2.set_ylabel('relative frequency', fontsize=18)
ax2.grid(True, color="lightgrey", linestyle="--")
ax2.set_axisbelow(True)    # gridを最背面に移動
weights = np.ones_like(data) / len(data)
ax2.hist(data, bins=num_bins, weights=weights, rwidth=0.5, align="right")

# (3) (1)の見栄えを調整
ax3 = ax1.twinx()
ax3.set_yticklabels([]) 
ax3.hist(data, bins=num_bins, rwidth=0.5, align="mid")
```

邪道な感じなので、正攻法があれば教えてほしいです。
TensorFlow2.0エラー

# 出たエラー
TypeError: len is not well defined for symbolic Tensors. (activation_3/Identity:0) Please call `x.shape` rather than `len(x)` for shape information.

#解決策
`$ pip install tensorflow == 2.0.0-beta`

#結果
多分解決　

# 参考にしたサイト
https://github.com/wau/keras-rl2/issues/4
Laravelメールアドレス確認メールでhttpsだと403 | Invalid signatureで認証できない問題への対応

## メールアドレス確認のURLをhttpsにする
商用環境はhttpsで運用されると思います。
デフォルトでは、httpでメールアドレス確認のURLが生成されてしまいますので、
以下の対応を行います。

```php:/app/Providers/AppServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider;

use Illuminate\Routing\UrlGenerator;

class AppServiceProvider extends ServiceProvider
{
    public function boot(UrlGenerator $url)
    {
      # 開発環境（local）はhttpなので、httpsにしない
      if (config('app.env') !== 'local') {
        $url->forceScheme('https');
      }
    }
}

```
`AppServiceProvider.php`で、bootにUrlGeneratorを渡して、
urlがhttpsで生成されるようにしています。

これで、メールアドレス確認メールのhttps化は完了です。

## 確認してみると403 | Invalid signature
メールアドレス確認URLは、httpのままだと成功しましたが、httpsにすると失敗します。

## メールアドレス確認URLで、403 | Invalid signatureを解決する

解決策として、TrustedProxyでプロキシを`'*'`に設定します。
IPがわかる時など、全てを許可したくないときは、以下ドキュメントを参考にプロキシを設定しましょう。
https://readouble.com/laravel/5.8/ja/requests.html#configuring-trusted-proxies

```php:/app/Http/Middleware/TrustProxies.php
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;

class TrustProxies extends Middleware
{
    /**
     * The trusted proxies for this application.
     *
     * @var array
     */
    protected $proxies = '*'; //これを'*'にするだけ

    /**
     * The headers that should be used to detect proxies.
     *
     * @var int
     */
    protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
```

## 解決時の環境について
この問題を解決時の私のLaravelバージョンは`5.8.13`です。
デプロイ先はHerokuです。

## まとめ
1. url生成をhttpsに変更する
2. IPアドレスが分からないときは、全プロキシを信用させる

## 参考にしたページ

### url生成をhttpsにする
https://qiita.com/hisash/items/4b3bb1ea47c38b0d8c86

### 今回の問題の解決
https://github.com/laravel/framework/issues/28311

### 同じと思われる問題に直面してる例
https://github.com/laravel/framework/issues/30594

### Laravelドキュメントの信用するプロキシの設定
https://readouble.com/laravel/5.8/ja/requests.html#configuring-trusted-proxies
Kaggleをやるぞ

データ分析に興味あるのでKaggleを始めてみようと思う。

いまのところ、データ分析のやり方とかは何も知らない。
これから頑張る。

Kaggle、登録はしてみたものの進め方よくわかんないので、てかKaggleってなにかよくわからないので、ここにメモする。

## Kaggleとは
データ分析コンペのプラットフォーム。
Kaggle内で就活もできたりするみたいだけど、基本的にはコンペのプラットフォーム。

データを与えられて、「これらのデータを元に、この次どうなるか予測せよ」的な問題が与えられる。

我々コンペ参加者がすることは、分析モデルを作ること。
分析モデルというのは、要は関数（だと思う）で、与えられたデータを元に予測結果を出力するという関数。
モデルって言葉はさっき初めて知ったので、間違ってるかもだけど、だいたいこんな感じ。

モデルを作ってその精度とかを競い合ってて、そのコンペ会場がKaggle。

まず俺が勉強すべきなのは「モデルとは」ってところからだな。
幸い数学とPythonは少しわかるからたぶん得意。頑張る。
railsの復習

Railsでの処理のポイント

- ルーティング
- コントローラー
- モデル
- ビュー

モデル、ビュー、コントローラーをまとめて
MVCという。

###HTTPメソッド

- GET ページを表示する操作
- POST データを登録する操作
- PUT データを変更する操作
- DELETE データを削除する操作

###コントローラ アクション

- index 一覧表示リクエストアクション
- new 新規投稿リクエストアクション
- create データ投稿リクエストアクション
- show 個別詳細表示リクエストアクション
- edit 投稿編集表示リクエストアクション
- update データ編集リクエストアクション
- destroy データ削除リクエストアクション

###部分テンプレート
renderメソッドを使う。
renderメソッドのpartialオプションでファイルの指定を行う。
部分テンプレートのファイル名の先頭は「_(アンダーバー)」で始める。

★以下、省略表示が鬼。順々に教えてもらいたいところ。部分テンプレートの理解が浅いうちから最終省略形見せられたら大混乱間違いなしだわ・・・。でも改めて見ると、やりたいことをササッとやってくれ、って考えると最終形の方が直感的に分かるか、って気がしないでもないが、経緯を理解した上で使ってかないと、部分テンプレートがどれなのか分からなくなりそう。

```erb
<% @users.each do |user| %>
  <%= render partial: "user", locals: { user: user } %>
<% end %>
```
```erb
<%= render partial: "user", collections:  "@users" %>
```
```erb
<%= render @users%>
```

###フォーム入力データの取得
form-tagに入力されたデータは、params.permit(フォームの名前定義)で取得。
form-withに入力されたデータは、params.require(モデル名).permit(フォームの名前定義)で取得。
form-withの場合、form-tagに比較して深い階層に保存される為、require()が必要になる。フォームの入力データは、プライベートメソッドにて取得することで、Classの外部から呼び出されないようにする。

###バリデーション 一定の制約をかける
空のデータを登録できないようにするような場合に使用。
validates フォームの名前定義, presence: true

###link_to
link_to 表示するテキスト, prefixもしくは、URIパターン, HTTPメソッド
HTTPメソッドを省略した場合は、GETで実行されるので注意する。

###ridirect_to
コントローラのビューに関わらず、特定のページにとばす。
ridirect_to アクション名 (実行条件？)

###コードの記述(試験対策)
スコープの意識は・・・まだあんまりしなくていいのかな。
コードの書き順はよく確認すること。routes.rbのコードの書き順に注意。
いつもは頭に書いてるのが末尾にあったり、
先に定義していないといけないコードを、後ろに書いてあったりする。

----------------------------
railsのエラー修正問題ヤベェな。
どないしょ。
VScodeを使って簡単にローカルサーバーを立てる

## vscode-live-server
VSCodeからボタンひとつでローカルサーバーが立てられる拡張機能です。
https://github.com/ritwickdey/vscode-live-server

## 良いところ
1. ボタン一つでお手軽簡単。
2. `hot reload`が有効。

## インストール
1. `VSCode`の`Extensions`から`Live Server`で検索
2. `install`を押す

## 使い方
1. 右下に`Go Live`のボタンが増えるので、立ち上げたい`html`を`VSCode`で開いて`Go Live`を押す
2. ローカルサーバーが立ち上がる

## 設定

- `liveServer.settings.root`
    - デフォルトは`/`
    - index.htmlがルートにない場合(例：/src/index.html)デフォルトのままだとjsファイルやcssファイルの参照が404になってしまうので、よしなに設定(例:./src)してあげる。
- `liveServer.settings.port`
    - デフォルトは`5500`
    - よしなに設定
- `liveServer.settings.https`
    - デフォルトは`false`
    - httpsの設定も可能


詳細はこちら
https://github.com/ritwickdey/vscode-live-server/blob/master/docs/settings.md
オープンソースコードとは

よく見る言葉である「オープンソースコード」スルーしていたので調べてみた。

簡単に言うと**公開されているプログラムのソース**という事らしいです。
あーなんとなくわかるって感じでした。

##そもそもソースコードとは?

コンピューターは普段、機械語を理解してプログラムを実行している。
人にとっては機械語を理解するのは難しいのでその代わりとして普段僕たちはプログラミング言語を用いてプログラムを実行している。ソースコードとはこのプログラミング言語によって記述されたプログラムの事をソースコードというそうです。
完全に経験0のおっさんがとりあえず転職した時の話。

キャリアチェンジしてエンジニアになるべく日々奮闘してます。
これからキャリアチェンジしようと考えているorしようと動いている同志の参考になればと。


# とりあえず転職した理由

2019年8月にポテンシャル採用をしているシステム(WEBアプリ)会社へバックエンドエンジニアとなるべく転職しました。

前の会社では総務で電卓叩いたり、契約書を作成したり、承認したり決済資料作ったりなどなどしていました。

全然畑違いな職種から何故転職したのか？

アナログな事務作業がひたすらに面倒だったから！！！

というのは動機で、実際には前職中に勉強を始めようとしましたが、仕事内容が違いすぎる上に忙しすぎて勉強の時間を確保できなかったためです。

それなら一層の事ポテンシャル採用(未経験者採用)してるところで、仕事しながら勉強した方が早くない？思い立ったが吉日、速攻で転職活動をして、幸運な事に今に至ります。


# 転職活動中に思った事

そもそも転職活動を急いだ理由は、機械学習の技術が進んでいる昨今、数年後にはバックエンドはAIが書くようになるんじゃないかと踏んだからです。
経験が一切無いので、自分の知識の中だけでの考えでですが、初心者としてはweb系が1番入りやすく、その分AIにも書きやすいものと考えたので、AI技術で作成できるようになってしまった後だと知見を持ったエンジニアしか生き残れなくなる！と焦って転職した訳ですね。はい。

転職サイトを転々としていて気付いたのは、未経験者を募集している会社がかなり多い事！
専門職だし、大学で授業を選択してたとか、専門学校に行ってないとダメって考えはどうやら古かったようです。。。
特に、20代未経験者を募集しているところと、インフラエンジニアを募集しているところはかなり多い印象でした。
そして最近の主流はSESのようですね。


# 面接を受けた時に聞いた現状

自分は自社内開発のみの会社を探していました。
理由は、派遣先によって全てが大きく違う事を知っていたからです。
ある程度技術がついてから、給料を上げるためにSESを選択するのはありだと思いますが、会社によっては2人〜10人規模のチームで出向と求人に書いてあったり説明を受けても、それは最初の1ヶ月だけで、自分以外の人はその後引き上げてしまい、聞ける人もいなくなり挫折する、なんて話を周りからよく聞いていたのです。

実際に自社内開発を行なっている5社に応募し、面接を受けたのですが、どこの会社も深刻な人員不足に悩まされているそうです。
(驚かれますが、前職の一般事務でも常に求人は出していましたが、なかなか良い巡り合わせが無く人員は不足していました)

専門職なら尚更ですね。。。

そこで、どこの会社も未経験者を採用し、エンジニアとして育てるしか無くなったのが現状のようで、さらには「これから未経験者を採用する」会社ばかりで、5社とも口を揃えて言ったのは「研修制度をまだ作っていないので、自分で勉強してもらう事になる」でした。

深刻な人員不足による会社の体力低下、恐ろしい。

自分は元々自習するつもりだったので、研修制度が確立されていない事は、さほど注視していませんでした。


# 実際に入社してみてどうか

率直に言うと「研修制度が確立されていない」というのが、予想の範疇を超えていました。
本屋で売ってる教本と、ネットで検索するとすぐに出てくる「とりあえず簡単なサイト作ってみる」系のサイトurlを渡されて、自習してました。まあまだ入社して3ヶ月なので、いずれにせよ何もできない現状です。

この言い方だとなんか不満を持っているように見えるが、けしてそんな事は無いです。
給料をいただきながら勉強できる、こんな素晴らしい環境はない！
ただ、研修が無いって言っても。。。と思ってても、こんなパターンもあるよ！って話。

別に意地悪されてる訳でもなく、散々調べ倒しても分からないと先輩方がきちんと教えてくれるので、本当に良い環境に巡り会えました。

同志よ、一緒に頑張ろう。
【C#,Unity】Dictionary<GameObject,float>をfloat基準で昇順にSortしようとしたら謎処理を挟んでいた話

###追記【2019/11/15】
@albireo 様にアドバイスしていただいた`SortedList`の方が簡易的かつ無駄なく処理できたので
記事の末尾に追加しておきました。

#この記事の狙い
自分の経験を書き記すとともに、有識者の方々からアドバイスや説明をもらえたらいいなぁ。
という期待。

##あらすじ
Unityで画面内に映っているTargetを取得＆自キャラとTargetの距離を取得できるようになったので、
これを「距離が近い順」で並べ替えたい！と思い、色々調べながら試してみることに。
#本題
まず「画面内に映っているTarget」と「Targetまでの距離」、この二つの情報を紐付けるには
どうすればいいのかを調べるところから始めた。

これは調べると直ぐに出てきた、最初はList＜＞か配列[ ]でなんとかするしかないのかな？とか考えていたが、
調べてみると`Dictionary`という超便利なクラスがあるではないか。
早速、意気揚々と使ってみる。

```cs
Dictionary<GameObject,float> ProvisionalValue = new Dictionary<GameObject,float>();
ProvisionalValue.Add(hit,target_distance); 
```

よし、これで情報の紐付けはできたな...！
後はこれを「距離が近い順」で並べ替えるだけだ...！

なんだ楽勝じゃん。勝ったな、風呂入ってくる。

#ここからが本当の地獄だ...！
さて、ちゃちゃっとSortして終わらせるか～

```cs
ProvisionalValue.Sort();
```

...あれ、できない。なになに？DictionaryにはSortの定義が含まれていない？
あら、そうなのか...。じゃあどうやって並び替えするんだろう、調べてみるか...。

>[【C#入門】DictionaryのKey、Valueの使い方(要素の追加、取得も解説)](https://www.sejuku.net/blog/41326#i-3)

ははーん、Linqを使えば出来るのね。試したことが無いけど、やってみるか...。

**ここで訳の分からないことをし始める（多分色々調べているうちにいろんな記事の情報が入り混じった）**

えーっと、まずはソートする基準がいるから（？）floatだけをList<>で取得してからこれをOrderByで
並べ替えて...、あれ？Valueが定義が含まれていない...？（Listだから）

これは何かがおかしい...！という感じで混迷を極めた結果、こうなった。

```cs
    private static Dictionary<GameObject,float> hitsOB = new Dictionary<GameObject,float>();
    private static Dictionary<GameObject,float> ProvisionalValue = new Dictionary<GameObject,float>();

    {
        ProvisionalValue.Add(hit,target_distance);
        Sort(ProvisionalValue);
    }

    public static void Sort(Dictionary<GameObject,float> itemTable) //取得したオブジェクトと距離のデータを距離が近い順でソートするメソッド
    {
        IOrderedEnumerable<KeyValuePair<GameObject,float>> _table_1 =
            itemTable.OrderBy(selector => selector.Value);
            foreach(KeyValuePair<GameObject,float> pair in _table_1)
            {
                hitsOB.Add(pair.Key,pair.Value);
            }
    }
```
改めて見ると何やってるんだか、と思いました。

ProvisionalValueに格納したデータをOrderByで並べ替えて、並べ替えたデータを_table_1に格納して、
foreachでpairに一つずつ格納してhitsOBに順に格納....

**いや、これ普通にProvisionalValueをOrderByでソートすればいいじゃん。**

はい、というわけでそうした結果がこちら。

```cs
ProvisionalValue.Add(hit,target_distance);
ProvisionalValue.OrderBy(x => x.Value);
```
**二行で終了。（なぜ俺はあんなムダな時間を...）**

#ふりかえり
そもそも混乱した理由は「よく理解していなかったから」につきます。
Dictionaryの値の取得方法すら理解していなかったが為に、KeyとValueがなんなのか分からずに使っていた
結果、今回のような無駄な時間を浪費する羽目になりました...。

まさしく**「知識は身を助ける」**を身をもって実感しました。

#追加記事【SortedList】
先に紹介したDictionaryクラスは値を格納した後にOrderByでソートしていましたが、
SortedListクラスを使用すればわざわざソートする必要がなくなります。

**しかし、注意しなければいけない点があります。**
それは**`SortedList <TKey,TValue>`**では、**`キー(TKey)`**の値を基準にソートされます。

今回の例で行くと、先の紹介したDictionaryは**`Dictionary<GameObject,float>`**としていましたが、
これだとTKeyの値に代入しているGameObjectのソート基準はNameの頭文字をABCD...順で並び替える為、
ソートの基準は距離で並び替えたかったので、順番を入れ替える必要がありました。

ということを踏まえた上で変更したものが以下の流れです。（距離の所得等は省いています）

```cs
private SortedList<float,GameObject> ProvisionalValue;

void Start()
{
   ProvisionalValue = new SortedList<float,GameObject>();
}
public void Sort()
{
   ProvisionalValue.Add(target_distance,hit);
   foreach(var item in ProvisionalValue)
   {
       Debug.Log("Distance : " + item.Key + " / Object : " + item.Value);
   }
}
```
これでコンソールに距離順で距離とオブジェクト名が表示されます。
uniq コマンドのオプション


# 要旨

* `man uniq` コマンド
* https://github.com/coreutils/coreutils/blob/master/src/uniq.c

上記を読めば理解が深まると思います。

お・わ・り （ゝω・）v 

🐟 ... 🐟 ... 🐟 ...


これだけだと寂しいので、以下、個人的なコメントなど書くことにします。

# バージョン

```shell
$ uniq --version
uniq (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

作者 Richard M. Stallman および David MacKenzie。
```

# 各オプション

標準出力を変える系

|オプション|説明|
|---|---|
|-c|重複した行数も出力する|
|-d|重複行だけ主力する (それぞれ1行ずつ)|
|-D|重複行だけ主力する (全部)|
|-u|重複していない行だけ出力する|
|--group|重複した行たちをひとまとまりとして、空行区切りで出力する|
|-z|出力する行区切りを改行ではなくゼロバイト文字にする|

重複判定条件を変える系

|オプション|説明|
|---|---|
|-i|大文字小文字を無視する|

重複判定条件を変える系 (オプション + 値を指定)

|オプション|説明|
|---|---|
|-f|スペース/タブ区切りされた文字列で、最初n個は比較しない|
|-s|最初n文字は比較しない|
|-w|n文字目までを比較する|

# 感想

普段から `sort | uniq` で、何も考えずに使っていたのですが、

* 重複していない行だけ出力したい
* 重複数を出力したい

など思って、検索してみたところ、 `uniq` コマンドのオプションがわりと充実していることが分かりました。

その他、感じたこととしましては、

* `sort | uniq`
manual にもあるとおり、 `sort -u` で代用できます

* `uniq -i`
`sort -f | uniq -i` としないと、期待どおりの結果にならず酷い目にあいそう

* `uniq -f`
場合によっては `cut` コマンドを噛ませて使わずとも、`uniq` だけで完結できるのですね

# おわりに

この記事では `uniq` コマンドのオプションについて紹介しました。

普段何気なく使っているものでも、あらためて仕様を確認すると面白いかもしれません。

それではごきげんよう。
ESP8266を壊した話

#壊した経緯
ESP8266を搭載しているボード（以降ESP）を使用して
CdSセルを用いて明るさを取得しようとしていた時のこと....
ESPが異常に加熱していることに気がつき原因を探していたら
ブレッドボードの上部にある+と-にESPの3.3vピンとGNDピンを接続したつもりがどちらも-の所に接続してしまっていたのだ。
#現在の状態
現在はusbを接続してもESPのledもつかずパソコンでシリアルポートの認識もしない。
しかしVccに5vを入力すると正常に動作する。
プログラムの書き込みもできるしシリアルモニタも見ることもできる。
今確認できてある問題があるのはusbによる給電ができないという点だけなのが不幸中の幸いだ。

>https://entotsu44.hatenablog.com/entry/2019/09/12/060000
Visualforce フォーム送信の入力チェックの処理順

##  フォームデータ送信のバリデーションの順番
1. HTMLのバリデーション: 桁数(HTML)、必須項目(HTML)など
2. 《submit》
3. `apex:inputField`のバリデーション: データ型、桁数(DB)、必須項目(DB)など。`apex:inputXXX`の必須チェック(`required="true"`のとき)。
4. 《actionで指定したApexメソッド》
5. トリガのaddError、ユニーク(DB)、カスタム入力規則、重複ルール。

1.と3.はApexメソッドを呼び出す前にチェックされる。たとえば「キャンセルボタン」などでApexメソッドでリダイレクトするようなときはバリデーションを回避する必要がある。
5.はDmlExceptionを投げるため、メソッド内で処理が必要。

## Apexが呼び出される前のバリデーションを回避する例
```html
<apex:commandButton value="キャンセル" action="{!doCancel}" html-formnovalidate="formnovalidate" immediate="true" />
```


## エラー処理の例
```java

try {
    update obj;
} catch (DmlException e) {
    System.debug(LoggingLevel.ERROR, 'error: ' + e.getMessage());
    System.debug(LoggingLevel.ERROR, 'stacktrace: ' + e.getStackTraceString());
    ApexPages.addMessages(e);
    return null;
}
```
Rails3.2でbrowserconfig.xml対策する

だれかがスタートメニューにピン留めしているらしい。「IPアドレスはわかってんだ」って問い詰めることも可能だが、驚かせるためにネタを仕込みたい。

#きっかけ
[Rails3.2で404ページを使う](https://qiita.com/kenmituo@github/items/9e6960829849fc9d5d2a)にてエラー対策してからやってくるようになった気がする。

```application#error_404.mail
An ActionView::MissingTemplate occurred in application#error_404:

  Missing template common/error_404 with {:locale=>[:ja], :formats=>[:xml], :handlers=>[:erb, :builder]}. Searched in:
  * "D:/rails/example/app/views"

  actionpack (3.2.17) lib/action_view/path_set.rb:58:in `find'


-------------------------------
Request:
-------------------------------

  * URL        : http://example.com/browserconfig.xml

```

作成した記憶のない`browserconfig.xml`にアクセスしようとしている。

ぐぐる。[browserconfig.xmlへのアクセスは何なのか？](https://mtfield.net/web-mgmt/browserconfig/)、俺も知りたい。

#対策
`browserconfig.xml`と相応する画像を用意すればいいらしい。

robot.txtやfavicon.icoと同じpublicに作成する。

```public/browserconfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<browserconfig>
  <msapplication>
    <tile>
      <square70x70logo src="browserconfig/small.png"/>
      <square150x150logo src="browserconfig/midium.png"/>
      <wide310x150logo src="browserconfig/wide.png"/>
      <square310x310logo src="browserconfig/large.png"/>
      <TileColor>#000000</TileColor>
    </tile>
  </msapplication>
</browserconfig>
```
画像は`app/assets/images/browserconfig`に保存した。

ドキュメントルートってどこだっけ？ってなってしまった。。。

#続き
##改造編
なぜか`public/browserconfig.xml`を認識してくれない。

場所を変えてみる。

```app/views/layouts/application.html.rb
  <meta name="msapplication-config" content="/common/browserconfig.xml" />
```

```app/views/layouts/common/browserconfig.xml"
(省略)
```

ダメだった。

##browserconfig.xmlを使わない（愚かな自分）
こんな感じにしてみたが、favicon.icoがスタートになる。なんでー？

```app/views/layouts/application.html.rb
<meta name="msapplication-TileColor" content="#000000"/>
<meta name="msapplication-square70x70logo" content="/assets/bc/small.png"/>
<meta name="msapplication-square150x150logo" content="/assets/bc/midium.png"/>
<meta name="msapplication-wide310x150logo" content="/assets/bc/wide.png"/>
<meta name="msapplication-square310x310logo" content="/assets/bc/large.png"/>
```
本番環境と開発環境を間違えていた。恥ずかしい。


#結局
public/browserconfig.xmlに設置するとXMLは参照はできたけど、画像を読み込んでくれないのであきらめた。
```
Rubyのcompact! に注意。

## 経緯
compact!メソッドによって仕事でバグを生み出してしまったので、備忘録としてアウトプット

## compact、compact!の戻り値
#### `compact`、`compact!`は配列から`nil`を弾くが、配列に`nil`が含まれていない時、`compact!`の戻り値が予想していないものだった。。。

```rb
## arrayがnilを含んでいる時
array = [1,2,3,4,5,nil]

# compact
array.compact
=> [1, 2, 3, 4, 5]

# compact!
array.compact!
=> [1, 2, 3, 4, 5]


## arrayにnilがない時
array = [1,2,3,4,5]

# compact
array.compact
=> [1, 2, 3, 4, 5]

# compact!
array.compact!
=> nil
#ふぁ！？!?
```

## 結論
## `nil`を含んでいない配列に`compact!`を使うと、「nil含んでねーじゃねーか」的な感じで`nil`が返ってくるので、注意！！！
kintone開発環境構築メモ

kintoneカスタマイズ開発の際の、環境構築に関する個人的な備忘録です。

# はじめに

kintoneでカスタマイズをする際は、いくつか方法があります。

1. kintoneのプラグインを使う
2. ローカルPCに環境を構築する
3. AWS Cloud9 などクラウド環境を使う

ここでは 2.の方法をまとめておきます。

# My環境

2019-11-15現在

* mac OS10.14.6
* Homebrewを利用しています
* Nodeはnodebrew

# Nodeのセットアップ

## nodeを新規にセットアップする

1. Homebrewをインストールします
2. nodebrewをHomebrewでインストールします
3. nodebrewでnodeをインストールします

* Homebrewのインストール方法は https://brew.sh/index_ja にあります。
* nodebrewはbrewでインストールします。 `brew install nodebrew` 
* nodeはnodebrewでインストールします。`nodebrew install stable`（最新の安定版）


## nodeの最新版をセットアップする

1. Homebrewをアップデートします
2. nodebrewをHomebrewでアップデートします
3. nodebrewでnodeをインストールします


```bash
$ brew update
$ brew -v
Homebrew 2.1.16
Homebrew/homebrew-core (git revision ce38; last commit 2019-11-14)
Homebrew/homebrew-cask (git revision 3d4819; last commit 2019-11-15)
$ brew upgrade nodebrew
$ nodebrew install stable
Fetching: https://nodejs.org/dist/v12.13.0/node-v12.13.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully
$ nodebrew list
v11.14.0
v12.3.1
v12.13.0

current: v12.3.1
$ nodebrew use v12.13.0
use v12.13.0
$ node -v
v12.13.0
```

# kintone開発ツールセットアップ

kintone-cli をインストールします。

```bash
$ npm install -g git://github.com/kintone/kintone-cli.git
```

# エディタ関連

## VS Code

* [VS Code をコマンドラインで起動する] https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line

# プログラミング言語関連

## Perl

* [plenvを使ったPerl環境構築 〜2018年度版〜] https://papix.hatenablog.com/entry/2018/03/10/160838
* [Perl] https://www.perl.org/

チートシート

```
brew install plenv
brew install perl-build
echo 'eval "$(plenv init -)"' >> ~/.bash_profile
plenv -v
plenv commands
plenv install 5.30.1
plenv versions
plenv global 5.30.1
```

## Ruby

### debug

* [printデバッグにさようなら！Ruby初心者のためのByebugチュートリアル] https://qiita.com/jnchito/items/5aaf323ab4f24b526a61
* [byebug]https://rubygems.org/gems/byebug/
* [pry-byebug]https://github.com/deivid-rodriguez/pry-byebug
* [pry-byebugでrubyをデバッグする]https://qiita.com/AknYk416/items/6f0bec58712edaf4940e

### Unit Test

* [使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」]https://qiita.com/jnchito/items/42193d066bd61c740612

# 参考

## 関連リンク

* kintone-cli https://github.com/kintone/kintone-cli

## パッケージを使ってインストールしたNode.jsを削除する

使い方に注意してください。

```bash
lsbom -f -l -s -pf /var/db/receipts/org.nodejs.node.pkg.bom \
| while read i; do echo ${i}; done
| sed -e "s/^\.\///" \
| while read ii; do sudo rm /usr/local/${ii} done
```
GitとGitHub入門

###はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているやっきーです。

まだまだ勉強中のため、間違いがあればどんどん指摘してください。

#Git, GitHubとは
Gitは、ファイルのバージョンを管理するツールです。Gitを使うことにより、誰が、いつ、どのような変更を加えたかを簡単にわかるようになります。また、ファイルの状態を元に戻したいときも簡単にすることができます。
GitHubは、インターネット上でデータを共有するためのサービスです。Gitと連携してローカルにあるリポジトリを公開することや、GitHubにあるデータをローカル上で編集することができます。

#GitとGitHubでできること
ここでは、githubのアカウント登録とgitのインストールができている前提で進めていきます。

#用語
リポジトリ...ファイルなどを格納する場所
ローカルリポジトリ...インターネットに接続していないリポジトリ
リモートリポジトリ ...インターネット上にあるリポジトリ
クローン(clone)...リモートリポジトリからローカルリポジトにデータを取り入れること
プッシュ(push)...ローカルリポジトリからリモートリポジトリにデータを送ること


##ローカルリポジトリを作成する
以下のコマンドで、リポジトリを作成します。

```sh

$ cd Desktop #デスクトップに移動

$ mkdir sample #sampleというディレクトリを作成

$ cd sample #sampleディレクトリに移動

$ git init #ローカルリポジトリを作成
Initialized empty Git repository in /Users/<ユーザー名>/Desktop/sample/.git/ 
#このようなメッセージが出ればOK
```
ここまでで、ローカルリポジトリの作成ができました。
次に、リポジトリにファイルを追加していきましょう。

```sh
$ touch test.txt #ファイルを作成

$ touch test2.txt                                                

$ touch test3.txt 

$ git add test.txt #test.txtファイルをGitに追加する

$ git add . #ディレクトリ内の全てのファイルをGitに追加する
```

ここで、正しくGitに登録されているか確認してみましょう。

```sh
$ git status #Gitの状態を確認
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

	new file:   test.txt
	new file:   test2.txt
	new file:   test3.txt
```

これで、ローカルリポジトリを作成できました。

##リモートリポジトリにpushする
まず、github上で新たにリポジトリを作成します。
トップページの左側にあるRepositoriesの"New"からリポジトリを作成します。
その後、リポジトリのURLが表示されるので、コピーします。

次に、ターミナルに以下のコマンドを入力します。

```sh
$ git remote add origin <コピーしたURL, httpsから始まるもの> 
```

最後に、作成したファイルをpushして完了です。

```sh
$ git push origin master 
```

##ローカルでファイルを更新・リモートにpush
では、コンピュータの中に入っているファイルを編集してリモート上にpushしてみましょう。

```sh
$ git add . #ファイルをリモートリポジトリに追加
$ git commit -m "テキストを追加" #変更内容を登録
```
すると、 ```2 files changed, 2 insertions(+), 1 deletion(-)```のように変更内容が表示されます。

変更内容をリモートリポジトリに反映させるために以下のコマンドを入力します。

```sh
$ git push origin master
```

githubで確認すると、変更が反映されているかと思います。

##リモートリポジトリの内容をローカルに反映させる
リモート上でファイルを編集、削除した場合、 ```git pull```で変更内容を反映させることができます。

##リモートからローカルにリポジトリを追加する
リモートにあるリポジトリをローカルにクローンします。
githubのリポジトリの画面を開き、"clone or download"を選択してURLをコピーします。
<img width="1303" alt="スクリーンショット 2019-11-15 11.36.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499419/99eb330e-e851-18cd-4492-19f36b2c9b41.png">

ターミナルを開き、以下のように入力します。

```sh
$ git clone <コピーしたURL> 
```
すると、ローカル上にファイルが作成されているかと思います。
これで、ローカル上でも編集が可能になります。

#参考URL
[git cloneで環境構築!リポジトリをクローンしよう | 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/71436)
[GitHub初心者はForkしない方のPull Requestから入門しよう | qnyp blog](https://blog.qnyp.com/2013/05/28/pull-request-for-github-beginners/)
[【5分でわかる】GitHubとは？概要やメリットを簡単解説！ | 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/7901#i-3)
IPv4環境のホームネットワークをIPv6に移行する～基本設計編～

## 概要
引っ越しにあたり「ネットワーク技術者として未だにIPv4なんて使っているのは如何なものか。これからIoTも流行るんでしょ？」と考えたため、調べたことなどを残しておくことにしました。ちょくちょく追記編集するつもりです。
ちなみにIPv6自体については特に記載しません。

## 現状
* インターネット回線はauひかり
* いくつか外部公開しているサービスがある。家族のモバイル端末からもアクセスされる。
* WiFi接続端末がある（というかほとんど）
* ほとんどの端末はDHCPによるアドレス割り当てを受けている
* DNSは内部と外部(MyDNS.jp)に保有していて、外部はDDNSで定期的にグローバル更新している
* 内側クライアントOSは主にWindows,Linux,iOS,Android
* 家族のモバイル端末の回線はBIGLOBEモバイル

## 現状の問題点
現時点で正直問題となっていることは無いが、今後のIPv4動向や電子機器全てがアドレスを持つようになった場合を想像して不安になる。

## 基本方針
* 内側はIPv6で構成する。
* 外部公開サービスはIPv4にも対応させる。

## 懸念点
### 回線がそもそもIPv6対応しているの？
auひかりはIPv4/IPv6デュアルスタックで両方ともアドレスを持っているため問題なし。

### IPv4とIPv6て混在できるの？
IPヘッダーの構造が違うから混在しても大丈夫でしょうと判断。
パケットを荷物、通信経路をベルトコンベアに例えると、荷物に「IPv6」とか「IPv4」とでかでかとラベルが貼られてるイメージ。混乱が起きようがない。

### 外部DNSサービスはIPv6対応しているの？
MyDNS.jp (http://www.mydns.jp/) は普通に対応しているのでOK。


### DHCPってIPv6版あるの？
DHCPv6と呼ばれるものがあるし、なんだったらIPv6の仕様でRA(Router Advertisement)というアドレス自動配布機構が備わっているためDHCPをわざわざ立てる必要性もなさそう。
ただし、ルーターが古い仕様にしか準拠していないとDNSが配布されないor任意のDNSが配布できない可能性もあるらしいため、そのときはDHCPv6で配布する。

### OSはIPv6に対応しているの？
メジャーなOSは全て、かなり前から対応している模様。
NASなどのマイナーなOSも大抵はLinuxベースであるため問題ないと思われる。

### モバイル回線はIPv6でアクセスされるの？
モバイル回線にしてIPv6確認サイト( https://test-ipv6.com/index.html.ja_JP )にアクセスさせたところ、残念ながらIPv4しか払いだされていなかった。
BIGLOBEモバイルにはIPv6オプションもなさそう...。つまり**外部公開サービス系はIPv4にも対応させないといけない**。

### PS4でこれまで通りゲームできるよね？
PS4やゲームに限った話じゃないけど、IPv6を使うには**相手(サーバー)もIPv6に対応している必要がある**。
GoogleやYahooといった超有名どころのサービスはもちろん対応しているが、サービスによってはv6対応しているしていないは当たり前のようにある。ちなみにAppleストアのアプリはIPv6対応が必須なのでこちらに関しては心配はないかと思われる。
https://developer.apple.com/jp/support/ipv6/



## まとめ
完全なIPv6移行は無理そう。
モバイル端末が圧倒的に多いはずだから、モバイル回線がIPv6オンリーになればイヤでも普及するとは思うけど難しいんだろうなぁ。
http要求を行い、ステータスコードが200の場合のみ内容を保存する

#背景
`curl`にて機能を作っていたが、「要求が失敗した場合も`-o`（output option）に保存されてしまう」問題が有りシェルスクリプト化しました。

#コード
```sh
#!/bin/bash
# ./curl+.sh {url} {output}
URL=$1
OUTPUT=$2
TMPOUTPUT=/tmp/$(date +%Y%m%d_%H%M%S_%3N)
 
status=`curl -o $TMPOUTPUT -li $URL -w '%{http_code}' -s`
if test $status -eq 200 ; then
cp $TMPOUTPUT $OUTPUT
echo 1
else
echo 0
fi
```
UE4.22からUE4.23にしたらOnlineSubsystemOculusで接続できなかったので対応した

作成中のプロジェクトをUE4.22からUE4.23.1にアップデートしようとしたらOnlineSubsystemOculusで接続しようとすると接続できない現象が発生したので対応した。
ここでは対応の内容を記録する。

# 発生した現象

UE4.23.1にアップデートするとクライアントからJoinSessionすると処理は成功するがサーバー側に接続できない。

# 原因と対応結果

以下のバグが原因だった。
https://issues.unrealengine.com/issue/UE-82549

プロジェクトに取り込んでいたOnlineSubsystemOculusに上記リンク先に書いてある以下の修正を適用すると接続できるようになった。

```
Change line 186 in IpAddressOculus.h (ToString) from:
return OculusId.ToString();
to
return FString::Printf(TEXT("%s.oculus"), *OculusId.ToString());
```

# 現象の調査過程

## ログの調査

* 正常に接続できるUE4.22のログと比較するとサーバー側で以下のようなログが出ているのが原因っぽかった。

```text
[2019.10.04-02.21.56:650][ 96]LogEngine: Changing dynamic resolution state.
[2019.10.04-02.22.14:924][735]LogHandshake: SendConnectChallenge. Timestamp: 28.507830, Cookie: 039125221129068025073170116200035043157184180036126099049244
[2019.10.04-02.22.14:952][735]LogPackageName: SearchForPackageOnDisk took   0.028s, but failed to resolve [Oculus ID].umap.
[2019.10.04-02.22.14:952][735]LogNet: Warning: There is no connection to: 0
[2019.10.04-02.22.14:952][735]LogNet: Warning: Server failed post-challenge connection from: [Oculus ID]
[2019.10.04-02.22.14:952][735]LogNet: Warning: There is no connection to: [Oculus ID]
```

## PackageNameまわりのコード調査

エラーメッセージを出している
Engine/Source/Runtime/CoreUObject/Private/Misc/PackageName.cpp　
をよんでみたりするが[Oculus ID].umapというようなマップがないので原因がわからず。

## VSからのデバッグによる調査

VisualStudioでプロセスにアタッチしてデバッグしてみようと、起動したウィンドウから切り替えるとエラーで落ちる現象が発生した。
エラーメッセージで調べてみると[こちらのバグ](https://issues.unrealengine.com/issue/UE-81742)がひっかかったのでコミット内容をエディタに適用してビルドするとエラーがでなくなった。

プロセスをアタッチしてデバッグしてみたところ。
PackageNameのコードが以下のように呼び出されていることがわかった。

```
>    Laplace-Win64-DebugGame.exe!FURL::FURL(FURL * Base, const wchar_t * TextURL, ETravelType Type) Line 144    C++
     Laplace-Win64-DebugGame.exe!UOculusNetDriver::LowLevelSend(TSharedPtr<FInternetAddr const ,0> Address, void * Data, int CountBits, FOutPacketTraits & Traits) Line 294    C++
...
```

少しコードも読んでみてOnlineSubsystemOculusのバグっぽいことを確認した。

## バグの調査

[issues](https://issues.unrealengine.com/)でOculusのキーワードを入れると[こちらのバグ](https://issues.unrealengine.com/issue/UE-82549)がひっかかった。
内容があてはまったので書いてある修正内容を適用してみる接続できるようになった。
独学でプログラミング学習を始めて1.5か月の振り返りと独学者へのアドバイス


独学でプログラミング学習を始めて1.5か月ほどがたちました。転職、ポートフォリオ等なにも成果がない状態ですが、私自身の振り返りとアウトプットの習慣付けのために学習内容や反省点、これから独学される方へのアドバイスなどを投稿します。技術的なことは書いていません。

##対象読者
・独学でプログラミング学習を始める方
・独学で挫折しそうな方

##自己紹介
・24歳、新卒1年目、メーカー営業職で工場研修中(長い)
・過去2度プログラミングの独学挫折(HTML,CSS,PHP)
・2019年9月末から3度目の独学スタート

##なぜ独学か
・お金がないからです。

##学習内容
・HTML(復習)
・CSS(復習)
・Ruby
・Ruby on Rails
・MySQL
・Bootstrap
・AWS
・Docker
チュートリアルやドットインストール、YouTubeなどの教材を利用し、手を動かしながら学習しています。現在はVM上のcentOS環境にDocker×Rails×MySQLでポートフォリオ製作中です。

##学習時間
・平日2時間
・休日4～10時間
平日は仕事前に0～1時間、帰宅後1～2時間という感じです。睡眠時間を削ることもありましたが翌日の体調が著しく悪化するため睡眠優先してます。その他、通勤・休憩などでPCを触れない自由時間が4時間以上あるので、その時間に技術書を読んだり、用語の理解に努めたりしています。
土曜日は朝から晩まで。日曜日は最低半日(約4時間)で後はリフレッシュに時間を使うようにしています。


##成長したこと
・独学で1.5か月継続している！！
過去2回は2週間ほどで辞めてます。「エラーが出ることと向き不向きは関係ない」と考えるようになったのが一番の要因だと思います。

・コンピューター、プログラムとは何かということを学んだ
「コンピューターにはどんな機能があるのか」、「プログラムとは何か」を理解しないままプログラミングやってみたいと言っていた自分から卒業しました。

・公式ドキュメントを参考にするようになった。
Qiitaファーストでコピペとかしてましたが、用語や概念を少しずつ理解していくうちに公式ドキュメントに抵抗がなくなりました。(幸い英語のリーディングには抵抗がありません。)


##反省
・プログラムを書く時間が少ない。
一番の反省点は、肝心のRuby, Rails, SQLへの理解が深まる前からDockerやAWSにも手を出してしまったことです。ただでさえ学習効率が悪いにも関わらず、DockerやAWSでの環境構築に時間がかかるうちに学習したことが頭から抜けていくという状態でした。

・アウトプット不足
エラーを解決した経験、隙間時間に学んだ用語などをQiitaに投稿する習慣が大切だと分かっていながらなかなかできませんでした。

##今の悩み
・ポートフォリオがRailsチュートリアルのサンプルに寄せられていく。デザインに気を遣わないとチュートリアルと何が違うのかわからなくなります。

##今後の方針
・基礎固め
ポートフォリオ製作を通して今まで学んだ技術への理解を深めていきます。新しい技術には手を出しません。

・アウトプットの習慣化
独学の最大のデメリットはアウトプット→フィードバックの機会が少ないために学習効率が悪いことだと感じています。(自走というより自歩です。)
自らアウトプット＋フィードバックを得られる場を確保しなければインプットの質も下がり、自己満の勉強になってしまいます。
MENTAなどのサービスでメンターお願いします。

##独学で学習を始めた方へアドバイス(自戒を込めて)
・エラーは解決できる
個人的に過去の挫折の原因は「エラーが出た→プログラミングに向いてない...」と考えてしまうことがでした。
「エラー発生→対応→解決しない」ということがよくあると思います。「対応して解決しなかった」ということは、プログラミングの向き不向きとは関係がありません(少なくとも始めて数か月は)。「うまくいかない方法を１つ見つけた」ということです。つまり解決に近づいているのです。初心者が出すエラーなど大したことはありません。検索して、ひたすら試せば解決できます。
「初心者がやるエラーはだいたい経験したかな」と思えるまでやってみてください。

・とりあえずPC立ち上げましょう
高すぎる目標やハードルを定めることは挫折のもとです。初めはとりあえず毎日PC立ち上げればオッケーぐらいの気持ちでいいかもしれません。私はたまにサボりそうになりますが、そのときはPC立ち上げることを目標にします。結局触りだすと楽しくなります。時にはハードルを思いっきり下げることも継続の秘訣です。

##おわりに
スクールに通わないと決めた以上、自分がもつリソースを最大限活用して学習効率を上げていくのみです。少しずつ技術的なこと、サンプルアプリなどもアウトプットしていきます。
アドバイスいただけると幸いです。
暗号化されたImageのプロジェクト間の共有

##はじめに

暗号化されたImageの共有について記載します。結論としては、Google Managed keyで暗号化している場合、透過的に共有可能です。

###暗号鍵の指定タイミング
暗号鍵の指定タイミングは、インスタンス作成時とImage作成時に指定可能です。

1. インスタンス作成時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/19a790b3-1cdf-3ddf-b298-22a4046fb033.png)

2. Image作成時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/ac0ffdb8-6ea9-9871-9506-b22bf98e45ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/d5329d2e-ce7e-2f34-f1ee-16d608b5613b.png)

Imageはインスタンス起動中も取得可能ですが非推奨になります。

###別のプロジェクトで作成したイメージを使用する
roles/compute.imageUserが付与されていれば、別のプロジェクトで作成したイメージを指定できます。
また、使用できるプロジェクトを制限することもできます。
https://cloud.google.com/compute/docs/images/sharing-images-across-projects?hl=ja

インスタンス作成時のイメージ指定画面でCustom imageタブをクリックし、Imageを作成したプロジェクトを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/d958f58c-1600-6217-f854-82edefd2bbd9.png)

使用したいImageを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/c837b914-1056-2118-49b1-8c50ee1f3e97.png)

Image作成時にKMSで暗号化している場合は、KMSの鍵にアクセスできないためエラーになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/0db9b73a-dbfa-d081-091b-7c52b034ab6e.png)

Image作成時にGoogle Managed keyを指定していればエラーにならない。また、インスタンス作成時にインスタンスを作成するプロジェクトのKMSでの暗号化も可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/e387105e-566f-70b7-589e-8a2d449b7c0e.png)

###snapshot
起動してるままでも取れるが、鍵の指定はできません。PDを作成する時に指定した鍵がそのまま使われる形になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/28034d68-6484-6291-77a3-24a8e36c5619.png)

##投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
SSL証明書発行を自動化しコマンド化

##やったこと
頻繁にSSL証明書を作成する必要があったので、いちいち入力するのは手間ですしコマンド化しました。
コマンド化手順→ [【超簡単】1分で独自コマンドを作ってみる(Mac・Linux)](https://qiita.com/KazukiOkada/items/9d0d97295c328c9240d9) 

##セットアップ
下記のシェルスクリプトを `mycsc` という名前でコマンド化しておく
(コード上部の情報を自分のものに書き換えてください)

```mycsc.sh
#!/bin/bash
#mycsc csc = create SSL Sertificate
 
#---実行前に下記の情報を入力してください(全て英語で)--------------------
 
COUNTRY="国　日本ならJP"
PROVINCE="都道府県"
LOCALITY="市町村"
ORGANIZATION="会社名"
ORGANIZATION_UNITNAME="所属部署名"
COMMON_NAME="自分の名前"
EMAIL="メールアドレス"
 
#---------------------------------------------------
 
#すでに.sslディレクトリが存在すれば削除
if [[ -e ./.ssl ]]; then
        rm -r .ssl
fi
 
#.sslディレクトリ作成 &　移動
mkdir .ssl && cd .ssl

#20文字のパスワード生成
password=`openssl rand -base64 12 | fold -w 20 | head -1`
 
#opensslコマンドを実行し、情報を自動入力する
expect -c "
        set timeout 3
        spawn openssl req -x509 -newkey rsa:2048 -keyout keytmp.pem -out cert.pem -days 365
        expect \"Enter PEM pass phrase:\" {
         send \"${password}\n\"
         exp_continue
        } \"Country Name\" {
         send \"${COUNTRY}\n\"
         exp_continue
        } \"State or Province Name\" {
         send \"${PROVINCE}\n\"
         exp_continue
        } \"Locality Name\" {
         send \"${LOCALITY}\n\"
         exp_continue
        } \"Organization Name\" {
         send \"${ORGANIZATION}\n\"
         exp_continue
        } \"Organizational Unit Name\" {
         send \"${ORGANIZATION_UNITNAME}\n\"
         exp_continue
        } \"Common Name\" {
         send \"${COMMON_NAME}\n\"
         exp_continue
        } \"Email Address\" {
         send \"${EMAIL}\n\"
         exp_continue
        } timeout {
         exit 1
        }
"

if [ $? -eq 1 ]; then
        echo "入力がタイムアウトしkeytemp.pemを作成できませんでした。情報が正しいか確認してください"
        exit
fi
 
#opensslコマンドを実行し、情報を自動入力
expect -c "
        set timeout 3
        spawn openssl rsa -in keytmp.pem -out key.pem
        expect \"Enter pass phrase for keytmp.pem\" {
         send \"${password}\n\"
         exp_continue
        } timeout {
         exit 1
        }
"

if [ $? -eq 1 ]; then
        echo "入力がタイムアウトしkey.pemを作成できませんでした。keytemp.pemとcert.pemを削除します"
        rm keytemp.pem cert.pem
        exit
fi

#keytemp.pemを削除し完了
rm keytmp.pem
echo "SSL証明書発行完了しました！"
```

#使い方
SSL証明書を発行したいディレクトリに移動し、 `mycsc` を叩くだけ

<img width="680" alt="SSL証明書作成結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/5f6cea91-8d1e-d6d1-e6a6-c5ab42569b46.png">
MacBookPro16インチの個人的にすごく良いと思うところ（ほぼキーボード周り）

以前Macを新調しましたが
新MacBookProのキーボードがかなり使いにくい…！
と愚痴りました。

[MacBookのTouch Barのショートカット設定方法とキーボードの愚痴](https://qiita.com/a-nishimura/items/972a0afc92f698fab9b8)

- 「Esc」キーが物理ボタンがない（コマンド派としてはとても使いづらい）
- 矢印キーもShiftとの間隔が狭くなっている（タイピングミスが起きやすい）
- 打鍵感が浅い（ストローク約0.5mm）

とずっと愚痴ってました。
すると2019/11/14発表の新MacBookPro16インチで改善されたっぽくてテンション上がりました。
やっぱり私が一方的に愚痴ってただけでなくてエンジニアは同じ思いを抱えていた方は多いのでしょう。
Appleも要望があったみたいな旨のことを言っているのでクレームは多少あったんでしょうね。

そして改善された内容がこちら

- **「Esc」キーの物理ボタンが復活**（コマンド派としても助かる！）
- **矢印キーもShiftとの間隔が狭くなっている**（これをAppleは逆T字型配列と呼んでいる！）
- **打鍵感の変更 シザー構造**（ストローク約1mm（これをAppleはMagic Keyboardと名付けた！）


CPU・メモリ・SSD周りの進化はもちろんあるが今回は置いておきます。
ムーアの法則からしてもチップは基本的に年月の経過に比例していくから。

ということで買おうか悩み中
Dockerのベースイメージディストリビューション選定のベストプラクティス

# 結論

以下3つのどれか

- Alpine Linux
- Ubuntu
- Debian

# 厳しい

- CentOS (理由によってはありえます)

## 選定理由の云々

コンテナのイメージ設定のベタープラクティスとして

- コンテナのイメージサイズは極力減らす

といったものが挙げられます。

CentOSはサーバー上で直に動かす分には、便利なモジュールがデフォルトで色々入ってて便利ですが、Dockerコンテナとして使うと余計なモジュールが多すぎてイメージサイズが莫大になってしまうため、一般的には控えたほうが良いです。CentOSイメージのBuildが遅すぎてストレスフルですし。

とにかく軽いイメージを目指すのであればAlpine Linuxですが、資料的ものが少ない(肌感)で、安定した運用を目指すのであればUbuntuかDebianです。Debianで作られたイメージがDocker Hub上では多い(印象)です。

## その他備考というか独り言

CentOSはLTSでサポート期間が長くてええやん！
かもしれませんが、イメージサイズの観点だけからすると厳しい印象です。


他にも良いディストリビューションあります！
って意見多数出ると思いますが、上記4つのディストリビューション以外試してないんですすみません。
Excelのマクロファイル（あ.xlsm）をアドインファイル（あ.xlam）で保存し、アドイン登録までするマクロ

# はじめに
　せっかく作ったExcelのマクロファイル（あ***.xlsm***）ですが、必要な作業毎に起動するのがメンドクサイ。
　そこで、①アドインファイル（あ***.xlam***）に保存後、②アドイン登録しています。
　しかし、それすらメンドクサイ。
　そこで、①②を実施するマクロと実行ボタンを作りました。

## パソコン環境
- Windows10 (64ビット)
- Office365　

# 実行ボタン（登録ボタン）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/eba272d3-918a-68c4-1c21-48042f695860.png)

# VBA本文
```VB
Option Explicit
Sub 特定フォルダにアドインの保存()

    Dim TWMname As String
    TWMname = Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 5)
    ActiveWorkbook.SaveAs "C:\Users\" & Environ("UserName") & "\AppData\Roaming\Microsoft\addIns\" & TWMname & ".xlam", FileFormat:=xlOpenXMLAddIn
                          
    ChDir "C:\users\" & Environ("USERNAME") & "\appdata\roaming\microsoft\addins"
    TWMname = Left(ThisWorkbook.Name, Len(ThisWorkbook.Name) - 5)
    
    AddIns.Add Filename:="C:\Users\" & Environ("USERNAME") & "\AppData\Roaming\Microsoft\addIns\" & TWMname & ".xlam"
    
    AddIns(TWMname).Installed = True
    MsgBox (TWMname & ".xlamをアドイン登録しました。")
End Sub
```
Javaにおける入力した5個の数字の内、最大値と最小値を求める(修正ver)

先日5個の数字から最大値と最小値を求めるプログラムを投稿しましたが、コメントでアドバイスをいただいたので修正したものを再投稿したいと思います。@LouiS0616 さんコメントありがとうございます...!!

ちなみに前回の記事のリンクをここに貼っておきます。https://qiita.com/GARA41679531/items/c81b57a56bfcb28f84a0

#変更した点
前回のコードでは変数 min と max を 0　で初期化していたので、入力された数字がすべて正の数または負の数の時に最大値もしくは最小値のどちらかが 0 で出力されてしまいました。
そこを改善するために、1つ目に入力された数字を変数 min と max に代入し、そこから大小関係を調べるコードに書き直しました!

#コードの記述
```Java
package max_min;
import java.util.*;
import java.math.*;

public class Max_Min {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		Scanner scanner=new Scanner(System.in);
		double max=0;
		double min=0;
		int i;
		double a;
		
		System.out.println("5個の数字の中から最大値と最小値を求めます。");
		
		for(i=1;i<6;i++) {
			System.out.print(i+"つ目の数字：");
			a=scanner.nextDouble();
			
			if(i==1) {
				min=a;
				max=a;
			}else {
				if(a<=min) {
					min=a;
				}else if(a>=max) {
					max=a;
				}
			}
		}
			System.out.println("最大値は"+max+"です。");
			System.out.println("最小値は"+min+"です。");
		
	}

}

```
上記に載せたコードが実際に書き直したコードです。

具体的にどこを変えたのかというと、 for 構文を使って5回数字を入力するプログラムを作っているのですが、その中で if 構文を使って1つ目に入力した数字を変数 min と max に代入させるようにしています。

#実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532357/cfe65d9d-af92-967e-9ad9-82e3c15155ee.png)
今回はすべて負の数を入力してみましたが、最大値が 0 になることなくちゃんと表示することができました!!

#まとめ
自分では完璧と思っているプログラムでも改善点は隠れているのだなと改めて実感しました ! 笑
今回記述したコードの中にもまだまだ改善点があれば教えていただけると幸いです ! 
最後まで目を通していただいてありがとうございました !!
matplotlibで作図入門: 簡単な関数を書く

**この記事を読むとできるようになること**
`matplotlibで超基本的な図が描ける`

gnuplot で図が作れるようになってしばらくすると，「もっと簡単に綺麗な図が描きたい」と思うようになると思います（※個人差があります）．
研究発表の図を作るのに無料で使えるツールとして有名なものの1つがmatlotlibです．かなり綺麗な図が描けます（※個人の意見）．
この記事では，すぐに使えるmatplotlibでの図の描き方の基礎中の基礎だけをまとめました．

**より詳細な使い方については，
[pythonのmatplotlibの使い方をまとめてみた](https://qiita.com/renesisu727/items/24fc4cd8fa2635b00a0d)
が大変わかりやすく，参考になります．**
特に，オブジェクト指向インターフェースは便利ですので使えるようになると良いです．


- 環境
    - macOS mojave 10.14.6
    - Python 3.7.5

ここではmatplotlibを用いて簡単な関数を描いてみましょう
$y = f(x)$ を描く時にコンピューター上で何が行われているかというと
（わかりやすさのために用語の正確さは無視すると），
$x$の組（配列）の要素$x_i$ のそれぞれに対し，
$y$の組（配列）の要素$y_i$ が計算されて，その組がプロットされています．
gnuplot でも同じです．
（なので，特に対数プロットにおいて，変化が急な部分ではプロット点を細かくとってあげないと正しい図にならないことがあります）

Python では次のようにして組$x$を作ることができます．
これは等差数列の配列を作っていると思ってください．

``x = numpy.arange(-10, 10, 0.01)``
引数は，
``x = numpy.arange(xの最小値，xの最大値，公差)``
です．
この等差数列（みたいなもの）を使って$y = f(x)$ を描画することができます．
では，試しに放物線を描いてみましょう．

```Python:sample.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# これはコード中に全角文字（日本語）を書く時に必要

#以下はおまじないみたいなもの
#numpy に np という名前をつける
import numpy as np
#同様に，matplotlib.pyplot に plt という名前をつける
import matplotlib.pyplot as plt

#x = np.arange(xの最小値，xの最大値，刻み)
x = np.arange(-10, 10, 0.1)
#描画する関数
y = x*x

#横軸にx，縦軸にyをとって描く
plt.plot(x, y)

#plot表示
plt.show()
```
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403437/cb507cca-b617-1ce1-53e0-58488dba6c1c.png)


では，次によく使うオプションをつけていろいろ描いてみましょう．

```Python:sample2.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(-10, 10, 0.1)
y = x*x

#描画範囲を指定する場合（x軸でも同様）
plt.ylim([0, 50])

#タイトルと軸ラベル
plt.title("TITLE")
plt.xlabel("Xlabel")
plt.ylabel("Ylabel")

#grid表示のon/off （デフォルトはFalse）
plt.grid(True)

#ラベルや線色，太さなどのオプション
plt.plot(x,y, label="legend", color="red", lw=3, ls="--")

#凡例を表示
plt.legend()

#plot表示
plt.show()
```
![sample2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403437/f21c0907-b427-0c3c-6fe7-2b92f0ed04f7.png)

図を保存するには，最後に
``plt.savefig("sample_figure.eps")``
などと書けばOKです．

ここで紹介したものは一例で，他のオプション（線色とか線種とか凡例の位置とかその他いろいろ）はググって必要なもの/お気に入りものを見つけてみてください．
Excelマクロ（VBA）からREST APIを呼び出して値を取得

# やりたいこと
ExcelマクロのVBAから、あるサイトのREST APIを呼び出して結果を取得したい。

元々、あるサイトからCSV出力してマクロで加工してましたが、CSVに載っていない項目がけっこうありました。
でもREST APIから取得できるとわかったので、VBAからREST API呼出しする方法を調べました。
（REST API呼び出すって最初からわかってたら、マクロ以外の方法を考えていたと思いますが、後戻りできず。。）

一貫してまとめてあるサイトが少なくいろいろ調べたので、ここにまとめておきます。

# VBA-JSONというVBAツールをダウンロード

以下サイトからJson変換、値取得などが簡単に行えるVBA用ツールをダウンロードして設定します。
https://github.com/VBA-tools/VBA-JSON

チュートリアルのビデオで、設定方法や使い方がわかりやすく解説されているのでオススメです。
READMEの下の方「Resources」の以下リンクから。
・Tutorial Video (Red Stapler)

# コード＆解説

コードはこちらからどうぞ
https://tamcom.jp/blog/call-rest-api-from-vba
Private Bitbucket Repository から ssh で pipenv install する

ssh鍵設定はしている前提で、自分のプライベートリポジトリを pipenv install する場合のやり方を忘れるのでメモ。

```bash:pipenv&nbsp;install
pipenv install git+ssh://git@bitbucket.org/[ユーザ名]/[リポジトリ名].git#egg=[egg名]
```

成功すると Pipfile にこんな感じに記録される。

```text:Pipfile
[packages]
...
[egg名] = {git = "ssh://git@bitbucket.org/[ユーザ名]/[リポジトリ名].git"}
...
```
Rubyの多重継承優先順位まとめ

# はじめに
言語の基本的な動作を確認する作業って、ついサボってしまうことが多いのですが、今回は職場の先輩に時間を頂いて
あらためてRubyで多重継承に伴うメソッドの呼び出され方を検証しました。

Rubyはクラスの多重継承ができない言語ですが、Moduleを用いて事実上の多重継承を可能にしています（Mixin方式）

# ケース１:複数のModuleを継承

```ruby
module Foo
  def do_task
    puts "I'm in Foo class!"
  end
end

module Bar
  def do_task
    puts "I'm in Bar class!"
  end
end

class Child
  include Foo
  include Bar

  def execute
    do_task
  end
end

instance = Child.new
instance.execute # which task is called?
```

結果：後勝ち

```
$ ruby case1.rb
I'm in Bar class!
```


# ケース２：親クラス継承＋Module取り込み

```ruby
module Foo
  def do_task
    puts "I'm in Foo class!"
  end
end

module Bar
  def do_task
    puts "I'm in Bar class!"
  end
end

class Parent
  def do_task
    puts "I'm in the Parent class!"
  end
end

class Child < Parent
  include Foo
  include Bar

  def execute1
    do_task
  end

  def do_task
    super
  end
end

instance = Child.new
instance.execute1 # which task is called?
instance.do_task # which task is called?
```

結果：取り込むModuleの後勝ち

```
$ ruby case2.rb
I'm in Bar class!
I'm in Bar class!
```


# ケース３：菱形継承（ダイヤモンド継承）



```ruby
module Parent
  def do_task
    puts "I'm in the Parent class!"
  end
end

module Foo
  include Parent
end

module Bar
  include Parent
end

class Child
  include Foo
  include Bar

  def execute
    do_task
  end
end

instance = Child.new
instance.execute # which task is called?
```

結果：問題なく実行可能

```
$ ruby case3.rb
I'm in the Parent class!
```



# まとめ

というわけで、Rubyではダイヤモンド継承にまつわる問題も回避できていること、基本的には後に書かれたものがオーバーライドするという挙動を確認しました。

複雑なコードでは随所に継承やModuleの取り込みを行いますので、このような基本的コードで挙動を検証するのもたまにはいいかもしれませんね。

多重継承については、[Wikipedia](https://ja.wikipedia.org/wiki/%E8%8F%B1%E5%BD%A2%E7%B6%99%E6%89%BF%E5%95%8F%E9%A1%8C)でも一定量の知識を習得できるので、CSバックグラウンドがない方やエンジニアになりたての方はあらためて確認してみても良いかもしれません
MetabaseでのLDAP認証設定

# MetabaseでのLDAP認証設定

## この記事の目的
たいしてLDAPの知識もないのにMetabaseを社内のADと連携させてLDAP認証させようと思ったら、なかなか説明している記事が見つからず、適当に設定したらひどい目にあったので、設定方法、内容を残します。

## 前提条件
* OS  
Ubuntu 18.04.3 LTS
* Metabase  
0.33.5

## 設定方法、内容
### LDAP認証設定の場所
管理者のユーザーでログインし、右上の歯車のマークから「管理者」を選択することで管理者用画面に飛びます。
「設定」のメニューから「認証」を選択し、「LDAP」の「設定」を押します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/e5620e29-1810-2095-47ef-3afd1db7f8e1.png)


### 設定画面
設定画面と各項目の説明です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327819/c3620614-3963-5608-9d61-c77e86af55ba.png)

#### サーバー設定
① LDAP認証
まずこれを「有効」にしないと以下の項目を設定してもログイン時LDAP認証してくれません。

② LDAPホスト
ADサーバーのホスト名、またはIPアドレス。「ldap://」は不要です。

③ LDAPポート
LDAPの場合は389、LDAPSの場合は636。

④ LDAPセキュリティ
SSL、STARTTLSを使用している場合はそちらを、使用してない場合はNone。

⑤ ユーザーネームまたはDN
MetabaseがADを検索する際に使用するユーザー。
自分が設定したのはAdministrator@ドメイン名。

⑥ パスワード
⑤のユーザーのパスワード

#### ユーザースキーマ
⑦ ユーザー検索ベース
絞り込むユーザーのDN。
自分が設定した際はOUに部署のGroupを設定。

⑧ ユーザーフィルター
LDAPの検索フィルター。
ここを適当に「&(ObjectClass=User)」と設定した結果、Metabaseの再インストールまで実施する羽目になった。
動きとしては、Metabaseのログイン時まずこの検索フィルターを用いてADを検索し、ヒットすればADのユーザーで認証し、ヒットしなければMetabaseのローカルユーザーで認証しているようです。
`|(uid={login})(mail={login})`の{login}はログイン画面でユーザーが入力したユーザー名(メールアドレス)を指すので、「ログイン画面で入力したユーザー名がADのuidまたはmailに該当する」という条件です。
これが抜けていたのでログイン画面で何を入力しようがヒットするのは必ずADの全ユーザー中の先頭1ユーザーで、結果ローカルの管理者ユーザーもログインできなくなり、LDAPの設定も戻せなくなって詰んでしまいました。
ちなみに初期設定時は記入例がうっすら表示されているけど途中で切れています。

⑨ メール属性
「▶属性」を押さないと表示されません。
AD情報のメール属性を指定。デフォルト値の「mail」でよければ何も入力しなくてよいです。

⑩ 名の属性
「▶属性」を押さないと表示されません。
AD情報の名の属性を指定。デフォルト値の「givenName」でよければ何も入力しなくてよいです。

⑪姓の属性
「▶属性」を押さないと表示されません。
AD情報の姓の属性を指定。デフォルト値の「sn」でよければ何も入力しなくてよいです。

#### グループスキーマ
ADのグループとMetabaseのグループを同期する場合はこちらを設定します。  
今回は割愛。

### 変更を保存
「変更を保存」を押して完了です。
設定に誤りがある場合は画面に赤字で表示されます。
自分が引っ掛かったのは「⑤ ユーザーネームまたはDN」あたりのフォーマットです。
これは環境によって書き方が異なるかもしれないのでAD管理者に相談した方がよいかもしれません。

正常に保存できたらADのユーザーのメールアドレスとパスワードでログインを試してみてください。

## 参照
https://www.metabase.com/docs/latest/administration-guide/10-single-sign-on
Metabaseの公式説明。ただユーザースキーマの設定内容等はだいぶ割愛されていてあまり役に立たなかった。
別のAWSアカウントのSNSに通知を飛ばす方法 


#背景・やりたいこと
何かある度に（例えば、ヘルスチェックのエラーだったり、負荷が高くなったり、オートスケールが走ったり）
管理用のメールアドレスに通知を飛ばしたかったりする。
もちろんそういう場合はCloudWatchなどで監視して、SNSに通知を飛ばし、そこからメールを飛ばす構成が一般である。

SNSにアクセスして、新しくトピックを作成し、更にそこに新しいサブスクリプションを追加し、
送信したいメールアドレスを追加して、認証メールを受け取って承認すれば、
このトピックあての通知は設定したメールに通知されるようになる。
後はCloudWatchのアラームが上がったときなどにこのトピックあてに通してあげればよいわけだ。
![構成１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361076/c37a0085-c877-ec39-2ec5-d2411b7369af.png)

しかし、アカウントがひとつの場合は、ここまでの設定でやりたいことが解決するのだが
AWSアカウントを様々な事情で複数持っていると、特に２桁を超えてくると厄介である。
例えばメール通知したいアドレスが変わったり、増えたりしたら、すべてのアカウントに入って
その都度設定しなおさなければならない。
しかも受け取り側に、認証メールが何十通も届くことになる。
![構成２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361076/e2dcda56-5a8f-27e1-2c01-d959cbccaf2a.png)

そこで、１つのAWSアカウントを代表アカウントとして、
その中で構築したSNSに対して、他のアカウントの通知を送り付けたくなる。
![構成３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361076/ac049b05-87cf-650b-56e1-10572f47c772.png)

ということで、そんなことができるよう設定してみる。

#設定方法

トピックをAWSマネジメントコンソールにて新規作成する場合、
*トピックお作成 ＞ アクセスポリシー - オプション*
より

|設定項目|選択する値|
|:-----------------|:-----------------|
| メソッドの選択|基本|
|トピックにメッセージを発行できるユーザーを定義します|全員|
|このトピックにサブスクライブできるユーザーを定義します|トピック所有者のみ|

とすることで、他のAWSアカウントから通知を受け取れるようになる。


既存のトピックを共有したい場合は、アクセスポリシーを直接いじることになる。
初期のなにもいじっていないポリシーの場合

```JSON
"Statement":[ {"Sid": "__default_statement_ID", "Effect": "Allow", ... }, ]
```

という値が入っているはずなので、このリストに以下の内容を追加する。

```JSON
{
    "Sid": "__console_pub_0",
    "Effect": "Allow",
    "Principal": { "AWS": "*" },
    "Action": "SNS:Publish",
    "Resource": "arn:aws:sns:<<使用リージョン名>>:<<AWSアカウントID>>:<<SNS名>>"
}
```
**※\<\<使用リージョン名>>　\<\<AWSアカウントID>>　\<\<SNS名>>は適宜値を入れ替えてください**
<br>
セキュリティ的にすべてのAWSアカウントより通知を受け取るのがまずいという場合は

```JSON
{ "AWS": "*" }
```
を

```JSON
{ "AWS": [ "111111111111", "22222222222222", ... , "777777777777" ] }
```
の様に書き換えると、リストに指定したAWSアカウント以外からの通知をはじくようになる。


後は他のAWSアカウントで、上記で設定したSNSを通知する先に設定してあげればよい。
設定する場合はARNを用いることになるので、確認をしておこう。
#まとめ
想像以上に簡単に設定できました。
boto3でCloudwatchのアラームを自動生成する（後日執筆予定）時に指定するSNSとしても最適ですね。
mb_strimwidth in PHP

# convenient build-in function 

テキストデータを一定の文字数で[...]したい時に便利。
こういうのがあるのは知りませんでした。
勉強不足ですね。

```php
	$text = "春はあけぼの。やうやう（ようよう）白くなりゆく山ぎは（やまぎわ）、少し明（あ）かりて、紫（むらさき）だちたる雲の細くたなびきたる。 春は、明け方（あけがた）が良い。 だんだん、白くなっていく山ぎわが、 少し明るくなって、紫がかった雲が、細くたなびいているのが、";

	echo mb_strimwidth($text,0,120,"...","UTF-8");

//春はあけぼの。やうやう（ようよう）白くなりゆく山ぎは（やまぎわ）、少し明（あ）かりて、紫（むらさき）だちたる雲の細く...
```
http://php.net/manual/en/function.mb-strimwidth.php
【超簡単】1分で独自コマンドを作ってみる(Mac・Linux)

#やりたいこと
"Hello World!"と表示するコマンド「myhello」の作成

#手順
1. ターミナルを開く
2. `myhello`を叩き、 `command not found` が返ってくることを確認する(すでに同名のコマンドが作成されていないかチェック)
3. `cd /usr/local/bin` を叩く(パスが通っている任意のディレクトリに移動)
4. `vi myhello` を叩く(myhelloというファイルを作成し、vimで編集)
5. `echo "Hello World!"`　の一文を記述し、保存
6. `chmod a+x myhello` を叩く(全てのユーザーに実行権限を付与)
7. `myhello`　を叩き `Hello World!` と表示されることを確認する



#結果
<img width="381" alt="独自コマンド作成結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181210/2d424016-f571-ee7a-fb6d-09227adf8164.png">


これで、今後どのディレクトリからでも`myhello`コマンドを叩けば`Hello World!`が表示されるようになります。