OmniAICreator/Qiita-1.07M huggingface dataset:
新人プログラマ向けMTG術

*プレインズウォーカーになろうって話じゃないよ！ミーティングだよ！* 

# 1. チケットを使おう
大抵のまっとうな開発では、タスク管理ツール (バグトラッキングシステムと言ったりいろいろですが) が導入されています。
通常、殆どの作業はこのツール上にあるタスク、チケットで管理されています。

**大抵の報告、連絡、相談のたぐいはこれで済みます。何かあったときは** (そうするなという命令がないなら) **今やっている作業のチケットに記録しましょう。**
そもそもミーティング自体がチケットベースで進んでいく現場も珍しくありません。
現状がチケットへ記載されているなら、それに越したことはないのです。

**Excelで書くのだけはやめましょう**。よっぽど込み入った表が必要ならともかく、ちょっと箇条書きにしたり、スクリーンショットにMSPaintで書き込めば済むものをExcelで書くのはいくらなんでもおさるさんです。

# 2.箇条書きを使おう
**時間は有限です**。
まずあらかじめ、いくつかの項目に分けて、言うべきことを箇条書きにしておきましょう。
予めこれをチャットやなにかで投げておくことも有効です。**割とこれで解決します**。

私の場合、概ね以下の項目に分けています。

* わからないこと  
文字通り、現在の知識や資料ではわからない、断定できないこと。  
「仕様のここがいまいちピンと来ない」というのはここ。ここからバグが見つかることもよくあります。
* 迷っていること  
設計や実装のパターンをどういう方向に向けたほうがよいかなど、あまり具体的でないし重要度も低いこと。  
「うーん、なんか引っかかるなあ」はここ。
* 判断が必要なこと  
具体的な選択肢があり、その内容がサービスや仕様に関わるのはここ。  
「今ここにこれこれこういうのがあるんですが、このまま行くとこういう問題があります。仕様を修正すれば対処できますが……」なんてのはここ。
* 共有したいこと  
対処済みの問題やちょっとした気付き。  
「このライブラリ、こういう時の挙動が妙でした。注意が必要かも」なんてのはここ。

# 3. どういうミーティングか確認しよう
**ミーティングの形は、発言者と予定時間で決まります**。
ミーティングの形に合わないことをするといろいろグダグダになります。

*※ 以下の類型は私が勝手にそう呼んでるだけであり、あまり厳密な/体系立ったものではありません。*

## A. 相談型
**だいたい数人レベルまで 一人あたり時間: 10分前後**
一番ありがたいミーティングです。なんでありがたいかって、**管理側からすると一番手間のかかるミーティングだから**。
だいたいは 1on1 で20～30分、または数人規模の小さなチームが 1時間、ぐらいの規模になります。

こういうときは本当に楽です。
**2. に書いたような内容を片っ端からかき集めてじっくり相談しましょう。ソースや資料を持ち込めるとなおよいです。**

ただし、なんらかの高度な (営業的な/政治的な/人事その他的な) 判断が必要な場合、この形のミーティングでは即座に解決しないものです。
そういった内容が含まれそうなら、**ミーティングを待たずにさっさと相談しましょう**。

## B. 共有型
**数人～十人規模 一人あたり時間: 5分前後**
よくある普通のミーティングです。
重要なのは、**解決法や善後策を相談するような時間はないと意識することです**。
このため、発言を求められた時、相談したいことがあるなら、問題の概略を話した上で**「あとで相談させてくれ」**としてさっさと終わりましょう。
**あなたが一分短く済ませれば、皆の一分が節約されます**。

## C. 報告型
**えらいひとあいて**
……この記事「新人プログラマ向け」なのでそうそうないと思うんですが、たまにあるんですよね……営業に連れて行かれたら何故か先方の偉い人が出てきたとか……

とりあえず、**黙ってましょう**。そして、**先輩社員に頼りましょう。**
その上で、できるだけ聞いて、何を言われそうか先回りで考えてみてください。運が良ければ「おっ、こいつ、デキるな……？」と評価されます。
よっぽどアレな会社でなければ、偉い人相手に、新人をフォローもなしにぶち込むような真似はしないはずです。**されたらなんかもう危ないので辞めていいです。**

# 4. できるだけミーティングの外に追い出そう
**ミーティングで最も重要なことは、ミーティングに持ち込まなくてよいことをミーティングから追い出すことです。**
その「設計の相談」、ミーティングじゃないと駄目ですか？
その「実装の質問」、ミーティングじゃないと駄目ですか？

……「ミーティングの時ぐらいしか相談先が捕まらない」？
そりゃあ、その事自体をミーティングでぶち上げるか、もっと上位の人間に相談するべきでしょうね。
sedで改行、タブを除くバックスラッシュをエスケープする

# Escape backslashes except newlines and tabs with sed

```bash
sed -e 's/\(\\\)\([^rnt]\)/\\\\\2/g' text
sed -e "s/\(\\\\\)\([^rnt]\)/\\\\\\\\\2/g" text
```

いや、sedでやる必要はないのでは
EC2上のApache（複数バーチャルホスト）https化・常時SSL化に際し参考にさせていただいたページ

# はじめに
EC2上にApacheを立ち上げ、複数のVirtualHostを公開しているが、そのうちのいくつかをhttps化（常時SSL化）したくなった。
複数VirtualHostがネックになって一筋縄ではいかないということが途中でわかったものの、予想以上に簡単に実現できた。
参考にさせていただいたページを以下に一覧。情報を公開してくださっている皆様に感謝します。

# 基本はこちら
## AWS EC2にLet's Encryptを導入してみた
https://qiita.com/MashMorgan/items/56498f276c54406b1928
certbotのインストールとか

ssl.confのどこにこの記述を追加すればいいんだろう？

# SSLを使っているとバーチャルホストが使えない？
## グローバルIPアドレス1つで複数のSSLサイトを立ち上げてみた
https://business.biglobe.ne.jp/hosting/blog/tech/20150324111454
## 名前ベースのバーチャルホストでSSLを使う（SNI）
https://blog.apar.jp/linux/378/

# ssl.confのSSLCipherSuiteってどう書くんだこれ？
## Apache で SSL/TLS 証明書を使用したサイトの評価を A+ にする
https://www.websec-room.com/2016/05/06/2606
SSL/TLS証明書がどのレベル（バージョン）を許可しているかを外部からテストしてくれる
オンラインツールを紹介。

# 後始末（http側の閉鎖）
## apacheでhttpへのアクセスをhttpsへ自動リダイレクトする
https://qiita.com/sue71/items/100004b704b9ff129b09

# 後始末（httpsサイトをSearch Consoleに追加、アドレス変更を申請）
## サイトのHTTPS化で必要となるGoogleサーチコンソールの再登録方法
https://nelog.jp/reentry-google-search-console

# 限定サイト（Digest認証をかけている）だとcertbotが遮断されてしまう
## IPアドレス制限下でもcertbotの無料SSL証明書を発行してもらう方法
https://qiita.com/AkihiroTakamura/items/06ced4e780dc217bc1aa

# PukiwikiのURL変更手順は？→iniファイルでURLを変更するだけ、の模様
## Pukiwikiのサーバ移行（old_3流プログラマのメモ書き）
https://jehupc.exblog.jp/15558893/
ゴミの日が覚えられないので、slackとechoに教えてもらうようにした

新卒で引っ越ししたばっかりでゴミの日が覚えられません...。
まぁ実家でもゴミの日を忘れることはよくあったのですが 笑

ということで、
**全くゴミの日情報を覚えていなくても、SlackとEchoにリマインドしてもらえればゴミ出しできる！(※ 寝坊さえしなければ)**

という事を**超簡単に**実現しました。

# どうなるか
## slackリマインド
ゴミの日の朝にslackでリマインド 

 >Event staring in 15 minutes:
可燃ゴミ 
7:00 AM ~ 8:00 AM

## echoで予定確認
「Alexa！明日の予定は？」
「明日は予定が1件あります。朝7:00 ~ 8:00 可燃ゴミ　です。」

## (オプション)iPhoneに通知
~ゴミ捨て日朝7時~

ぴろん！(iPhoneにリマインダーで通知)

# 利用するもの
- Slack
- Google Calendar
- Echo
- (オプション) IFTTT

# Google Calendarのゴミの日予定をslackに投稿する
## slackとGoogle Calendarを連携させる
公式の[GoogleカレンダーとSlackを連携させる ](https://get.slack.help/hc/ja/articles/206329808-Google-カレンダーと-Slack-を連携させる)というページがあるので、これで**ゴミの日のカレンダーと投稿したいslackチャンネルを紐づけてください。**

僕の場合は、ゴミの日カレンダーと家族予定共有チャンネルを紐づけています。ゴミの日スケジュールを7:00 ~ 8:00で作成して、開始時間にリマインドされるようにしています。

![スクリーンショット 2018-04-07 14.23.52.png](https://qiita-image-store.s3.amazonaws.com/0/114709/0767057e-8243-af64-4171-531350e90493.png)

## Google Calendarにゴミの日の予定を追加する
slackと連携するカレンダーにゴミの日を追加します。
基本的には隔週や、毎週火・金に可燃ゴミ。などのルールで追加すれば問題ないのですが、以下のようなパターンがあります。

> 第1・第3木曜は資源ごみ、第2・第4木曜はペットボトル

これが、確実に2週間に1度なら問題ないのですが、**第5週目の回収は行わない。**というルールがあるとズレが生じます。

なので以下のように、「月1回第○(偶数)木曜日にペットボトルごみ」というのを2件作成します。同様に「月1回第○(奇数)木曜日に資源ごみ」というのを2件作成します。

![スクリーンショット 2018-04-07 11.55.54.png](https://qiita-image-store.s3.amazonaws.com/0/114709/f50a763a-e1bf-2881-1919-7c22ebf15d1b.png)

![スクリーンショット 2018-04-07 11.57.41.png](https://qiita-image-store.s3.amazonaws.com/0/114709/17f08ec0-9f0d-3051-571b-d545ec3ac817.png)

Google Calendarの繰り返しルールで、あまり複雑なルールが設定できないみたいので分けて設定するしかないです。
公開設定にしたかったのですが、どこの地区に住んでるかモロバレなのでやめました。

# ゴミの日予定をEchoに教えてもらう
これはEchoとGoogle Calendarをリンクするだけで終わりです。

[Echoにカレンダーをリンクする](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=202126980)で、簡単にリンクできます。

# (オプション) iPhoneに通知する
[IFTTT](https://ifttt.com/)を利用することによってiOSのリマインダーにゴミ捨て予定を登録し、指定時間に通知を出すことが出来ます。画面上では**Alarm**と出ていますが、これは時計のアラームを鳴らす機能ではなく、**ただ通知を出すだけの機能なのでご注意を。**

slack通知とechoでの予定確認の上の最終予防線ということで、オプションにしておきました。

IFTTTで以下のようなアプレットを作成します。

>if Google Calendar : Any event starts 
then iOS Reminders: Add reminder to list

![スクリーンショット 2018-04-07 13.57.32.png](https://qiita-image-store.s3.amazonaws.com/0/114709/d91e0a98-3e76-a233-5c9d-f8b2b8e7cfc9.png)

![スクリーンショット 2018-04-07 13.57.43.png](https://qiita-image-store.s3.amazonaws.com/0/114709/e4fdda8a-5792-ab28-22d2-c6a6d353c3c1.png)

アプレット実行の遅延が結構あるので、Google Calendarの方はイベントの30分前をトリガーにしておいて、リマインダーのアラームの時間を`{{Starts}}`にしておけば、指定時間に通知が出るようにできます。

※リマインダーにうまく追加されない場合は、設定>IFTTT>リマインダーのボタンをトグルオフ→トグルオンしてやり直してみてください。僕はそれでうまくいきました。

# 実装までの所要時間
**1時間程かと思われます。**

iOSのリマインダーでアラームを鳴らす機能が最近実装されたばかりらしくて、情報があまりなかったのと、トグルボタンのon/offをしないとうまくいかないところでハマって2時間ぐらいかかりましたが、それ以外のところは1時間ぐらいで終わってました。

# 感想
色々とツールは使いましたが、**ノーコーディングで**ゴミの日自動リマインドシステムを素早く実装することが出来ました。
このように、小さな生活の自動化をいくつも積み上げて生活の二重化をどんどん無くしていこうと思います！ DRYの原則バンザイ！

これで毎日ぐっすり眠れそうです...🛌
地図タイルの計算まとめ

## 地図タイルとは？
地図の配信に使われる手法
画像やGeoJSON/Protocol Buffersとかで配信される
これの計算メモ。

![タイル座標.jpg](https://qiita-image-store.s3.amazonaws.com/0/232676/60cd9374-b5b3-8c81-2219-813ae659ea1b.jpeg)
拡大率(Level)Z/とXYで表される。


![osm00.png](https://qiita-image-store.s3.amazonaws.com/0/232676/4689416d-d846-bba9-edf2-0ce4e810120d.png)|![平射.png](https://qiita-image-store.s3.amazonaws.com/0/232676/446e0a53-c124-d33b-0778-9950657e65ea.png)
© OpenStreetMap contributors

左がGoogle Maps/OSM/地理院地図などインターネットで使われる地図の表示方法(EPSG:3785)
※実際地球は丸く(楕円形)正方形で表すと歪むので距離単位mはあくまで投影している図面上の距離や面積なので注意

EPSG:3785
Pseudo-Mercator/Spherical Mercator
900913 3587 54004 41001 102113 102100
http://epsg.io/3785

### タイルのレベルの計算
タイルのレベルは拡大率 L0は全世界でL1,L2とレベルが上がると表示領域が拡大される。

世界を正方形で表す = 球体
座標値:メートル単位

半径:6378137の球
2×r×π= [円周長:] 40075016.6855784861531768177614

つまり正方形の世界の一辺の長さ=球の円周長でこれを256pxで表したのがレベル0。
レベルは1pxが何mかで表され、レベル0を4タイル(1タイルは256pxの正方形)で表現したのがレベル1(Quadtree)。

[円周] / 256pxで約15,654メートル/px

L08で1px=611.49メートルくらい
L17で1px=  1.19メートルくらい

これを求める計算

```typescript
const GEO_R:number = 6378137;
let level:number = 15

window.document.write(
  (2 * GEO_R * Math.PI / 256 / Math.pow(2, level)).toString()
);
```

### 緯度経度からタイルXYを求める

グリニッジ子午線-赤道がxy:00なので円周長を半分に割った値が北西端(左上端)
[円周長:] 40075016.6855784861531768177614 / 2

-20037508.3427....
 20037508.3427....

レベルが指定された場合、
左上端を原点としてタイルは始まるので256px=何メートルがあれば原点XYとのm差で割るだけで行番号(y)列番号(x)が求まる。

緯度経度とm単位の換算は探せばいくらでも出てくる。
degrees2meters.js
https://gist.github.com/onderaltintas/6649521
緯度方向が高緯度になるほどm単位が加算される

```typescript
let degrees2meters = function(lat:number, lon:number) {
  var x = lon * 20037508.34 / 180.0;
  var y = Math.log(Math.tan((90.0 + lat) * Math.PI / 360.0)) / (Math.PI / 180.0);
  y = y * 20037508.34 / 180.0;
  return [x, y]
}

const GEO_R:number = 6378137;
const orgX = -1 * (2 * GEO_R * Math.PI / 2);
const orgY = (2 * GEO_R * Math.PI / 2);

//let xy = degrees2meters(36.104600,140.085871);
//let level =17;
let xy = degrees2meters(35, 135);
let level =15;

let unit = 2 * GEO_R * Math.PI / Math.pow(2, level)

let xtile = Math.floor((xy[0] - orgX) / unit);
let ytile = Math.floor((orgY - xy[1]) / unit);

//https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png

window.document.write( `https://cyberjapandata.gsi.go.jp/xyz/std/${level}/${xtile}/${ytile}.png` )
```
都合こんな感じで35,135辺りのタイルを参照できる。

### タイルXYZから緯度経度を求める

タイルXYZから緯度経度(北西/左上起点)を求める。(unit足し引きで4隅)

```typescript
let meters2degress = function(x,y) {
  let lon = x *  180 / 20037508.34 ;
  //thanks magichim @ github for the correction
  let lat = Math.atan(Math.exp(y * Math.PI / 20037508.34)) * 360 / Math.PI - 90; 
  return [lon, lat]
}


let level = 15;
let xtile = 28671;
let ytile = 12979;

const GEO_R:number = 6378137;
const orgX = -1 * (2 * GEO_R * Math.PI / 2);
const orgY = (2 * GEO_R * Math.PI / 2);

let unit = 2 * GEO_R * Math.PI / Math.pow(2, level)

let x = orgX + xtile * unit;
let y = orgY - ytile * unit;

let latlon = meters2degress(x,y);

window.document.write( `https://maps.gsi.go.jp/#${level}/${latlon[1]}/${latlon[0]}/` )
```
LaravelでS3にある画像を全てローカルにコピーする

Artisanコマンドを作成し、「php artisan dev:images」などを実行してコピー出来るようにします。その際のhandle関数はこちら。

```App\Console\Commands\CopyS3FilesToStorage.php
/**
 * 保存するS3バケットのディレクトリ
 *
 * @var array
 */
protected $shouldCopyDirectories = [
    'user-profile-images',
    'team-profile-images',
];

public function handle()
{
    $prodS3Disk = Storage::disk('s3');

    // ディレクトリにある全てのファイルを一次元配列として取得
    // ディレクトリの中にディレクトリがあっても再帰的に取得されます
    $allFiles = array_reduce($this->shouldCopyDirectories, function ($stack, $directory) use ($prodS3Disk) {
        array_push($stack, ...$prodS3Disk->allFiles($directory));
        return $stack;
    }, []);

    // ファイル数を取得しプログレスを開始
    $bar = $this->output->createProgressBar(count($allFiles));

    $publicDisk = Storage::disk('public');

    // コピー処理
    foreach ($allFiles as $file) {
        // 既にコピーされていればコピーを実行しません
        if (!$publicDisk->exists($file)) {
            $publicDisk->put($file, $prodS3Disk->get($file));
        }

        // プログレスを進める
        $bar->advance();
    }

    // プログレスを終了
    $bar->finish();
}
```
ReNom TDA GUIを使ってタイタニックのデータを分析

#はじめに
　先日、AI・人工知能Expoに行った際、GRIDのブースで ReNom TDAについて聞いてきました。
データを可視化するのに使いやすく理解の助けになりそうと思い、githubから持ってきて
試して見ました。まずはGUIでcsvファイルの分析を試して見ます。

#準備
インストール手順や、使い方等は ReNomのサイトに詳しく書いてあります。

## インストール
ReNom本体
http://www.renom.jp/ja/rsts/renomdl/main.html

ReNom TDA
http://www.renom.jp/ja/rsts/renomtda/main.html

ReNom TDA APIでの使用例
http://www.renom.jp/ja/notebooks/tda/mnist-dataset-mapping/notebook.html

GUIでの使い方
http://www.renom.jp/ja/notebooks/tda/how-to-use-gui/notebook.html

#GUIでデータ分析する場合のポイント
データ分析では有名なtitanicのデータを分析してみると事にしました。その際少しハマったところは下記の点です。

- Csvファイルを、インストールしたReNomTDA以下の gui/data  以下にコピーする必要がありようです。
- 欠損価があるとそもそもloadできなさそうなので、欠損値のある行はとりあえず削除
- テキストは分析対象にならなさそうなので、数値に置き換え。例えば sex は male=1とfemale=2など 
- 名前など分析対象外のものは列ごと削除

上記をまとめて対応したスクリプトです。
```
 sed 's/"\([^"]*\)"/"pname"/' train.csv | cut -d, -f1,2,3,5,6,7,8,10,12 | sed '/,,/d' |  sed 's/female/2/' | sed 's/male/1/' | sed 's/C/1/' | sed 's/Q/2/' | sed 's/S/3/' > train_noname.csv
```

train_noname.csvを読み込めると、ヒストグラムが表示されます。
「計算に使う」はターゲットデータであるSurvived以外にチェック、「色に使う」は全選択します。

<img width="1079" alt="Screen Shot 2018-04-07 at 13.12.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/128327/f4228d4d-8833-adb0-9817-96c4bbd6888a.png">

# 分析結果
まずは一般的な主成分分析し、散布図で表示、色はSurvivedかどうかを見てみます。
何となく、生存者かどうか、傾向は見えるように思います。

<img width="977" alt="Screen Shot 2018-04-07 at 13.21.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/128327/29319613-4a7c-897b-d6d8-bdc0884830a2.png">

次に分析モードだけをTDAに変えて、散布図と比較して見たところです。
図はカッコいいのですが、どう見ればいいのかな？
<img width="1202" alt="Screen Shot 2018-04-07 at 13.23.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/128327/3a93620f-4094-fa14-6f2a-4e91a0bdf23a.png">

# 終わりに
正直なところ、どう読み取るべきか、いまひとつ分かりません。
TDA 自体を理解する必要があるようです。
VSTS-CIのCordova-iOSビルドで「 Error code 65 for command: xcodebuild」や「Error code 70 for command: xcodebuild」エラーが表示された時の対処法

# :one: 環境
* VSTS (Visual Studio Team Services) CIサービス (無料プラン)
* Agent: Hosted macOS Preview
* Node.js: v6.14.1
* cordova: v7.1.0
* cordova-ios: 4.5.4

# :two: エラー内容
VSTS-CIのCordova-iOSビルドで以下のエラーが表示された。

```bash:エラー内容：パターン1
Code Signing Error: my-ionic1 has conflicting provisioning settings. my-ionic1 is automatically signed, but provisioning profile 5568-****-****--****--****--****-****6d55 has been manually specified. Set the provisioning profile value to "Automatic" in the build settings editor, or switch to manual signing in the project editor.
Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 11.2'

Error code 65 for command: xcodebuild
```

```bash:エラー内容：パターン2
error: exportArchive: "my-ionic1.app" requires a provisioning profile.
Error Domain=IDEProvisioningErrorDomain Code=9 ""my-ionic1.app" requires a provisioning profile." UserInfo={NSLocalizedDescription="my-ionic1.app" requires a provisioning profile., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}

Error code 70 for command: xcodebuild
```

# :three: 原因
原因の特定はできなかった。
おそらく、xcode-8からプロビジョニングプロファイルが自動取得になったため、CI環境でその自動取得がうまくいっていないと思われる。

# :four: 対応

cordovaのビルド設定ファイル(`build.json`)に、プロビジョニングプロファイル指定方法(`CODE_SIGN_STYLE`)を手動(`Manual`)にして、`provisioningProfile`項目にプロビジョニングプロファイルのUUIDを指定する。

```json:build.json
{
    "ios": {
        "debug": {
            "codeSignIdentity": "iPhone Developer",
            "developmentTeam": "**********",
            "packageType": "development",
            "provisioningProfile": "********-****-****-****-************",
            "buildFlag": [
                "CODE_SIGN_STYLE=Manual"
            ]
        },
        "release": {
            "codeSignIdentity": "iPhone Developer",
            "developmentTeam": "**********",
            "packageType": "app-store",
            "provisioningProfile": "********-****-****-****-************",
            "buildFlag": [
                "CODE_SIGN_STYLE=Manual"
            ]
        }
    }
}
```
1. `developmentTeam`と`provisioningProfile`の`**********`は各々設定する
2. xcode-8から`codeSignIdentity` はdebugとreleaseどちらも`iPhone Developer`にする
新米データサイエンティスト、研修プログラムを考える。

こんにちは、教育業界に就職した新卒1年目のデータサイエンティストです。
新卒研修ということで自分でコンテンツを探してプログラムを組み立てる機会をいただきました！
そこで、折角なので進捗状況や学んだこと等、以後の振り返りのためにポストしていこうと思います。
今回は、自分のスキル状況、目標、具体的なコンテンツについて書いていきます。

##**現在のスキル**
- SQLのSELECT文の基本的な部分が書ける
- pythonがほんの少し書ける（関数の実装くらいまで）
- Tableauが使える（[Tableau アカデミックプログラム](https://www.tableau.com/ja-jp/academic)を利用していました）

ご覧の通り、一般にデータサイエンティストとして必要なスキルがほぼありません...
本当に0からのスタート、何から始めれば良いのか...

##**目標**
目標を立てる上で、こちらの記事を参考にさせていただきました。
[データサイエンティストに必要なスキル要件](https://tjo.hatenablog.com/entry/2017/06/25/185426)
上記事によると、データサイエンティストに最低限必要なスキル要件は

- 東京大学出版会の統計学シリーズ3巻分に該当する統計学の知識
- みどりぼん及びアヒル本に該当するベイジアン統計モデリングの知識と確率的プログラミングのスキル
- はじパタに該当する機械学習の知識
- R / Pythonでコードが書ける
- SQL文法を含むデータベース操作の技術
- クラウドの知識 

となっています。見事にほぼ該当しません。
３ヶ月でここまで完了することは難しいと思ったので、これらのスキルを身に付けることを一年目の目標としました。
その上で、新卒研修の目標として

- データ分析の全体像を理解する
- 統計学の基本を理解する（[統計学入門](https://goo.gl/6rrdXd)に該当する内容)
- 機械学習の基本を理解する([はじパタ](https://goo.gl/d2ZKif)に該当する内容)
- クラウドの知識を付ける

を設定しました。

##**やるコンテンツ**

###統計学の時間 (https://bellcurve.jp/statistics/course/#step1)
- 統計学の基礎知識
- 程よく要約されているかつ章末に簡単な練習問題がある。

研修でこれをやり、自学で統計学入門を進めるという形で取り組んでいきます。

###東大松尾研データサイエンス演習コンテンツ (http://weblab.t.u-tokyo.ac.jp/gci_contents/)
- データ分析の全体像を速習できる
- 演習問題が豊富にある

東大松尾研が個人学習向けに公開されている演習コンテンツです。jupiter notebook形式で、知識を付けるとともにコードを写経し自分で実行してみることもできるということで今回使用させていただくことにしました。

###Cousera_Machinlearning (https://www.coursera.org/learn/machine-learning)
- わかりやすいと有名な講座
- 機械学習の全般

今回、機械学習関連のオンラインコースを調べていたところ、かなりオススメされていたので学習させていただくことにしました。

###Google Cloud Platform Fundamentals:Core Infrastructure (https://www.coursera.org/learn/gcp-fundamentals)
- GCPの基礎部分

クラウドの知識として、GCPについて学ぶことにしました。
まずは一番基礎的な講座をやります。

###From Data to Insights with Google Cloud Platform Specialization (https://www.coursera.org/specializations/from-data-to-insights-google-cloud-platform)
- Bigqueryなどデータサイエンス寄りの機能について

次に実務でも使用する可能性が高い部分を含むコンテンツを学習します。

###Data Engineering on Google Cloud Platform Specialization (https://www.coursera.org/specializations/gcp-data-machine-learning)
- Cloud Dataproc/Cloud Dataflow/Streaming Systems/TensorFlow周りについて

データエンジニア寄りの部分を学習します。
特に、GCPの学習コンテンツはハンズオン形式で学習できるので良いと思いました。

##**終わりに**
以上のコンテンツを入社してから約3ヶ月間行っていく予定です。
頑張っていきます！
rmagickがbundle installできなかった時の対処法について

# Railsでなぜかrmagickがインストールできなかった時の対処法

私の環境
Rails 4.2.5
ruby 2.3.1
Mac OS Sierra
imagemagick 6(7だと失敗するらしいです)

##症状
tarminalでbundle installすると
```tarminal.
Package MagickCore was not found in the pkg-config search path.
Perhaps you should add the directory containing `MagickCore.pc'
to the PKG_CONFIG_PATH environment variable
No package 'MagickCore' found
checking for outdated ImageMagick version (<= 6.4.9)... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.
```
下記を見ると「MagickCore.pc」がないらしい。。。
Perhaps you should add the directory containing `MagickCore.pc'

なので「MagickCore.pc」を探すことに、、、

いろいろググっていると

gem install rmagickで失敗する。
https://qiita.com/KTakata/items/f4a632207af0a8078c06

が出てきました。ここにはパスを通して実行するとありました！

しかし。上記の記事では
MagickCore.pcの場所をあっさり見つけているのですが、私のPCにはない、、、
どうやって見つけたんだ、、、どうやらfindというものをターミナルで使うのか。
（私はプログラミングをを初めて1ヶ月ぐらいなので、、、それすら知りませんでした。みんな知っているのでしょうか）

なので、ターミナルで

```tarminal.
$ find /uer/
```
と入力しいろいろ出てきた中からimagemagickで検索！
探して見ると

```tarminal.
/usr/local//Cellar/imagemagick@6/6.9.9-40/lib/pkgconfig/MagickCore.pc
```
あった！

あとはさっきの
「gem install rmagickで失敗する。」
https://qiita.com/KTakata/items/f4a632207af0a8078c06
で見た$ PKG_CONFIG_PATH=を使ってパスを通してインストールしました。

```tarminal.
$ PKG_CONFIG_PATH='/usr/local//Cellar/imagemagick@6/6.9.9-40/lib/pkgconfig/' gem install rmagick
```
って入れると
```tarminal.
Building native extensions.  This could take a while...
Successfully installed rmagick-2.16.0
Parsing documentation for rmagick-2.16.0
Installing ri documentation for rmagick-2.16.0
Done installing documentation for rmagick after 4 seconds
1 gem installed
```

できた！ということでした。

この記事がインストールの助けになれれば幸いです！
IDは数値じゃない文字列なんだ


IDってどんなサービスでも使いますよね。

例えば、API仕様書に以下の内容が書かれていたとしましょう。

```text:api-spec.txt
articleId: 記事の識別子。整数値。
```

```json:response-sample.json
{
  "articles": [
    {
      "articleId": 1,
      "text": "hoge hoge hoge..."
      ...
    }
  ]
}
```

おそらく MySQL などの auto increment を使うとこんな感じのAPIが出来上がるかもしれません。

このようなAPI仕様書があった場合に、受け取る側では Int型などの数値型でマッピングするべきでしょうか？
私はどんな場合でもString型でマッピングするべきだと思いました。

# 理由
## 理由1: 数値型の表現できる幅はString型に比べて少ない

当たり前ですが、数値型では表現できる限界があります。
言語やOSに依存してしまいますが、32bit, 64bitの場合の unsigned integer で表現できる値は以下です。
- 32bit: 0 ～ 4,294,967,295 (42億9496万7295)
- 64bit: 0 〜 18,446,744,073,709,551,615 (1844京6744兆737億955万1615）

上記を見る限り正直なところ、サービス全体で64bitを扱えるのであれば大抵の場合は問題ないでしょう。
しかし、String型の方が数値型よりも、表現の幅は大きいので、とりあえずString型で良いと思います。

## 理由2: IDには様々なフォーマットがある

ID (identifier) は日本語に訳すると識別子となるように、何かを一意に識別するものです。

要素によっては、UUIDを使ったり、前述した auto increment値を使った整数値かもしれません。
しかし、どんなフォーマットであっても要素を一意に特定する意味しかありません。
IDがどんなフォーマットでもいいよう、受け取る側ではとりあえずString型としておけばいいと思います。

よくある間違いとしては 「IDが数値型の場合は登録順に並ぶから、IDでソートすればいいから数値型で持っておく方が良い」 があると思いますが、IDはあくまでもサービス内で一意な値であって、**要素の大小関係を表すものではありません**。絶対にIDをequal以外で評価してはいけません。

## 理由3: 内部での取り回しが楽

全ての場合でString型でいいじゃんとなればコードを書く場合に、楽。

正直なところ、これが一番大きい理由です。
あっちこっちで、これはIntだ！Stringだ！と考えたり変換したりするよりかは、全てStringだよと決めた方が楽ですよね。

# まとめ

- 表現できる情報量が多いStringの方がベター
- IDがどんなフォーマットでも対応できるようとりあえずStringで良い
- IDはStringだ！って決めた方がコーディングが楽

以上の理由から、 **特別な理由のない限りIDはString型で使う** べきであると私は思います。
あくまでも個人的の意見なので、ぜひ みなさまのご意見をお待ちしております。
表の罫線を引く


```vb
Option Explicit

Sub WriteLines()
Dim baseAreaRow As Long '区切りの罫線引くために、区切り調べる範囲の行
Dim baseAreaCol As Long '区切りの罫線引くために、区切り調べる範囲の列
Dim startRow As Long
Dim startCol As Long '選択範囲の開始列
Dim endCol As Long '選択範囲の終了列
Dim bottomBorder As Border
Dim memoLineStartRow As Long 'これで普通線の行覚えといて、次に普通線出てきたら、その間を破線で埋める？
Dim i As Long

    baseAreaRow = 5
    baseAreaCol = 2
    
    startRow = 6
    
    startCol = Selection.Cells(1).Column
    endCol = Selection.Cells(Selection.Count).Column
    
    memoLineStartRow = 0

With ActiveSheet
    
    For i = 1 To 20 '左端エリア上から見ていくか
        Set bottomBorder = .Cells(i, baseAreaCol).Borders(xlEdgeBottom)
        'xlDashもxlContinuousに含まれる。GUIで引いた破線これxlContinuousのxlHairlineだ。表のんどっちだっけ
        If (bottomBorder.Weight = xlThin Or bottomBorder.Weight = xlMedium) _
        And bottomBorder.LineStyle = xlContinuous Then  '普通の線か太線(winでもxlMedium？)で、かつ実線なら、選択範囲にも同じ実線引いてあと間を破線？で埋める
            .Range(.Cells(i, startCol), .Cells(i, endCol)).Borders(xlEdgeBottom).LineStyle = bottomBorder.LineStyle '線引く
            .Range(.Cells(i, startCol), .Cells(i, endCol)).Borders(xlEdgeBottom).Weight = bottomBorder.Weight 'ひとまず実線引く
            '前回の実線から今回の実線までの間に破線引く
            If memoLineStartRow <> 0 Then
                .Range(.Cells(memoLineStartRow, startCol), .Cells(i, endCol)).Borders(xlInsideHorizontal).Weight = xlHairline '.LineStyle = xlDash         ''''''xlDashだっけ。xlDot？ それかborders.weightがxlhairline？
            End If
            memoLineStartRow = i + 1
        End If
    Next i
    
    '縦線は、横線引き終わって最後のmemoLineStartRowで行範囲が分かってからにする？
    .Range(.Cells(startRow, startCol), .Cells(memoLineStartRow - 1, endCol)).Borders(xlInsideVertical).LineStyle = xlContinuous
    '周囲を太線(winもxlMediumでいい？)で囲う
    .Range(.Cells(startRow, startCol), .Cells(memoLineStartRow - 1, endCol)).BorderAround LineStyle:=xlContinuous, Weight:=xlMedium
    
End With

End Sub


```
Lumen でログファイルをレベルと日付ごとに分けて出力する

[Lumen](https://lumen.laravel.com/) でログファイルをレベル毎、日付毎にわけることができないかといろいろと調べました。

結果、以下の対応が簡単でお勧めです。
　環境：Lumen (5.6.3)

```php:bootstrap\app.php
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
    :
  途中省略
    :
$handlers = [];
$handlers[] = (new RotatingFileHandler(storage_path("logs/critical.log"), 30, Logger::CRITICAL, false))->setFormatter(new LineFormatter(null, null, true, true));
$handlers[] = (new RotatingFileHandler(storage_path("logs/error.log"), 30, Logger::ERROR, false))->setFormatter(new LineFormatter(null, null, true, true));
$handlers[] = (new RotatingFileHandler(storage_path("logs/warning.log"), 30, Logger::WARNING, false))->setFormatter(new LineFormatter(null, null, true, true));
$handlers[] = (new RotatingFileHandler(storage_path("logs/info.log"), 30, Logger::INFO, false))->setFormatter(new LineFormatter(null, null, true, true));

app('Psr\Log\LoggerInterface')->setHandlers($handlers);

return $app;
```

setFormatter() で日付が入るように指定しています。
[RotatingFileHandler()](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Handler/RotatingFileHandler.php) を使い、Logger::XXXX のレベルのログに対して、ログファイルのパスと最大ファイル数を指定しています。
RotatingFileHandler で最大ファイル数を指定することで、古いログは削除されるため、ログが残りすぎる心配がありません。
便利ですね。
　
　
ぐぐると他にもいろいろと方法は出てきます。
多いのが　$app->configureMonologUsing() を使ってログ設定を定義するというものでしたが、どうもこの関数はLumenの最新版では削除されているようで、「未定義の関数を呼んでるぞ！」と怒られますので気を付けましょう。

---
最近、サーバーサイドを始めました。
REST API を作るのに便利なフレームワークはないか探したところ、[Lumen](https://lumen.laravel.com/) が軽量でよいと聞き、勉強しているところです。
VGG16-SSD~ssdkerasのその先１~

#対象
Faaster-RCNN,SSD,Yoloなど物体検出手法についてある程度把握している方．
VGG16,VGG19,Resnet，MobileNetなどをSSDに組み込むときの参考が欲しい方．
自作のニューラルネットを作成している方．

# 1.VGG16とは
オックスフォード大学のVisualGeometoryGroup（VGG）が開発した16層のレイヤーからなるニューラルネットワークであり，他の多くの物体検出手法ではいまだにVGG16がよく使われている．
![VGG16.png](https://qiita-image-store.s3.amazonaws.com/0/246406/b976a013-4637-e977-022d-b46ff8a385e8.png)

筆者がなぜVGG16と書いているかというと，SSDにはそのほかのフレームワークによって精度と速度のトレードオフではあるが，目的に合わせて活用することができるからである．（実際の実装に関する情報はとても少ないのだが・・・）

# 2.VGG16-SSD
この図は見飽きたという方もいるだろうが，YoloとSSDの比較である．
どちらも畳み込み層とプーリング層からなるネットワークである．今回はYoloについては触れないこととする．
![ssdvsyolo.jpg](https://qiita-image-store.s3.amazonaws.com/0/246406/c9a9a866-c0de-0b9d-e0fa-e7bd4dfa9d3d.jpeg)

だいたいどれも同じで，FC層を取っ払ってDetection層を追加している．
カーネルサイズは1，3の組み合わせが主流である．





# 3.　SSDv2AveragePoolling版を試した．
筆者の環境
Keras v2.1.6, Tensorflow v1.6.0 GPU GTX1080

![shibuya.PNG](https://qiita-image-store.s3.amazonaws.com/0/246406/151ef4ee-50c3-d125-d3c5-e2cc0cc577a0.png)



![VGG16-SSD.gif](https://qiita-image-store.s3.amazonaws.com/0/246406/6b5244a2-652a-a3e9-4558-150b23173d8d.gif)



# 4.考察
一般的にObjectDetectionに関してFaster－RCNN，Yolo，SSDのどれも小さい物体の検出は苦手としており，苦労している方も多いであろう．
そんな方には以下の記事がおすすめです．
https://qiita.com/tanakataiki/items/36e71e7d2f5705bd98bb


# 5.終わりに
この記事を見た方はDeeeeeepLearningに興味をお持ちでしょう！
上手くいったカスタムネットワークのプルリクお待ちしています！
https://github.com/tanakataiki/ssd_kerasV2



#　参考
https://qiita.com/God_KonaBanana/items/2cf829172087d2423f58
https://arxiv.org/pdf/1409.1556.pdf
http://aidiary.hatenablog.com/entry/20170104/1483535144
https://www.kunihikokaneko.com/dblab/keras/snowmasaya.html
railsで投稿の編集、削除機能

# 編集機能の流れ

* editページへ飛ばす
* editページでもともとの値をデフォルトで出す
* updateメソッドで変更

## form

### form_tagで書く場合

```ruby:edit.html.erb
<%= form_tag("/posts/#{@post.id}/update") do %>
 <form>
  <div class="form-group">
   <label for="exampleInputEmail1">編集する</label>
   <textarea name="title" class="form-control"><%= @post.title %></textarea>
  </div><!--form-group-->
  <button type="submit" class="btn btn-primary">保存</button>
<% end %>
```

### form_withで書く場合

```ruby:edit.html.erb
<%= form_with model: @user do |form| %>
  <%= form.text_area :user_name, id: "user_name" %>
  <%= form.submit "更新する" %>
<% end %>
```

```ruby:routes.rb
post "posts/:id/update" => "posts#update"
```

```ruby:post_controller.erb
  def edit
    @post = Post.find_by(id: params[:id])
  end
  def update
    @post = Post.find_by(id: params[:id])
    @post.update(title: params[:title])
    redirect_to("/")
  end
```

form_withでmodelで書いた場合はpostの中にネストした形でparamsがくるのでparams[:post][:title]などになる点に注意

# 削除機能の流れ

* destroycontrollerへrouteを飛ばす
* controllerでdestroy

```ruby:show.html.erb
     <%= link_to("/posts/#{@post.id}/destroy",{method:"post"}) do %>
     <button type="button" class="btn btn-outline-primary">
       <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> 削除
     </button>
     <% end %>
```

```ruby:routes.rb
post "posts/:id/destroy" => "posts#destroy"
```

```ruby:post_controller.erb
  def destroy
    @post = Post.find_by(id: params[:id])
    @post.destroy
    redirect_to("/")
  end
```

## よくある間違え

destroyしたあとはそのページは消えているのでredirect_to("/")で
VirtualBox内のUbuntuにホストのMacからSSH

VirtualBox内のUbuntuにホストのMacからSSHするのに時間かかってしまったので、備忘録として。

#環境
ホスト：macOS High Sierra 10.13.4
ゲスト：Ubuntu 16.04.4 LTS

#やったこと
①ホスト側で準備

```shell
VBoxManage modifyvm "VM name" --natpf1 "guestssh,tcp,,2222,,22"
```

VirtualBoxのマニュアルそのままです。


- VM name：VirtualBox内のゲストOSの名前（自分で設定するやつ）
- "guests~~"：ネットワークアダプター1にデフォルト設定されているNATのポートフォワーディング設定。名前、プロトコル、ホストIP、ホストポート、ゲストIP、ゲストポートと思われる。

②SSHしてみる

```shell
ssh -p 2222 [Ubuntuのユーザー名]@localhost
```

ここに時間かかりました。
①の設定により、ホストの2222番ポートへのアクセスはゲストOSの22番ポートへのアクセスになるみたいです。
IPアドレス指定して云々は要らないみたいですね。

##補足
NATって何？

ホストとゲストの間にいる、ネットワークの調整さん的存在？だと思ってます。
VirtualBoxのマニュアルを読むと、NATさんにより、ホストや外部のネットワークからはゲストのネットワークには到達できないみたいです。そもそも認知もできないらしい。
ためにしpingコマンドを打ってみると、ゲストからホストのIPには通りますが、ホストからゲストのIPには通りません。へぇ〜。
ゲストからgoogle先生にもping通ります。

なのでポートフォワーディング設定しないといけないんですね。へぇ〜。

以下雑な絵。

![vmnetwork.gif](https://qiita-image-store.s3.amazonaws.com/0/240470/348dba36-e321-37e2-9ef8-864fdac2f8f0.gif)
PHPで処理時間計測してみた

#PHPで処理速度を計算するには
「処理速度を計測したいコード」を下記のコードで挟んであげる。
※ `microtime()`の引数にはtrueを入れてあげないと秒にならない。

```php
$st = microtime(true);
  // 処理
$now = microtime(true);
echo '○○の処理時間:'.($now - $st)."秒<br>\n";
```

###複数処理の場合

```php
$st_a = microtime(true);
  // 処理
  $st_b = microtime(true);
  // 処理b
  $end_b = microtime(true);
$end_a = microtime(true);

echo '処理aの処理時間:'.($end_a - $st_a)."秒<br>\n";
echo '処理bの処理時間:'.($end_b - $st_b)."秒<br>\n";
```
初心者向け言語とフレームワークとスクールの矛盾印象、色々雑感。

近年、未経験者を対象にしたプログラミングスクールが増えている。現に私も通っていた。

学び始めたのは30代前半。これはかなり遅いらしいが、人生100年と考えるとあと70年近くは付き合える。いいじゃないか。ちなみに職場でプログラミングを使う機会は一切ないので、いい加減フラストレーションが溜まっている。

ちなみにプログラミングスクールをネット検索すると、中には非エンジニアがフリーランスエンジニアを推奨してスクールの紹介をして（結果広告収入を得て）いるサイトもあるので、用心を。

Twitter見ていると結構リアルな情報がリアルタイムで手に入るのでオススメです。

しかし、今回語りたいのはスクールの是非ではない。自分自身プログラミングの入り口がスクールだったため、それなりに内部（？）事情云々は絡めていくが。

今回は、自分が学んできた言語の印象やフレームワークについて、思うがままに書き綴ってみた。玄人プログラマーからみれば知識が怪しい部分も多いと思うが、そこは先達者の余裕と寛大な心をもってお読みいただければ嬉しく思う。

# Ruby
スクールが大好きなRuby。しかし、スクールで学ぶのはRuby on Rails。Rubyのフレームワークである。

``rails new``だけで何だかよくわからないファイルがたくさんできる。そして使用するのは一部分だけ。

**「何だかよくわからないものを、言われるがままに作り変えたらそれらしいものができた。」スクールに通った率直な感想はそれです。**

自分にも受け身な部分が多かったと反省しているが、如何せんプログラムの内部事情がわかりづらい。**それでも形としては成果物ができるので、初心者が誤った達成感で「できたふり」をしてしまう。**初心者がフレームワークから学ぶ一番の弊害は、それだ。

実際の現場では効率化・合理化が重視され、プログラムを全て根幹から作る必要はないだろう。そのためのフレームワークなのだから。しかし、これは経験者だからこそ許されること。フレームワークだけに甘えてしまうと、初心者では予想外の事態に対応できないだろう。

私はRuby on Railsを学んで、**「どこで何が影響しあって、何がプログラムを動かしているのか」**を知りたくなった。それが後の勉強のきっかけになっている。

それにしてもRubyを使用している企業は少ないな。その割にスクールにおける採用率が高い言語である。これについては、いつか別記事にしたい。

# PHP
PHPについては100%独学だ。本とGoogle先生ありがとう。ネットでは「PHPはプログラミング言語なのか？」という論議がなされている・・・今回それは置いておく。

私は最初MAMPを使って環境構築し、簡単なお問い合わせフォームを作った。当時は良い本に出会えず、教えてくれる人もいなかったため随分苦労した。しかし、そこで使用したMySQLのおかげで、SQL文やデータベースとの連携について少しは理解することができた。

Ruby on Railsを学んだ後のハナシなので、基礎部分についてはあまり苦労したかったな。

最近はHomebrewを使ってCakePHPの環境構築をしてみたり。これは別記事をお読みいただければ幸いである。

LaravelはRuby on Railsと似ているらしい・・・こちらも使ってみたい。

# Java
「Javaから始めた方がいいよよ！」
「JavaからPHPは簡単だけど、その逆は大変だよ！」

よく言われますが、Javaから始めて挫折した人は何人いるのでしょうか？何も知らない初心者が、Javaから始めたばっかりにプログラミングそのものを嫌いになってしまった・・・そんな悲劇もあったりなかったり。

こう言われる理由には「オブジェクト志向の仕組み」があるそうだ。オブジェクト志向については自分も理解が半端であるため、その言葉の重みがそれ程わからない・・・

私がJaveの基礎本を読んだのは最近だ。（一回通読しただけ；）さわりの部分しか学んでいないが、例の「オブジェクト志向」についてJavaがどういう仕組みで動いているのか気になったから。

私の場合、選んだ本が良かった。（下記で紹介している。）しかし読んでみると、「これって初心者でもいけるんじゃね？」という印象だった。ただ、読んだタイミングはRuby on Railsを触りPHPで基礎を学んでから。この感覚、全くの初心者には当てはまるか、それはわからない。

良い本や指導者がいれば、もしくはハードルが高いほど燃える方がいれば、初心者がチャレンジするのも良いと思う。

# JavaScript
決してJavaの類似品などではない。全くの別物です。

**個人的に、初心者に一番オススメできる言語だ。**理由は、環境構築の必要がないから。Google ChromeやSafariなど、普段ネットの閲覧で使用してるブラウザ上で簡単に動作確認ができるから、とにかく手軽だ。

そして、どこで何が動いているかわかりやすいから。超ざっくり説明すると、各ファイル・言語の連携はこんな感じ。

## HTML
表示の骨組み（テキスト入力欄、ボタンなど）
``<script src="JavaScriptのファイル名"></script>``の一文でJavaScriptを呼び出せる

## CSS
表示のデザイン部分（文字色や背景色など）

## JavaScript
条件やユーザーの動作によってHTMLやCSSのデザインを変更する。（クリックしたらテキスト入力欄を表示させるなど）

**フォルダの階層も必要ファイルも少ないため、全体像が見やすい。さらに手軽に動かせるため、小さいけれど確実な達成感が味わいやすい。**

プログラミングに限らず、初心者にとってこれがどれほど重要なことか。それを味あわせてくれる言語だ。

# オススメ本
オマケで私が特にお世話になった本を紹介しておく。インプレス率高し。

- いちばんやさしいPHPの教本
- 基礎からのMySQL
- スッキリわかるJava入門
- いちばんやさしいJavaScriptの教本

ちなみにRubyの基礎については、プログラミング学習サイト「Progate」で補完していた。ある程度の範囲なら無料で使用可能だ。同様に「ドッドインストール」もオススメできる。

さらにスクールに通っていれば、カリキュラムも利用できるだろう。真っ当なスクールであれば、かなりの頻度でカリキュラムの更新がされている&卒業生にも無料公開している。逆に、それらを行なっていないスクールは避けた方が良い。

私の通っていたスクールも、アルゴリズムやRubyの基礎部分が充実しカリキュラムのボリュームが通学開始当時の倍になっていた。卒業生として、こちらも利用させてもらおう。

# まとめ
スクール語りをするつもりはあまりなかったが、意外と多くなってしまった・・・

最後に初心者向けの言語について個人的な基準をまとめてみる。

- 自分が楽しめるか（これ最重要！）
- 転職を考えている場合は、進みたい業界で需要のある言語かどうか
- 作りたいアプリがある場合、それに適した言語かどうか
- 自分は言語が難しいほど燃えるのか、初めはラクに始めたいのか
- 動くものを早く作りたいのか、その根幹部分を探りたいのか

まあ、結局は継続しなければ成果は出ない。
どの言語を選んだとしても、日々精進である。
[Serverless Framework] Missing required key 'Bucket' in params が出たときの対処の１つ

#はじめに
Serverless Frameworkを使ってデプロイをした時に出たメッセージで少し解決に時間がかかったのでログの残しします。

#環境
* VirtualBox
* Ubuntu
* Serverless Framework 1.26.1
* Python
* AWS

#ログ
`sls deploy` を実行したときに出力したログはこちら

```
user@ubuntu:~/serverlessframework$ sls deploy
Serverless: Installing requirements of requirements.txt in .serverless...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Injecting required Python packages to package...
  Serverless Error ---------------------------------------
  Missing required key 'Bucket' in params
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
  Your Environment Information -----------------------------
     OS:                     linux
     Node Version:           9.5.0
     Serverless Version:     1.26.1
```

#事前情報
serverless.ymlの `service` を変えてデプロイをした

#対処
文献を色々漁っていたときに書かれてた内容としては、デプロイ時に作成されるS3バケットの作成に失敗している等であったため、
元々のS3バケットを削除して再実行したが、それでも同じメッセージが表示されていた。
尚、実行しているユーザのIAMポリシーはこちらであったため、権限周りは問題ないと判断。

```
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ]
        },
```

`Missing required key 'Bucket' in params` が出力されたときは何度か `sls deploy` や `sls remove` を実行していたのですが、
その前に、 `An error occurred: ServerlessDeploymentBucket - API: s3:CreateBucket Access Denied.` が出力されていたので、調べてみると `CloudFormation` というキーワードが出てきたので、スタックを消してから再実行すると正常にデプロイされた。

#その他
`Missing required key 'Bucket' in params` のメッセージで調べてたときに、S3バケットの上限(100)に達したときも同じメッセージがでるようなので、その辺りも疑って確認してみましたが、全然余裕がある状態でした。

#最後に
なぜこのようなことになったかまでは調べてないですが、まずは以下のことをやってみるといいかもです。

* Serverless Frameworkに渡すIAMポリシーのS3への権限周り
* S３バケットの上限(100)に達していないか
* CloudFormationのスタックを削除

新しい情報を入手したら更新します。
Solidityのダイヤモンド継承の解決

## はじめに

Solidityは多重継承がサポートされています。当然、ダイヤモンド継承問題も発生します。今まではC#をはじめとした単一継承の言語しか扱ってこなかったので、備忘録がてら多重継承した際の動作をメモしておきます。なお、本記事はethereumやsolidity、継承の仕組みについては知っていることを前提にしているので、関連事項の説明は割愛します。

## 多重継承の解決

```javascript:Sample1.sol
pragma solidity ^0.4.11;

contract Parent {
    event Log(string);
    
    function foo() public returns (string) {
        emit Log("Parent");
    }
}

contract Child1 is Parent {
    function foo() public returns (string) {
        emit Log("Child1");
        Parent.foo();
    }
}

contract Child2 is Parent {
    function foo() public returns (string) {
        emit Log("Child2");
        Parent.foo();
    }
}

contract GrandSon is Child1, Child2 {}
```

Solidityは、`is`キーワードを使用して継承を行います。上記のサンプルコードでは、`Parent`コントラクトを基底として、`Child1`と`Child2`の2つの派生コントラクトを作成しています。さらに、その2つを多重継承した`GrandSon`コントラクトがあります。注目していただきたいには、`Parent`で定義されている**`foo`メソッドは`Child1`と`Child2`の両方でオーバーライドされている**点です。

この状態で`GrandSon`の`foo`メソッドを呼び出すと、実行されるのは`Child2`と`Parent`の`foo`メソッドだけです。つまり、**`child1`の`foo`メソッドは実行されません**。これは、`GrandSon`が基本的には`Child1`を知らないからです。`GrandSon`からChild1`と`Child2`両方の`foo`メソッドを呼び出すためには、以下のように書き換えます。


```javascript:Sample2.sol
pragma solidity ^0.4.11;

contract Parent {
    event Log(string);
    
    function foo() public returns (string) {
        emit Log("Parent");
    }
}

contract Child1 is Parent {
    function foo() public returns (string) {
        emit Log("Child1");
        super.foo(); // superキーワード
    }
}

contract Child2 is Parent {
    function foo() public returns (string) {
        emit Log("Child2");
        super.foo(); // superキーワード
    }
}

contract GrandSon is Child1, Child2 {}
```

先ほどのコードと異なり、`Child1`と`Child2`内で`Parent`の`foo`メソッドの呼び出しに`super`キーワードが使っています。`super`キーワードは、基底クラスを呼び出すためのキーワードです。それだけでなく、**`GrandSon`コントラクトが継承している次の基底コントラクトも探索します**。つまり、`Child1`の`foo`メソッドも実行されます。`GrandSon`の`foo`メソッドを呼び出すと、最終的には`Child1`と`Child2`、`Parent`の`foo`メソッドが呼び出されます。

### まとめ
Solidityでダイヤモンド継承を行うと、最後に継承したコントラクトだけを辿って実行します。すべての継承ルートを辿りたい場合には、`super`キーワードを使って基底クラスのメソッドを呼び出す必要があります。
AWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法とノウハウ　第一回

# 概要

AWS 認定ソリューションアーキテクト – アソシエイト資格の勉強法や概略の記事で投稿したので、今回は合格の感覚を忘れないうちに勉強して学んだ知識／ノウハウについて書いていこうと思います。
これから資格試験を受ける方の参考に少しでもなれればと思います。

勉強法や概略は以下を参照

　[AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法](https://qiita.com/fkooo/items/e5284a4ed3c3466ffd41 "AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法")

## 試験勉強を始めてまずつまずくところ

上の記事でも書きましたが、AWSって何？という素人が突然思い立って試験勉強を始めたので勉強しようとしてすぐにつまずきます。
何につまずくのか、そう、AWSのサービスの多さです。。。
Amazon S3が2006年3月14日にリリースされてから10年。革新的に進化してきたAWSのサービス数はおよそ100。
これらを全部覚えることができるのか？勉強する度に初めて聞くサービス名が出てきて、よく3文字で記載される略称にも大混乱です。勉強を始めて一週間これが最初のつまずきできた。
本当に合格できるのか？勉強法はこれであっているのか？不安になる日々でした。

モチベーションが下がりつつ気晴らししつつ勉強を続けていると、やっとこのサービスは前にも出てきたなと思うことが多くってきました。
この時点で覚えたサービスは約20程度。やっと100のサービス全て覚える必要がないことに気が付きます。

そう、サービスごと

* サービス詳細の理解が必要
* サービス概要、特徴的機能、ユースケースの知識が必要
* サービスの概略だけ押さえる

くらいに分類できることに気が付きます。
そしてその内、上の２つに分類されるサービスの理解に時間をかけて勉強しておくと試験と戦えます。
具体的に私が試験を受けてみてそれぞれに分類したサービスは次の通りです。

## サービス詳細の理解が必要

[前記事](https://qiita.com/fkooo/items/e5284a4ed3c3466ffd41 "AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法")の各種書籍／資料を参照したり、実際に自分でサービスを使ったりして、詳細を理解する必要があるサービスは以下くらいが該当しそうです。

* EC2
* S3
* RDS
* DynamoDB
* VPC
* CloudFront
* Route 53
* CloudFormation
* IAM

## サービス概要、特徴的機能、ユースケースの知識が必要

ここに分類されるのは、以下のサービスです。

* Lambda
* Glacier
* ElastiCache
* Amazon Redshift
* Snowball
* CloudWatch
* CloudTrail
* Config
* EMR
* Kinesis
* Cognito
* SNS
* SQS
* SWF



## サービスの概略だけ押さえる

最後に概略は押さえたいサービスは以下の通りです。

* Elastic Beanstalk
* Storage Gateway
* Database Migration Service
* Server Migration Service
* API Gateway
* Direct Connect
* CodeCommit
* CodeDeploy
* CodePipeline
* OpsWorks
* Trusted Advisor
* Inspector
* Device Farm
* WorkSpaces

## まとめ

とりあえず第一回目としてサービスごとの重要度／時間をかけて勉強すべきサービスをまとめました。
私の独断なのでここで登場しなかったサービスは全く勉強する必要がないわけではないと思いますが、これらの勉強で8割の正解率で合格できたのは確かです。

分類や記載しなかったサービスについても今後まとめていく上で修正する可能性があるため、随時更新の記事としつつ、第二回は[サービス詳細の理解が必要]に分類したサービスを中心に、試験対策問題集みたいな形を目指してまとめていこうと思います。

### 【随時更新】勉強法と試験ノウハウ　

[試験対策／勉強法概略](https://qiita.com/fkooo/items/e5284a4ed3c3466ffd41 "AWS初心者がAWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法")：試験対策／勉強法の概略や受けてみてのポイントを記載

[第一回]：試験対策重要サービスを分類

[第二回（前半）](https://qiita.com/fkooo/items/2a403cba7ce55afbdd0f "AWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法とノウハウ　第二回（前半）")：重要サービスの勉強ポイント（前半）

[第二回（後半）](https://qiita.com/items/2acd45ee6a87a4f267f4 "AWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法とノウハウ　第二回（後半）")：重要サービスの勉強ポイント（後半）

[第三回](https://qiita.com/fkooo/items/0f317e676a7022b76837 "AWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法とノウハウ　第三回")：主要サービスの勉強ポイント

[第四回](https://qiita.com/fkooo/items/5540ad9efadcb218c694 "AWS 認定ソリューションアーキテクト – アソシエイト資格試験に合格した時の勉強法とノウハウ　第四回")：特徴的サービスの勉強ポイント

[まとめ回](https://qiita.com/fkooo/items/c578b6c23215685252e8 "まとめ回")：合格対策 AWS認定ソリューションアーキテクト - アソシエイト資格の知識のまとめ
正規化された数字(0 ~ 1)を -1 ~ 1に変換する

色々な値を正規化することがあります。
正規化した値をケースによっては -1 ~ 1にしたいことがあるんですが
その度にすぐ出てこず忘れてしまうので備忘録として残しておきます。

# 式
```javascript
var val = (normalize - 0.5) * 2;
```

# 例
```javascript
var normalize = 0.4; //0 ~ 1
var val = (normalize - 0.5) * 2; // -1 ~ 1
consoloe.log(val); // -0.2
```
Emacs: lpr-buffer で文字化けを回避する

Windows の Emacs から [ak2pr.exe](https://ja.osdn.net/users/tarancho/pf/ak2pr/wiki/FrontPage) を使って `lpr-buffer` でテキストをプリントアウトするとき、文字コードが `sjis` でないと文字化けしてしまうので、プリンタ出力に送り出すときに `sjis` 化するためのアドバイスです。
ファイル自体のコードはそのままで変更されません。

はじめのうちはその都度手動でコードを変換してプリントしていたのですが `(C-x RET f)` 、ときどきそれをし忘れてバケバケになり紙を無駄にすることがあり作ったものです。
ちなみにこの元になったものがおそらくはじめて書いたまともな Emacs lisp です。

lpr-buffer, lpr-region, print-buffer, print-region に作用します。

# ダウンロードとインストール

[ここからダウンロード](https://gist.github.com/s-fubuki/f85a93da3e13bf97703dbb29dbcd8cee)して、  `load-path` の通ったディレクトリに置き `init.el` に以下の行を追加してください。

```emacs-lisp:sample.el
(require 'lpr-buffer-wrap)
```

# y-or-n-p
元々 `lpr-buffer` は起動時に問い合わせが入らなかったのですが、現在は問い合わせが入るようになり `M-x lpr-buffer` として起動するときは鬱陶しいので、そのときは問合せが入らないようにしてあります。

キーバインドしてそこから起動した場合は問い合わせが入ります。

# lpr-region
部分印刷したいのに `M-x lpr-region` とせず指癖で `M-x lpr-buffer` として失敗することがある為、それを自動で回避するため、リージョンがある場合 `lpr-buffer` で起動しても `lpr-region` になるようになっています。

# dired `P`
dired から `P` でもプリントできますが、そちらはマークファイルを外部コマンドに丸投げしていてこのパッチの効力が無いので、`lpr-buffer` で出力する関数で置き換えています。

# オプション変数
prefix 付で起動すると `lpr-switches` に `lpr-switches-add` を追加して起動します。
自分は以下のように設定して C-u 起動時は文字が少し小さくなるようにしています。

```emacs-lisp:sample.el
(setq lpr-command         "c:/emacs-25.1/bin/ak2pr/bin/ak2pr.exe"
      lpr-add-switches     t
      lpr-command-switches nil)

(setq lpr-switches     '("-op" "-u1" "-sA4" "-bl")
      lpr-switches-add '("-f9")) 
```

もちろん dired から `P` で印字するときも `C-u P` は有効です。

# print-buffer について
`lpr-buffer` の亜種のコマンドにヘッダを追加する `print-buffer` がありますが、Windows, ak2pr そして自分のプリンタとの組み合わせのときはその効果が無効なようで `lpr-buffer` と同じ出力になります。

が、念のためこちらも `lpr-buffer` 同様の効力があるように、`lpr-buffer` `(print-buffer)` よりも下位の印刷ルーチンを乗っ取っているので、好みの方をお使いください。

# 動作確認バージョン
> GNU Emacs 25.3.1 (i686-w64-mingw32)
>  of 2017-09-18

# Emacs 26.1 への対応修正 (Sat Jun 23 2018)

もっと良い方法があるのかもしれませんが、`this-command-keys-vector` の返り値でキーバインドから実行されたものかどうか判別していて、 `26.1` でその値が変わっていてうまく判別できなくなっていたので修正しました。
変更は関数 `y-or-n-p-lpr` のみです。

[ 26.1 対応版 lpr-buffer-wrap.el](https://gist.github.com/s-fubuki/f85a93da3e13bf97703dbb29dbcd8cee)

> (emacs-version)
> "GNU Emacs 26.1 (build 1, i686-w64-mingw32) of 2018-05-31"
【花粉症辛い】避粉地ワーク始めませんか？【でも働きたい】

#春が来た
みなさん　花粉で苦しんでませんか？
私はスギ花粉　Level7の能力者なので今年は3月の中旬から　鼻のキーゼルバッハ部が損傷し
鼻血まじりの鼻水と
喉の不快感、熱　そして
アレルギー用目薬による眼圧上昇から　薬物性緑内障であやうく視神経が死ぬ所でした

ので、避暑地ならぬ避扮地　台湾に1か月ほど逃げています
台湾は安価で行け、時差も1時間、ネット環境もよく　スギが生えてないので、おすすめです

また、現在花粉症の症状がない人も、花粉を吸い続けると発症するという可能性もあるため
予防のために　なるべく避けたほうがいいですね


#花粉のない場所
世界中に花粉はあるので、全部を避けるには南極とか　そういう所しかないかもしれないが
日本人が困っている代表的なものは
スギ、ヒノキ、ブタクサ、イネ　です

#前提
私は基本　バックパッカーですから　その前提です
お金かけられる人は　いいチケット買っていい宿泊まってください

チケットは基本LCC等のカクヤスチケット
預入荷物は基本的に行わないので、手荷物7キロに収める必要がある（PCをふくめ！）
宿は安く AirBnBなりドミトリを使う
仕事がメインなので、


また　このへんの　技術者がLCCでバックパッカーするためのノウハウをまとめようとおもう


#考察項目
花粉が無い以外にも仕事をする上では色々な条件が必要です

- 費用
費用は抑えられた方がいいね

- 言葉
多少は・・

- 治安
怪我したりパソコン盗まれたんじゃ話にならない

- 宿の質
仕事をしに来ているので必然的に宿の利用割合が多いはず
コワーキングスペースは　まだ少ないし難易度高め

- ネット
ネット環境悪いと仕事にならない

- ご飯のおいしさ
モチベーション

- 観光
休日ぐらい観光したって・・


#候補地
- 北海道
スギ、ヒノキは少ない。ブタクサはほとんどない
日本としては物価安い。ご飯も個人的に美味しい
日本なので言葉も治安もいい

- 沖縄
スギ、ヒノキは少ない
日本としては物価安い。ご飯は個人的に低評価
日本なので言葉も治安もいい

- 伊豆諸島
花粉症の原因になる植物がいない
日本としては物価安い。ご飯はまーまー
日本なので言葉も治安もいい

- 草津温泉
標高が高く花粉症になる植物が生えない
日本としては物価安い。ご飯はまーまー
日本なので言葉も治安もいい

- 台湾
スギはない。物価安い。旅費も安い。ご飯うまい
治安がいい、ネット環境良い
宿が良い

- 韓国
スギヒノキはない。物価そこそこ安い。旅費も安い。ご飯うまい
治安普通　性犯罪は多い、ネット環境良い
PM2.5と黄砂が酷い

- タイ
スギ、ヒノキない。物価安い。ご飯うまい
治安悪い、ネット環境劣悪

- マレーシア
スギ、ヒノキない。物価安い。ご飯うまい
治安悪い、ネット環境まーまー

- インドネシア
スギ、ヒノキない。物価安い。ご飯うまい
治安悪い、ネット環境最悪


#スギ花粉者におすすめ
個人的なおすすめが　台湾です！
理由として　この時期の台湾の気温はとても過ごしよいし
宿がとても良いので宿での仕事がはかどる
宿ではたいていFreeで台湾ウーロン茶が飲めます
台湾ウーロン茶にはメチル化カテキンというアレルギーをおさえる効果も言われているので
花粉症患者には向いている
言葉は通じないものの　漢字からだいたい推測できるので問題なし。時々日本語喋れる人がいる
ご飯も美味しいし、漢方の国なので　花粉症で疲れた体を癒すにももってこい
国自体が小さく、休日に日帰りで観光が出来る


花粉症回復用の食事もまたまとめる
Microsoft Computer Vision API OCR の使い方 (日本語)

次のページの処理に日本語の処理を加えます。
[Microsoft Computer Vision API OCR の使い方](https://qiita.com/ekzemplaro/items/ee652a63c3890e051582)

参考ページ
[Cognitive Services: OCR機能で印刷物の写真からテキストのデータ化をしてみる](https://azure-recipe.kc-cloud.jp/2017/02/cognitive-services-computer-vision-1/)

次の画像を処理してみます。
![test_ja.png](https://qiita-image-store.s3.amazonaws.com/0/179446/e08ee89e-a463-c6da-2e59-323459fff468.png)

```py:japanese.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
import  requests 
import	json

ocr_url = 'https://westus.api.cognitive.microsoft.com/vision/v1.0/ocr'
headers  = {'Ocp-Apim-Subscription-Key': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}
params   = {'language': 'ja', 'detectOrientation ': 'true'}
data     = {'url': 'https://example.com/test_ja.png'}
response = requests.post(ocr_url, headers=headers, params=params, json=data)
response.raise_for_status()

ocr_data = response.json()

output = ""

for txt_lines in ocr_data['regions']:
    for txt_words in txt_lines['lines']:            
        for txt_word in txt_words['words']:
                output += txt_word['text']
        output += '\n'
    output += '\n'
 
print('language:' + ocr_data['language'] + '\n')
print(output)
```

実行結果

```text
$ ./japanese.py 
language:ja

大きな森のすぐ近くに、木こりが、おかみさんと子供
たちと一緒に住んでいました。男の子はヘンゼルで女
の子はグレ-テルという名前でした。木こりにはほと
```
POJOでのプロパティ読み込み

POJOでプロパティを読みこむ実装のサンプルです。

```java
package sample;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;

public class propertyApp {

	public static void main(String[] args) throws FileNotFoundException, IOException {
		ResourceBundle rb = ResourceBundle.getBundle("sample", Locale.getDefault());
		System.out.println(rb.getString("project_id"))	;
		System.out.println(rb.getString("project_name"));
		
		Properties p = new Properties();
		p.load(new FileInputStream("resources/sample.properties"));
		System.out.println(p.getProperty("project_id"));
		System.out.println(p.getProperty("project_name"));
	}

}
```
20年前の「障害の再発防止策の考え方」は今でも通用する説

---

**障害の再発防止策は、**

**1. メカニズム
2. ツール
3. ルール
4. チェックリスト**

**の順番に検討せよ。**

---

上記は、私が20年前に所属していたパッケージソフト開発会社の標語です。
※転職したので現在の所属会社ではありません。

当時はまだインターネットが今ほど普及しておらず、修正パッチはCD-Rで配布していました。

特に、データ破損系の障害の場合は、

1. お客様にファックスで障害内容を報告し、
2. 緊急ホットラインを開設し、
3. データ異常が見られる場合はバックアップを預かって修正後に返却し、
4. 上記と同時並行でバグの原因調査と修正を行い、
5. パッチをCD-Rに焼いて配布する。

という障害対応を行っていました。
各パッケージの利用社数は数万〜10数万社に上りますので、大変な騒ぎでした。

**そして事後に、障害の再発防止策を検討し報告する義務が課されるわけです。**

## メカニズム

- 仕組みとして、障害原因を封じ込める対策。
- 人手を介在せず、精神論の入る余地もない。つまり人間に依存しない。

例えば「登録ボタンを連打するとデータが重複登録されてしまう」というようなバグであれば、

- 連打されても重複登録が発生しない（あるいは連打できない）ボタン部品を開発する。
- さらに、画面のスーパークラスで、ロード時にボタンを部品に置き換えてしまう。

というような対策です。
※あくまで説明のための例示です。処理速度が〜、設計として〜、等は無視して読んでくださいね。

このカテゴリによる再発防止策が最も強固で、あるべき姿とされていました。

## ツール

以下のような再発防止策がこのカテゴリになります。

- 静的コード解析ツールで、今回と同様の障害を検出する。
    - 当時はOSSというものも普及していなかったので、会社内で静的コード解析ツールを作っており、それに機能追加することが多かったです。
- あるいは、テストツールに今回と同様の障害を検出できるようなスクリプトを組み込んで、リリース前に毎回それを走らせる。

人手を介在させていますので、ヒューマンエラーの可能性が残ってしまいます。
したがって、メカニズムよりも有効性が下がります。

## ルール、チェックリスト

今考えると、チェックリストの方が、ルールよりも実効性がありそうに思えますが…

チェックリストの順位が一番下にきている理由は、

- ルールとは、チーム内のローカルルールではなく、全社統一の開発ルールを意味していたこと。
- 「チェックリストに項目を追加します！」という再発防止策に安易に逃げずに、メカニズム、ツールによる対策を検討するように促されていたこと。

ということだったと記憶しています。

## あとがき

少なくとも、自社プロダクト/サービスのビジネスモデルでは、今でも通用する標語ではないでしょうか。

エンタープライズ系業務システム（受託開発・保守運用）では、コストや体制などのハードルはあるかもしれませんが…

**しかし分野を問わず、メカニズムやツールでバグを抑え込むアイデアを考えて提案すれば、きっと技術者として良い評価に繋がるはず（私はそうあって欲しいです）。**

ちなみに、当時この会社では、再発防止策の評価制度がありました。
創造的かつ効果的な再発防止策を出したチームに対しては、最高で数十万円の報奨金を出していました。

障害は出ないに越したことはないですが、「失敗から学べ」というのも、いつの時代も変わらないセオリーですよね。

なお、本稿の内容は、私の現在の所属企業における立場、戦略、意見を代表するものではありません。
Link > pip > 更新パッケージの確認、インストール > PyMieScattのv1.7.0へのアップデート

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
```

pipでインストールしたPyMieScattの最新版がv1.7.0になっていた。
http://pymiescatt.readthedocs.io/en/latest/index.html#revision-notes-version-1-7-0-5-april-2018

pipではどのようにアップデートをするのか?

### link

- [pipでいれたパッケージを一括アップデート](http://dragstar.hatenablog.com/entry/2016/09/02/113243) by dragstarclassicさん

情報感謝です。

```shell-session
$ sudo pip list --o  # 更新情報の確認
```

```shell-session
$ sudo pip install PyMieScatt -U  # PyMieScattのアップデート
```

Jupyter Notebook上で

```py
import PyMieScatt as PMS
print(PMS.__version__)
```

```txt:run
1.7.0
```
Microsoft Computer Vision API OCR の使い方

次のページを参考にしました。
[Use OCR to detext text in an image](https://docs.microsoft.com/en-us/azure/cognitive-services/computer-vision/quickstarts/python#OCR)

次のドイツ語の画像を処理してみます。
![test_de.png](https://qiita-image-store.s3.amazonaws.com/0/179446/c081f3cf-8900-6d21-596d-49a554d281da.png)

Ocp-Apim-Subscription-Key と url は変更して下さい。

```py:deutsch.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
import  requests 
import	json

ocr_url = 'https://westus.api.cognitive.microsoft.com/vision/v1.0/ocr'
headers  = {'Ocp-Apim-Subscription-Key': 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}
params   = {'language': 'de', 'detectOrientation ': 'true'}
data     = {'url': 'https://example.com/test_de.png'}
response = requests.post(ocr_url, headers=headers, params=params, json=data)
response.raise_for_status()

analysis = response.json()

print(analysis)
```

実行方法
```bash
./deutsh.py > tmp01.json
sed "s/'/\"/g" < tmp01.json > tmp02.json
jq . tmp02.json | grep text
```

実行結果

```text
  "textAngle": 0,
              "text": "Vor"
              "text": "einem"
              "text": "großen"
              "text": "Walde"
              "text": "wohnte"
              "text": "ein"
              "text": "armer"
              "text": "Holzhacker"
              "text": "mit"
              "text": "seiner"
              "text": "Frau"
              "text": "und"
              "text": "seinen"
              "text": "zwei"
              "text": "Kindern;"
              "text": "das"
              "text": "Bübchen"
              "text": "hieß"
              "text": "Hänsel"
              "text": "und"
              "text": "das"
              "text": "Mädchen"
              "text": "Gretel."
```