OmniAICreator/Qiita-1.07M huggingface dataset:
IBOutletで繋いだUIButtonでsetImageが機能しない

# 状況
`@IBOutlet`で`UIButton`を配置してる場合
タイトルテキスト・制約(大きさ・場所)などは決まってる事が多く
**画像だけ変えたい！**ってなる事あると思うのですが
詰まったのでメモ。

`UIButton`の画像を変えたい、指定の画像にしたい時は
**・[jbnkk40/BallFaceCam](https://github.com/jbnkk40/BallFaceCam)**を例にすると
こんな感じで`setImage`を使えばいけるはずなのですがなぜかダメでした

```swift
@IBOutlet weak var albumButton: UIButton!
func showCaptureImageToAlbumButton(capturedImage: UIImage) {
//ここで画像セット //したけどダメ(tintが反映されてしまう)
        albumButton.setImage(capturedImage, for: .normal)
//枠線効果などは普通に反映される
        albumButton.layer.borderWidth = 1
        albumButton.layer.borderColor = UIColor.white.cgColor
        albumButton.layer.cornerRadius = 5
//addTargetも普通にいける
        albumButton.addTarget(self, action: #selector(transToAlbum), for: .touchUpInside)
}
```

# 対策
**xcode側から画像をなんでもいいので設定する**

```swift
//最初出したくない場合はこうやって隠しちゃえばいい
override func viewDidLoad() {
   super.viewDidLoad()
   albumButton.isHidden = true
}
```

なんで画像設定したらうまくいくのかは結局わかりませんでした
xcodeが完璧じゃないのは仕方ないんですが
こういう仕様で悩む回数は減らしたいもんです、、

# 参考
**・[UIButtonをタップして画像を切り替える - Qiita](https://qiita.com/Tanashun/items/670404fc910becb847c3)**
YWGT(ふりかえり手法)

# 結論

- Y:やったこと
- W:わかったこと
- **G:愚痴**
- T:つぎにすること

# はじめに
※KPTとYWTのそれぞれの説明については割愛させて頂きます

ふりかえり手法において有名な「KPT」ですが、私はあまり好きではありません。
理由は、どうしても「P」に偏重して問題ばかりが出てしまい、気持が暗くなって、思い出す事が嫌になってしまうからです。
また「Problem」という単語の特性上、責任追求や個人攻撃に繋がる可能性もあり好きではないのです。

だから経験ふりかえりな「YWT」が好きです。
自分のやった事の話は言いやすいし、それに良かった事も悪かった事も、最終的には「よかった思い出」になっていくので、気持が暗くなることが少ないからです。

しかしそんな「YWT」にも欠点があります。
それは「KPT」の「P」にあたるものが出にくいことです。
「W」のわかったことで挙げればよいですが、それが意外と難しいです。

例えば
「××のやり方をしてはダメだった」
というのはまだいいのですが
「××のやり方をしなかったからダメだった」
というのは(やってないので)なかなか難しいのです。


## 例

- Y:××を導入したyyの開発をやった
- W:どんな時にxxを使えばいいのかがわかった
- **G:zzに使えないのが判明して、あの時はほんと往生して大変だった・・・**
- T:導入する前に検証を十分する

## 説明

W(わかったこと)を次々に挙げていくと、どうしても愚痴が出てきます。
しかし愚痴はYWTでは分類できません。
愚痴は愚痴を呼び多くの発言を生み出しますが、分類できないので記録ができません。
「YWGT」なら愚痴も記録できるので、発言として残ります。
しかも愚痴になる事は、200%問題があった事なので「P」にあたり「T(つぎにすること)」で改善に繋がります。

# おわりに

## 「振り返り」で一番大切なのは多くの発言をする、させること

振り返りにおいて**一番の難しい事**は何でしょうか？

それは**「思い出すこと」**ではないでしょうか。

振り返りの目的は

**「振り返ることで、学びを得たり成長する」**

ことだと考えます。

つまり、できるだけ多く思い出すことができ、発言できれば、それだけ多くの学びが得られ、成長することに繋ります。
気持が暗くなってしまい、思い出す事が嫌になってしまうと、折角の経験した学びの機会が減ってしまいます。
だから、**どのように気分を上げて思い出させるか**、が重要だと考えます。

感情に紐付く記憶は、同じ感情になると引き出される事がよくあります。
感情記憶は強いです。

「P」に相当する事の記憶は高い確率で辛かった記憶であり、辛かった記憶は愚痴になります。
愚痴を言う事はストレス発散になり、気持を楽になり、気分を上げることになります。
また全然知らない人の事ではなく、同じプロジェクトを経験した仲間なので、愚痴に同調できることもあり、聞いている人も辛い気持に紐付いた記憶がどんどん出てきます。

そして意外と楽しいです。

よかったらぜひ試してみてください。
お酒飲みながらでもいいと思います。

- 関連

新人との振り返りに合うのはYWT
https://qiita.com/lunar_sword3/items/74c546901102b7757901
【WordPress】ログインできなくなった【Nginx】

以前まではできていたはずなんだけどある日途端にできなくなった。

ログイン画面で、ID、PASSいれてエンターしても、またログイン画面に戻されてしまう。
ググってもこの状況の解決方法がなかったため念の為書いておきます。

## 対処方法

`nginx.conf`の.phpへのアクセスを司るディレクティブに、

```
fastcgi_param  HTTPS on;
```

を追加したらいけるようになった。

ただ、別のサーバではこの設定を入れずとも問題なくログインできているので、
きっとどこか根本的なところを治す方法もあるような気がするけどいったんはこれで。
WEBページ先のコンテンツを開いた状態でアクセスする方法

GoogleスプレットシートにてWEBスクレイピングよりデータを取得しようしているのですがリンク先コンテンツに10件以上の時、以降を【次を読み込み】ボタンを押して読み込む様な場合　URLパラメータにて開いた状態でアクセスする事は出来ないでしょうか？

参考URL→https://p-ken.jp/p-apis/bonus/lot?model_nm=%BA%DE%B0%BA%DE%B0%BC%DE%AC%B8%DE%D7%B0KK&cost=21.2766&ps_div=2&mode=

スプレット関数は IMPORTXMLにてデータをtable指定して取得する感じです。既に10件までなら取得は出来ています。
正規表現を使って大量のログの検索をしたので残しておく

#参考サイト

https://murashun.jp/blog/20190215-01.html

#なぜ正規表現を使ったか

仕事で10万件近くのログの終了時間を取らなければいけないケースがあり、
Grep検索で正規表現を使用して解析を行いました。

#今回探したログの内容

ざっくりですが下記のような感じです。

[2019/08/25 12:58:48] <プロジェクト名> MSG0002_処理が完了しました。

#探した条件

今回の条件としては
**終了時刻が午前2時〜4時のもの
かつ　今年のログ
かつ　全てのプロジェクト**

です。

#どんな正規表現を使ったか

¥[2019/0[0-9]/[0-3][0-9] 0[2-4]:[0-9][0-9]:[0-9][0-9] ¥<プロジェクト_[0-9][0-9][0-9]¥> MSG0002_処理が完了しました。

※プロジェクト名はフェイクです。

こんな感じで検索してみたところできました。

また、開始時間も調べないとという追加がきたため、

¥[2019/0[0-9]/[0-3][0-9] 0[2-4]:[0-9][0-9]:[0-9][0-9] ¥<プロジェクト_[0-9][0-9][0-9]¥> MSG0002_処理が完了しました。|¥[2019/0[0-9]/[0-3][0-9] 0[2-4]:[0-9][0-9]:[0-9][0-9] ¥<プロジェクト_[0-9][0-9][0-9]¥> MSG0001_処理を開始しました。

てな具合にすればうまく取れました。

もっとうまい方法があるんでしょうが今の所これが僕の限界かなって感じです。

突き詰めれば面白い正規表現。
勉強していきます。

#profile

生まれも育ちも大阪の浪速中の浪速っ子が30才未経験からITエンジニアとして生きるブログもやってます。
よかったらみてください:muscle_tone2:

<a href="https://blogmura.com/profiles/11016817?p_cid=11016817"><img src="https://blogparts.blogmura.com/parts_image/user/pv11016817.gif" alt="PVアクセスランキング にほんブログ村" /></a>
Digest Authorization with Nginx

## Nginx で Digest 認証

### Nginx で Digest 認証やろうとしたときのおはなし

- *結論から言うと非サポートです。*

`nginx-1.0.x.tar.gz`をゲットしてmakeしろということです。

[HTTP Digest Authentication support for NGINX.](https://www.nginx.com/resources/wiki/modules/auth_digest/)

Nginx の最新バージョンは v1.17.4 です。

安定性と機能面を v1.0.x に落としてもいいと思えばやってよし。

### Apache で実現したおはなし

最新の v2.4.41 でもできました。
Wordpressでゴミ箱に移動しない、非公開にできないとき

めったに起こらない現象だと思うので、もし同じ条件があれば試してみてください。

## 投稿記事にタイトルが入っていない
投稿記事にタイトルが入っていない場合に、非公開、下書きへの変更。さらにはゴミ箱へ移動さえできませんでした。

## 投稿記事にタイトルを入れる
投稿記事にタイトルを入れると、非公開、下書き。ゴミ箱に移動できるようになります。
ただし、タイトルを入れた後「タイトルなし」にはできなくなります。

---

### その他が原因？
他に原因があるとしたら、

+ プラグイン
+ テーマ
+ パーミッション
+ phpのバージョン

などかなと思います。

+ プラグインを無効にする。
+ テーマを変える。
+ パーミッションを最適化する。
+ phpのバージョンを変える。

など試してみてください。（検索するといろいろ出てきます。）

---

#### まとめ

小さなことですが検索して見つからなかったので、もし困ってたらためしてみてください。
railsでアプリを作るときのメモ2

# rails generate
いろいろ作ってくれる魔法の呪文を唱えます

```
$ rails generate controller home top
```

## ルーティングについて
routes.rbにコードが追加されています。

```ruby:/config/routes.rb
Rails.application.routes.draw do
  get 'home/top' # 追加されている
end
```

これによって ```$ rails s``` をすると
http://localhost:3000/home/top にアクセスできます

## ビューについて
新しくファイルが作成されています。

```html:/app/views/home/top.html.erb
<h1>Home#top</h1>
<p>Find me in app/views/home/top.html.erb</p>
```

先ほどの http://localhost:3000/home/top にアクセスするとこの画面が表示されます。
<img width="820" alt="スクリーンショット 2019-09-26 16.48.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/945b932e-bcee-905b-e37e-ba1ee3debba8.png">

## コントローラについて
新しくファイルが作成されています。

```ruby:/app/controllers/home_controller.rb
class HomeController < ApplicationController
  def top
  end
end
```

## ルーティング編集

```ruby:/config/routes.rb
Rails.application.routes.draw do
  get 'top' => "home#top"  # 編集
end
```

http://localhost:3000/top にアクセスすると、homeコントローラのtopメソッドが呼び出されます。

# 紹介ページを作る
## ルーティング追加

```ruby:/config/routes.rb
Rails.application.routes.draw do
  get 'top' => "home#top"  
  get "about" => "home#about" # 追加
end
```
## コントローラ追加
```ruby:/app/controllers/home_controller.rb
class HomeController < ApplicationController
  def top
  end
  def about
  end
end
```
## ビュー作成
自動生成されないので自分でファイルを新規作成します。

```html:app/views/home/about.html.erb
<div class="about-main">
  <h2>MyFormAppとは</h2>
  <p>
    フォームを新しく作成するアプリケーションです。
  </p>
</div>
```

# 共通コンポート作成
ヘッダーなどの共通部分を作成します。

```html:/app/views/layouts/application.html.erb
<!-- 追加 -->
  <header>
    <div class="header-logo">
      <a href="/top">MyFormApp</a>
    </div>
    <ul class="header-menus">
      <li>
        <a href="/about">MyFormAppとは</a>
      </li>
    </ul>
  </header>
```
トップページ
<img width="1440" alt="スクリーンショット 2019-09-26 18.46.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/6ba2cb0d-45a5-5c2c-6b6b-e91bd953023e.png">
紹介ページ
<img width="1440" alt="スクリーンショット 2019-09-26 18.47.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/5d4ab544-4b09-82a7-e901-23dfa331adce.png">

同じものが表示されています。

# CSS
CSSファイルは自動で作成されています。

```css:/app/assets/stylesheets/home.scss
ul, li {
  list-style-type: none;
}
body {
  background-color: #3ecdc6;
}
.main {
 position: absolute;
 top: 64px;
}
header {
  height: 64px;
  position: absolute;
  width: 100%;
}
.header-logo {
  float: left;
  color: white;
}
//
.header-logo a{
  color: white;
}
//
.header-menus {
  float: right;
}
.header-menus a {
  color: white;
}
```
<img width="1440" alt="スクリーンショット 2019-09-26 19.32.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/74800d41-0d0f-622a-77ab-0115f6f92243.png">

とりあえずここまで
AWS認定 ソリューションアーキテクト プロフェッショナル（SAP-C01）の受験記録

**2019/09/23に試験に合格しました。**
個人的にAWSの試験は、

- 学習範囲が広い
- どのサービスを学習したら、試験ガイドを読んでもよくわからない
- 過去問が公開されていない
- これを読めばいいといったまとまった情報がない

ので、学習しづらく苦手です。

今回なんとか合格できたので、振り返ってみて、自分なりに一番よいと思った方法を記載します。
他の方を記事を見ると、BlackBeltやホワイトペーパーも読むと書いてありますが、本数が多く、読むだけでは頭に入らないので問題を解きながら出てきた内容を覚えていく方法で学習しました。

## 対象者
・ソリューションアーキテクトアソシエイトに合格するレベルであること
　※合格してから長期間経っている人は後述する黒本で復習してください。
・問題を解きながら覚えていくタイプの人
　※ドキュメントを読んで覚えるより、問題を解きながら覚えていく人向けです。


## 方法
### 1. 試験ガイドの確認
まずは試験ガイドを確認します。

https://aws.amazon.com/jp/certification/certified-solutions-architect-professional/

そこに掲載されているホワイトペーパーは一通り読みます。
（最初はざっと読む程度でもいいです。）
紹介されているトレーニングに無料でできるのがあるのでそれもやります。

### 2.黒本で学習

https://aws.koiwaclub.com/

で最上位のダイヤモンドプランに契約すると、
プロフェッショナル向けの問題ができます。
ここで復習もかねて、アソシエイトレベルの問題から解きます。
なぜ、その選択肢が正解で、その他が不正解なのか？解説やBlackbeltなどを調べながら理解していきます。
間違えた問題は答えられるまで何度か繰り返します。
（３〜4周くらいやりました）
黒本の問題は、小問の順番が更新するたびに変わってしまうので、
番号だけでなく、大問の番号と問題の見出し部分をメモしておいて、見直しできるようにしておきます。

### 3.苦手な分野を重点的に学習
黒本を学習して、全般的にわからないサービス等があったら、そのサービスを学習します。
僕の場合は、VPCやネットワーク周りを設定するなどが苦手だったので、
書籍や実際に実行して学習しました。

https://qiita.com/murapon/items/c6194042f49954783081

https://qiita.com/murapon/items/e2b94199556cca4a3934

また、いくつかのサービスのBlackBeltやホワイトペーパーを読みました。
BlackBeltは、

https://www.youtube.com/playlist?list=PLzWGOASvSx6FIwIC2X1nObr1KcMCBBlqY

で動画でも見れます。1.5か1.75倍速で見れば1本30分くらいで見れますし、
資料には書かれていない情報も聞け、頭に入りやすいので時間があれば動画もおすすめです。

- どんなサービス？
- ベストプラクティス
- 実装パターン

などを把握できればいいかと思います。
細かなコマンドや数値、操作手順などは覚えなくても大丈夫かと。

### 4.Udemyで学習

https://www.udemy.com/aws-solutions-architect-professional-practice-exams-2018/

で問題をさらに解きます。よくしているセールで買えば約1500円です。
黒本だけだと、問題数が少ないのでこちらの問題も解きます。
黒本とUdemyで問題の傾向が違うので、黒本を覚えたのに、udemyはまったくできないってなる場合がありますが、
気にせず、解いて覚えてください。
こちらも黒本と同様になぜその選択肢かを理解した上で正解になるように何度も繰り返します。
（３〜4周くらいやって9割以上正解できるようになりました）

### 5. ECS、CloudFormationを学習
2.と同様に、udemyを学習してわからなかったサービスを重点的に学習します。
さらに、ECS、CloudFormationに関してBlackBeltやホワイトペーパーなどで学習してください。
黒本やUdemyに記載が少なかったのですが、本試験ではよく問われました。
ECSは、Fargateとの組み合わせや使い方などを、CloudFormationは記述方法やパラメータの扱いなどを見ておくとよいかと思います。

## 他にやったこと

http://jayendrapatil.com/aws-certified-solution-architect-professional-exam-learning-path/

に記載されているリンク先ページの例問を解きました。（全部で700問近くあります。）
最初にこちらをやったのですが、アソシエイトレベルの問題が多く、
後で解いた黒本や、Udemyとかぶる問題もいくつかありました。
無料ですし、これと公式ドキュメントの読み込みで合格した方もいます。
ただ、黒本、Udemyをやるならこちらは不要かなと思います。

## 試験振り返り
アソシエイト試験に合格してから3年以上経っていたので、その復習も含めて、大体100時間くらいは勉強しました。
黒本で学習した問題が何問か本試験でも出てたので、
黒本やUdemyの問題は完全にできるようにしておいた方がいいと思いました。

## 参考にした記事

https://qiita.com/tsumita7/items/2bc8ef52cc0cfbad8b5c

https://qiita.com/ro9lo/items/238c6f04ef9fc07969f2

https://qiita.com/ro9lo/items/fd6c3482cd73dd3a1d26
JavaScript 関数定義&for文

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

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください！！

今回はJavaScriptの文法事項をまとめてみました！


#関数定義
まずは関数の定義から見ていきます！

```Javascript
const introduce = function() {
   console.log('こんにちは');
   console.log('これからよろしくお願いします');
};
```
この関数は簡単な挨拶をする機能を持っています。
console.log()はC言語で言うとprintf()でPythonで言うとprint()に相当する関数です。
JavaScriptは大きくES5とES6の２種類があり、最近開発されたES6では同じ機能でも下のように記述することが推奨されています。

```Javascript
const introduce = ()=> {
   console.log('こんにちは');
   console.log('これからよろしくお願いします');
};
```

ここで()=>はアロー関数と呼ばれています。

#forループ
ここでは実際に使われる関数内のforループを紹介していきます。

```Javascript
const returnFactorial = (n)=> {
   let result=1;
   for(let i=1; i<=n; i++) {
      result *= i;
   }
   return result;
};
```

returnFactorial関数はいわゆる階乗を計算する関数です。
JavaScriptのforループはC言語のような使い方で使用します。
for(初期化; ループ条件; インクリメント)
C言語を触ったことのある人からしたら、とてもわかりやすいですね！！


#まとめ
今回はJavaScriptの関数定義とfor文に焦点を当ててまとめてみました。

先ほどfor文はfor(初期化; ループ条件; インクリメント)のような使い方をすると説明しましたが、実際にはfor(let v of s)のようなPythonチックな使用法もあるみたいです。

新しい文法に出会ったら、その都度ネットで調べて習得していこうと思います！

最後までご覧いたたぎありがとうございました！！
Polyak Averaging

式だけメモ。これの読み方誰か教えてください。。。

# Polyak Averaging
Polyak Averagingは、最適化アルゴリズム中のパラメーター空間内のいくつかのポイントの平均化です。そのため、最適化中にポイント $\theta_1, \theta_2...$ が得られた場合、Polyak Averagingは次のようになります。凸関数用。

```math
\hat\theta_t = \frac{1}{t}\sum_{i=0}^t\theta_i
```

# Polyak-Ruppert Averaging
$\hat\theta_t$ を加重平均します。非凸関数用。

```math
\hat\theta_t = \alpha\hat\theta_{t-1}+(1-\alpha)\hat\theta_t,\alpha\in[0, 1]
```
</br></br>
後でここに図とか書きます。

- [https://coffee-g9.hatenablog.com/entry/Polyak_averaging](https://coffee-g9.hatenablog.com/entry/Polyak_averaging)
【CodeCommit/Windows】ユーザー名 or パスワードを間違えてgit clone出来なくなった場合の解決方法

git clone時にユーザー名 or パスワードを間違えた後、
The requested URL returned error: 403
が出てクローンできなくなった場合の解決方法です。

##対象
AWS CodeCommit
クライアント：Windows PC

##手順
1. コントロールパネル > ユーザーアカウント > 資格情報マネージャー > Windows資格情報
2. 汎用資格情報から、CodeCommitのものを開き、削除を押下
3. 再度git cloneするとユーザー名とパスワードを求められるので正しい値を入力すればOK

##参考
[Git for Windows: Git for Windows をインストールしましたが、リポジトリへのアクセスが拒否されます (403)](https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/troubleshooting-ch.html#troubleshooting-windowshttps)
GPU無しtensorflow 1.14.0 C++におけるUbuntu18.04上でのソースビルドとCMakeで使えるようにする

#事のきっかっけ
C++でやりたくなった。
(ここに至るまでに、Windowsでのビルドを諦めてしまったのは内緒。)

##前提条件
- OS:Ubuntu 18.04

##事前知識
- .bash_profileに書こうが.bashrcに書こうが特に変わりないので、各自の都合に合わせてください。

##ビルド前の事前準備
- pyenvをインストール。

1. `sudo apt install git`でgitをインストール。
2. `git clone https://github.com/pyenv/pyenv.git ~/.pyenv`でpyenvをインストール。

3.`vim ~/.bash_profile`でエディタを開き、以下の3行を記載し、保存する。

```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

4.`source ~/.bash_profile`を実行し、先程の設定を読み込ませる。

- pythonを入れる前の下準備

1.`sudo apt install zlib1g-dev libssl-dev libbz2-dev libreadline-dev libsqlite3-dev`


- python3.7をインストール

1. `pyenv install 3.7.4`を実行し、Python3.7.4をインストール。
2. `pyenv global 3.7.4`を実行し、デフォルトを3.7.4にする。
3. `python -V`を実行し、上記のバージョンとなっているのかを確認する。


- virtualenvをインストール

1. `pip install virtualenv`で、インストール。

- virtualenvで仮想環境の作成

1. `virtualenv py3.7.4`で、仮想環境を作成。`py3.7.4`の所は、任意で構わないが以後はこの設定でやっていくので、各自で書き換えていただきたい。
2. `source py3.7.4/bin/activate`を実行し、仮想環境を起動させる。

- ビルド用にpipでパッケージインストール

1. 下記のコマンドを1行ずつ実行し、インストールしていく。

```
pip install -U pip six numpy wheel setuptools mock
pip install -U keras_applications==1.0.6 --no-deps
pip install -U keras_preprocessing==1.0.5 --no-deps
```

- Bazel0.24.1のインストール

1.`sudo apt install pig-config zip g++ zliblg-dev unzip`を実行し、前提となるシステムをインストールする。
2.https://github.com/bazelbuild/bazel/releases/tag/0.24.1
にアクセスし、bazel-0.24.1-installer-linux-x86_64.shをダウンロードする。
3.`chmod +x bazel-0.24.1-installer-linux-x86_64.sh`を実行し、シェルスクリプトが動くようにする。
4.`./bazel-0.24.1-installer-linux-x86_64.sh --user`を実行し、bazelをインストール。
5.`vim ~/.bash_profile`を実行し、以下の1行を入力し保存する。

```
export PATH="$PATH:$HOME/bin"
```

6.`source .bash_profile`を実行し、設定を読み込む。

- tensorflowのソースファイルをビルド

1. `git clone https://github.com/tensorflow/tensorflow.git `を実行し、ソースファイルを取り込む。
2. `cd tensorflow`でソースファイルの階層に移動。
3. `git checkout r1.14`を実行し、1.14系のブランチを作る。
4. `./configure`を実行し、質問に答えていく。基本的にYes or No形式の質問は全てNOを選択し、[Default ...]といったYes or Noとは違う形式の質問は、基本的にエンターキーを押す。
5. `bazel build --config opt --config monolithic tensorflow:libtensorflow_cc.so`を入力し、ビルドを実行する。非常に長いので、時間がある時に行うべし。

- 自分の導入したいプロジェクトで使う

1.git cloneした時にできたtensorflowのフォルダをそのまま自分が使用しているプロジェクトフォルダにペーストする。
2.CMakeLists.txtとディレクトリ構造を下記に示す。

ディレクトリ構造

```
Projectファイル(今回は、test)
|-CMakeLists.txt
|-main.cpp
|-tensorflow(git cloneしてできたフォルダそのまま持ってくる)
```

CMakeLists.txt の中身

```
cmake_minimum_required(VERSION 3.14)
project(test)

#---追記---
set(CMAKE_CXX_FLAGS "$(CMAKE_CXX_FLAGS) -g -std=c++11 -W")

#bazel-bin,bazel-genfilesは、シンボリックなので、移行の際は注意
link_directories(./tensorflow/bazel-bin/tensorflow)

include_directories(
    ./tensorflow/
    ./tensorflow/bazel-genfiles
    ./tensorflow/bazel-bin/tensorflow
)
#---追記end---

add_executable(test main.cpp)

#---追記---
target_link_libraries(test tensorflow_cc tensorflow_framework)
#---追記end---
```

以上で、自分はJetbrains社製のCLionでやりましたが、ビルドが無事通りました。

ちなみに、ソースファイルの中身は

```

#include <stdio.h>
#include "tensorflow/tensorflow/c/c_api.h"

int main() {
   printf("Hello from Tensorflow C library version %s\n", TF_Version());
   return 0;
}
```

です。
FBX SDKのPython版とC++版の違い

# FBX SDKのPython版とC++版の違い

こちらの公式ドキュメントを読んでみて、理解した内容をメモとして残します。
[Differences between FBX SDK and Python FBX](https://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_363E55D8_6EDB_40F8_8F58_E42F8D525D3D_htm)


Python版には、C++版の関数のほとんどが含まれていますが、以下が異なるようです。



## C++版のテンプレート関数とテンプレートクラスはPython版にはない

テンプレート関数っていうのはC++の構文で、こんな感じのやつです。

```c++
template<class T> T Add(T a, T b)
{
    return a + b;
}
```

`T` の部分は様々な型を受け入れます。

Pythonにはテンプレート関数という構文はないので、代わりに、型ごとに個別の関数を提供しているようです。



## 配列の出力はC++版ではポインタ、Python版ではリスト

関数が配列のようなデータを出力するケースの場合、以下のような違いがあります。

- C++ ではポインタで出力する
- Python ではリストで出力する

例えば、C++版には `GetPolygonVertices` という関数があります。
（参考: [FbxMesh Class Reference](https://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_mesh_html)）

こんな感じの関数です。（関数の中身は適当）

```c++
int* GetPolygonVertices(){
    int* array = new int[num];
    // 何らかの処理
    return array;
}
```

この関数は、Python版では以下のようになるようです。

```python
def GetPolygonVertices():
    array = []
    # 何らかの処理
    return array
```



## C++版のポインタ渡しはPython版ではタプルになる

複数の値を関数が出力するようなケースの場合、以下のような違いがあります。

- C++ は、ポインタで渡した引数に出力する
- Python は、タプル（複数の戻り値）で出力する

例えば、C++版には `KeyAdd` という関数があります。
（参考: [FbxAnimCurve Class Reference](https://help.autodesk.com/view/FBX/2017/ENU/?guid=__cpp_ref_class_fbx_anim_curve_html)）

こんな感じの関数です。（関数の中身は適当）

```c++
int KeyAdd(KTime pTime, int *pLast){
    // 何らかの処理
    return index;
}
```

この関数の出力は以下の２つあります。

- `index` : 戻り値
- `pLast` : ポインタ渡しの引数

この関数は、Python版では以下のようになるようです。

```python
def KeyAdd(KTime pTime):
    # 何らかの処理
    return index, pLast
```

１つ目の戻り値が `index` で、２つ目の戻り値が `pLast` になりました。



# さいごに
C++とPythonの文法の違いが比較できて面白いですね。
railsのmigrationで主キーの名前と型を変える

```rb
class BackupByMail3 < ActiveRecord::Migration[5.2]
  def change
    create_table "backup_mail", id: false |t|
      t.string "key", limit: 64, primary_key: true
    end
  end
end
```

Googleのせい（自分の検索の仕方が悪いとは絶対言わない）だとは思うがドンピシャなものがなかなか見つからず手間取ったので載せておきます。
eng-practices (How to do a code review) 読む

[Google's Engineering Practices documentation](https://google.github.io/eng-practices/) は読んでいてためになったので気になった部分をメモ。

## The Standard of Code Review
- perfect じゃなくても code health が良くなれば approve
- (perfect を求めない一方で) reviewer は改善点をコメントできるべきで、ただし重要じゃなくて author が無視していいなら nits を付けると良い

### Mentoring
- 知識の共有は code health 向上にも良い
- 一方で教育目的のコメントなら nits を付けるとか、この CL で必ずしも解決しなければならないことではないと伝わるように心掛ける

### Principles
- 意見とか個人の嗜好 < 事実とかデータ
- デザインはスタイルとか個人の嗜好にはならない（むずい）
  - *たぶん、 reviewer と author でデザインの選択で意見が割れる時もあるけど、事実としていずれも等しく有効なものであると示されたなら（reviewer の嗜好とは反しても） author の変更は approve しないといけないという感じか？*

### Resolving Conflicts
- 合意が取れないからといって CL を放置しないように

## What to look for in a code review
### Design
- 一番大事
- 機能追加するに良いタイミングか？

### Functionality
- 並列プログラミングは難しいので注意 （ので使わない理由にもなりえる）

### Complexity
- 読むの難しい、つまり変えるときに bug になりやすい
- over-engineering (必要以上の一般化や今はいらない機能) に注意する

### Tests
- テストは一緒の CL に
- main には入らないからといって complexity を許容しない

### Naming
- 良い名前はそれを表現するのに十分に長くて、読みづらくないように長すぎない（むずい）

### Comments
- コメントというのは普通 explain why するもので explain what してたらそれはコード読んでもわからないということなのでコードの方をシンプルにした方がいいのではないか
- note: ドキュメンテーション != コメント

### Style
- 色々問題引き起こすのでスタイルの変更を別の変更に混ぜないこと

### Documentation
:no_entry_sign:

### Every Line
:no_entry_sign:

### Context
:no_entry_sign:

### Good Things
- コードレビューは間違いに注視しがちなので褒めることも忘れない

### Summary
:no_entry_sign: 

## Navigating a CL in review
### Summrary
:no_entry_sign:

### Step One: Take a broad view of the change
- CL description をまず見て reject するならすぐに返信する
  - 対案を入れる
  - 礼儀正しくする

### Step Two: Examine the main parts of the CL
- 大きすぎたら CL 分けてもらうように頼む
- major なデザインの問題があったらすぐに返信すべき

### Step Three: Look through the rest of the CL in an appropriate sequence
:no_entry_sign: 

## Speed of Code Reviews
### Why Should Code Reviews Be Fast?
- チーム全体のスピードが落ちるから
- 不満が溜まるから
- code health もリファクタとかし辛くなって影響でてくるから

### How Fast Should Code Reviews Be?
- きたらすぐに返事を返す、1 営業日が最大

### Speed vs. Interruption
- 仕事に集中してる時は中断しない
  - 中断すると戻るのに時間がかかるという話
- break したら返信しよう

### Fast Responses
- CL に対して終わりまでが早くなるより個々のレスポンスが早くなる方が重要

### Cross-Time-Zone Reviews
:no_entry_sign: 

### LGTM With Comments
- 時間の節約のためのコメント付き LGTM
  - 適切に対処してくれそうだと確信できていれば
  - minor で必ずしも変更しなくていいなら

### Large CLs
- 時間がない、時間かかるなら分けてもらうよう頼む

### Code Review Improvements Over Time
:no_entry_sign: 

### Emergencies
:no_entry_sign: 

## How to write code review comments
### Summary
:no_entry_sign: 

### Courtesy
- 人に対してではなく、コードに対してコメントするといい

### Explain Why
- 何故コメントしたのかが伝わるように

### Giving Guidance
- 問題を伝えて解決してもらうのか、より直接的な指示を与えるかはバランスをとる
  - 一番の目的は CL をベストにすること
  - 二番目に開発者のスキル向上

### Accepting Explanations
- レビューツール上のコメントだけでは将来の開発者には分からないので、説明を要求されたら普通はもっと分かるようにコードを変更する必要がでてくる

## Handling pushback in code reviews
### Who is right?
- 同意が得られなかったら author が正しいか考える
- それでも正しいと思えなかったら、より説明を加える
  - author からの返信を理解しようとしている姿勢
  - その上で何故変更を求めているかということ

### Upsetting Developers
- ちゃんと丁寧にしてたら大抵は大丈夫なはず

### Cleaning It Up Later
- 後でやるから LGTM くれというのは大抵はやらないことになってしまうから、今すぐやる方がいい

### General Complaints About Strictness
- レビューをきつくすると不満が出るがスピードが早ければ大抵は緩和される

### Resolving Conflicts
:no_entry_sign:
Pythonの内包表記について

#目的
いまだにPythonの内包表記がいまいち理解できていないのでざっくり再確認

#内包表記とは
Pythonにてリストをforを用いて生成する方法
1行で書ける＆早いので便利

#基本の書き方

```Python
array = [x for x in イテラブル]
```

~~xが2回出る
1回目のxはfor内容を受け取る変数のような認識でいいっぽい
2回目のxは通常のforと同じくリストを順繰りに見た値が入る
リストはスライスも可能~~

※コメントにより訂正
forの前には式を指定でき、forによって作られた値をさらに演算してリスト化可能
なので以下のようにすべての値を2倍してリスト化などもできる

```Python
array = [2*x for x in イテラブル]
```

※コメントにより訂正
forで走査するのはリストと言うよりイテラブルなオブジェクト（連続するデータ列）



#条件指定
ifで条件に合致したもののみリストにすることができる。

```Python
array = [x for x in イテラブル if 条件]
```

#実際にやってみる
適当なリストから偶数だけ抜き出してみる
偶数を2倍したものもリスト化してみる

```python
array = [1,3,4,6,7,8,9,0,23]
array2 = [x for x in array if x%2==0]
array3 = [2*x for x in array if x%2==0]
print(array2)
#>>[4, 6, 8, 0]
print(array3)
#>>[8, 12, 16, 0]
```

#参考文献
pythonの内包表記を少し詳しく
https://qiita.com/y__sama/items/a2c458de97c4aa5a98e7
C#で英単語の単数形を複数形にする

### 英単語の単数形を複数形にする

暇だったので、Githubを見ていたら、Rubyでは標準機能で英単語の単数形を複数形にする機能があると知りました。
へ～。
person→peopleとか。
wolf→wolvesとか。
覚えたな～。
などと中学校の英語の授業を思い出して懐かしくなりながら。

さてと。

### Ruby2CSharp
Rubyは読めないのですが、正規表現は100行ほどなので、それならC#に移植しておいたらどうだろう。
ちょうどエクステンションの勉強中でもあるし。

### 移植！
ということで、移植してみました。
Rubyの正規表現では、指定範囲を引用するのに「\」を使うのですが、C#では「$」を使います。
/iの意味がわからなかったのでオミット。
/もなくしちゃいました。いいのかな。ま、いいか。

```C#
using System.Text.RegularExpressions;

public static class StringExtensions
{
	public static string Inflections(this string value)
	{
		var inflect = value;

		inflect = Regex.Replace(inflect, "s$", "s");
		inflect = Regex.Replace(inflect, "^(ax|test)is$", "$1es");
		inflect = Regex.Replace(inflect, "(octop|vir)us$", "$1i");
		inflect = Regex.Replace(inflect, "(octop|vir)i$", "$1i");
		inflect = Regex.Replace(inflect, "(alias|status)$", "$1es");
		inflect = Regex.Replace(inflect, "(bu)s$", "$1ses");
		inflect = Regex.Replace(inflect, "(buffal|tomat)o$", "$1oes");
		inflect = Regex.Replace(inflect, "([ti])um$", "$1a");
		inflect = Regex.Replace(inflect, "([ti])a$", "$1a");
		inflect = Regex.Replace(inflect, "sis$", "ses");
		inflect = Regex.Replace(inflect, "(?:([^f])fe|([lr])f)$", "$1$2ves");
		inflect = Regex.Replace(inflect, "(hive)$", "$1s");
		inflect = Regex.Replace(inflect, "([^aeiouy]|qu)y$", "$1ies");
		inflect = Regex.Replace(inflect, "(x|ch|ss|sh)$", "$1es");
		inflect = Regex.Replace(inflect, "(matr|vert|ind)(?:ix|ex)$", "$1ices");
		inflect = Regex.Replace(inflect, "^(m|l)ouse$", "$1ice");
		inflect = Regex.Replace(inflect, "^(m|l)ice$", "$1ice");
		inflect = Regex.Replace(inflect, "^(ox)$", "$1en");
		inflect = Regex.Replace(inflect, "^(oxen)$", "$1");
		inflect = Regex.Replace(inflect, "(quiz)$", "$1zes");

		inflect = inflect
			.Replace("person", "people")
			.Replace("man", "men")
			.Replace("child", "children")
			//.Replace("sex", "sexes")
			.Replace("move", "moves")
			.Replace("zombie", "zombies");

		if (inflect == value) inflect += "s";

		return inflect;
	}
	//https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/activesupport/lib/active_support/inflections.rb

```

ついでにテストも勉強中なので、テストも作ってみました。
テスト通ったから、こんな感じなのでしょうか。

```C#

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tool.Tests
{
	[TestClass()]
	public class MainWindowTests
	{
		[TestMethod()]
		public void InflectionsTest()
		{
			Assert.AreEqual("wolves", "wolf".Inflections());
			Assert.AreEqual("apples", "apple".Inflections());
			Assert.AreEqual("gifts", "gift".Inflections());

			Assert.AreEqual("boxes", "box".Inflections());

			Assert.AreEqual("people", "person".Inflections());
			Assert.AreEqual("men", "man".Inflections());
			Assert.AreEqual("women", "woman".Inflections());
			Assert.AreEqual("children", "child".Inflections());
			Assert.AreEqual("sexes", "sex".Inflections());
			Assert.AreEqual("zombies", "zombie".Inflections());
		}
	}
}

```
bashで標準入力をシングルクォーテーションで囲みカンマをつける(CSV?

bashで標準入力をシングルクォーテーションで囲みカンマをつける(CSV?

```:bash
cat| awk '{for(i=1;i<=NF;i++)printf("'\''"$i"'\'' ,")}END{printf("\n")}'
```

JSの配列を生成するのに使用。これはCSVなのか？

参考

- [sed/awkで各文字列をシングルクォーテーション・ダブルクォーテーションで囲む | 俺的備忘録 〜なんかいろいろ〜]
(https://orebibou.com/2017/03/sedawk%E3%81%A7%E5%90%84%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%82%AF%E3%82%A9%E3%83%BC%E3%83%86%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%BB%E3%83%80%E3%83%96/)

> "awkの場合
awkの場合だとこんな感じ。

>1
2
awk '{for(i=1;i<=NF;i++)printf("\""$i"\" ")}END{printf("\n")}' # ダブルクォーテーションの場合
awk '{for(i=1;i<=NF;i++)printf("'\''"$i"'\'' ")}END{printf("\n")}' # シングルクォーテーションの場合
blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{for(i=1;i<=NF;i++)printf("\""$i"\" ")}END{printf("\n")}'
"abc" "def" "ghi"
blacknon@BS-PUB-UBUNTU-01:~$ echo abc def ghi | awk '{for(i=1;i<=NF;i++)printf("'\''"$i"'\'' ")}END{printf("\n")}'
'abc' 'def' 'ghi'"
フィッシャー–イエーツのシャッフル、分割代入で入れ替え

フィッシャー–イエーツによる配列のシャッフル。
入れ替え部分が分割代入で書ければ一行で済んでスッキリ。

```javascript
const shuffleArray = arr => {
  let n = arr.length
  while (n) {
    const r = Math.floor(Math.random() * n--);
    [arr[r], arr[n]] = [arr[n], arr[r]]
  }
  return arr
}
```
server.servlet.session.timeoutのデフォルト値

spring-boot-2.1.8では30分。

```xml
   <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath />
    </parent>
```

ドキュメントが見当たらなかったのでソースコード見たところ以下のようになっている。

```java
package org.springframework.boot.web.servlet.server;

public class Session {

	@DurationUnit(ChronoUnit.SECONDS)
	private Duration timeout = Duration.ofMinutes(30);
```
災害時に何を考えるのか？

#今回令和元年台風１５号にて感じたことを書いています  
最近ですが。
ふと思うことがいっぱいあります。
正直やらないといけないことがいっぱいありすぎてしまって困ってしまう。
これ一番まずいです。
まず最初にやらないといけないことは情報を地図に落としてみる。
これだと思います。  
##クライシスマッピングの有効性  
これは一番に感じました。
マッピングをしていくと共に情報が整理されていきました。
ただし、初めての人はOpenStreetMapを使うことを勧めません。
なぜならOpenStreetMapは最初からWebアプリなど加工されるための地図であることを認識されている方は少ないと思います。
まず最初は今回自分も使いましたがGoogleMyMapで自分なりのものを作成することをおすすめしたいと思います。
なぜなら操作も簡単でレイヤわけもできこれほど良いツールは思いつきません。
まずかんたんなもので攻めるこれが肝心だと思います。
##やってみて思ったことは  
意外とやってほしいと伝えると自分たちで動いてくれる方も見えましたが。
殆どはグループで投稿だけする人たちの多さにびっくりしました。
情報が逆流して一時期異常すぎるほどおかしな情報が流れていることもありました。
ある野党議員とかは自分の主張を押し通すばかりで役には立っていません。
正直ありのまま流すのが一番なのかなと思ってしまいました。    
##これからやらざる負えないのは  
ずばり災害ボランティアを継続することです。
一時ごとでは収まらないことがはっきりとしています。
台風災害はいつどこで起きるかわかりません。
そのときにどういった形にまとめるかが今後の課題になると思います。
正直言うとこれが一番難しい。
自分のやりたいことをやっても構わないが集約することには付き合っていただきたいと思うのが私からの希望です。  
##今後の動きとして  
今後はOpenStreetMapベースの使いやすいWebアプリを作ろうとしています。
それは国民が災害にあったときに必要なものです。
今回の災害で思ったことはFineMyStreetも役立たずだったことこれが一番痛かったことです。
それ以上に簡単な被害通知システムが今後必要になると思います。
それを作りにかかりたいと思います。
以前から話題になってましたが色んな派閥が出てきてしまい作成にこぎつけてません。
今年中には作成にかかり今後作り上げていく流れを自分は作りたいと思います。
できたときにはちゃんとした場所で公開したいと思います。

###今言えることは災害が起きるとみんなドタバタです。これを打破しないといけない。
といったことでしょうね。
JavaScriptの変数の巻き上げ(Hoisting)

# ふたこと要約
`var` で宣言された変数はホイスティングされるよ。
これを知らない故に、意図しない値代入とか発生しているかもだよ。

# JavaScriptの巻き上げ(Hoisting)とは
## その前に
### JavaScriptの変数定義 `var`
- 関数内のどこからでも宣言することができる。
- 再宣言も可能。

## varを使うとホイスティング(巻き上げ)が起こる
- どこからでも宣言できる `var` は、関数内のいかなる場所で宣言されたとしても、その関数の先頭で宣言されたのと同じように動作する。

### 例
```js
var test = "test1";

function func_hoisting() {
    console.log("func_hoisting-1 ", test);
        // 期待値:test1, 出力: undefined
    
    var test = "test2";
        // 関数内で宣言。
    
    console.log("func_hoisting-2 ", test); // 出力: test2
}
```

### 解説
感覚的に、最初の `func_hoisting-1` では関数外で宣言した `test1` が出力されると期待するが、実際は `undefined` となる。

これは、関数 `func_hoisting()` の2行目でtestという変数を宣言することで、この関数の先頭で `var test;` と宣言されたことと同義となるため起きる現象。

つまり、func_hoisting()は以下と同じ動作をしている。

```js

function func() {
    var test; // 変数を宣言。

    console.log("func-1 ", test); // 出力: undefined
    var test = "test2";
    console.log("func-2 ", test); // 出力: test2
}
```
このように、変数の宣言が関数の先頭に移動したように見えるため、巻き上げ(Hoisting)と呼ばれている。

# 対策（推奨しない）
## 関数内で利用する変数に `var` をつけない
```js

var test = "test1";

function func_not_hoisting() {
    console.log("func_not_hoisting-1 ", test); // 出力: test1

    test = "test2"; // varをつけずに代入
    console.log("func_not_hoisting-2 ", test); // 出力: test2
}

```

# 対策
## 変数の宣言は適宜正しく行う。
関数の先頭で明示的に宣言しておけば、意図しない値にはならない。

```js

function func() {
    var test; // 変数を宣言。

    console.log("func-1 ", test); // 出力: undefined
    var test = "test2";
    console.log("func-2 ", test); // 出力: test2
}
```

# もっと推奨
変数の定義には `const` , `let` がES2015で追加されている。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements#Declarations
そちらに移行していくのがベスト。

# 参照
https://developer.mozilla.org/ja/docs/Glossary/Hoisting
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var#var_hoisting
Laravel6でVueを入れずにBootstrap、jQueryのみのmake:auth

公式見て従来の`make:auth`と同等のしようとすると
VueかReactが入っちゃう記載になっている

試しにやってみたらうまくいったのでメモ

>Laravelが提供するBootstrapとVueのスカフォールドは、Composerを使いインストールするlaravel/uiパッケージに用意してあります。

とのことなので、Laravelのプロジェクト直下にて

```bash
composer require laravel/ui
```

laravel/uiパッケージをインストールできたら、ui Artisanコマンドを使いBootstarpをインストールします。

```bash
// 基本的なスカフォールドを生成
php artisan ui bootstrap

// ログイン／ユーザー登録スカフォールドを生成
php artisan ui bootstrap --auth
```

あとは、

```bash
npm install

npm run dev
```

をしたら

見慣れた画面が出来ております。
![SC000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/174757/deae805e-8862-260f-65fb-13d39139b1a3.jpeg)


別にVueは使わないよって時に、お試しください
シンデレラガールズで最も体型の近い二人は誰？

[前回](https://qiita.com/ysk0832/items/d47dbff02d687df62efb)の続きというかおまけみたいな感じ．
ソースコードは[ここ](https://github.com/ysk0832/hobby)

#やること
全員分のcos類似度を計算するだけ。データは(身長,体重,B,W,H)の５次元ベクトル。190人いるので、組合せは~~190×189×(1/2)=17955通りあります。~~4人抜いてるので186×185×(1/2)=17205通りでした。

#コード
前回と概ね同じです。

```python
import numpy as np
import pandas as pd

# csv読み込み
df=pd.read_csv("cg.csv")

# 内積
def ip(a,b):
  return (a*b).sum()
# ノルム
def norm(x):
  sum=(x*x).sum()
  return np.sqrt(sum)
# 類似度
def sim(a,b):
  return ip(a,b)/(norm(a)*norm(b))

# 名前と計算結果をリストに保存
name1list=[]
name2list=[]
simlist=[]
count = 0 #計算の進捗確認用
for i in range(0,185):
  for j in range(i+1,186):
    result=sim(df.iloc[i,1:6],df.iloc[j,1:6])
    count+=1
    if count%1000==0:
      print(result)
    name1list.append(df.iloc[i,0])
    name2list.append(df.iloc[j,0])
    simlist.append(result)

# 新たにデータフレームを作成
df_result=pd.DataFrame({'name1':name1list, 'name2':name2list, 'sim':simlist})

# 類似度top10を出力
print(df_result.sort_values("sim",ascending=False).iloc[0:10])
```

結果
<img width="310" alt="スクリーンショット 2019-09-26 0.52.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/462051/7da50917-731b-1d83-bd2e-0896c05e2f93.png">


一番類似度が高かったのは里奈とライラさんでした。けっこう意外?
数値見比べてみるとこんな感じ。

   |身長|体重|B|W|H
---|---|---|---|---|---
藤本里奈|154|41|77|55|80
ライラ|150|40|75|54|78

確かに近いですね。里奈がライラさんのほぼ上位互換といったところ（失礼）．調べてみたらこの二人，2014年のクリスマスガチャで絡んでるんですね．ユニットとかあったら個人的に面白いと思う．
他にも、飛鳥と頼子、イヴとほたるが同率で２位だったり、けっこう面白い結果になりました。

#まとめ
ライラさんは成長するとぽよる（暴論）
Terraform init で Registry service unreachable. とエラーが出た場合の対処法


# 環境
Terraform 0.12.9
MacOS Mojave 10.14.6

# エラー

terraform init をすると、こんなエラーが表示されました。

```terminal:terminal
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...

Registry service unreachable.

This may indicate a network issue, or an issue with the requested Terraform Registry.


Error: registry service is unreachable, check https://status.hashicorp.com/ for status updates
```

# どうやったら解決出来るだろうか？

バージョンを変えれば解決するのではと思い、[tfenv](https://qiita.com/kamatama_41/items/ba59a070d8389aab7694)を使ってバージョンを 0.12.9 -> 0.11.14 にダウングレードして再び``terraform init``した所、次はこんなエラーが、、、

```terminal:terminal
Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...

Error installing provider "aws": Get https://releases.hashicorp.com/terraform-provider-aws/: dial tcp: i/o timeout.

Terraform analyses the configuration and state and automatically downloads
plugins for the providers used. However, when attempting to download this
plugin an unexpected error occured.

This may be caused if for some reason Terraform is unable to reach the
plugin repository. The repository may be unreachable if access is blocked
by a firewall.

If automatic installation is not possible or desirable in your environment,
you may alternatively manually install plugins by downloading a suitable
distribution package and placing the plugin's executable file in the
following directory:
    terraform.d/plugins/darwin_amd64
```

最後の文によると、どうやらプラグインを手動でダウンロードすれば良さそうです。

さらに[このサイト（Terraform Provider がないエラー対処 | infraya.work）](https://infraya.work/posts/terraform_init_error/)を見ると、[https://releases.hashicorp.com/](https://releases.hashicorp.com/)からプラグインをダウンロード出来るみたいです。

# 解消方法

ということで、[https://releases.hashicorp.com/](https://releases.hashicorp.com/)から該当するプラグインのzipファイルをダウンロードして解凍し、出てきた実行ファイルを``/Users/ユーザー名/.terraform.d/plugins/``に置いた所、エラーが解消されました。

```terminal:terminal
$ terraform init

Initializing the backend...

Initializing provider plugins...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

# 追記

僕の場合はawsのプラグインが足りないみたいだったので、これをダウンロードしました。
@2019/9/26

https://releases.hashicorp.com/terraform-provider-aws/2.29.0/terraform-provider-aws_2.29.0_darwin_amd64.zip
AWSからの通知「New Amazon EC2 On-Demand Instance limits now available」

## 9/25のAWSからの通知
AWSから以下のタイトルのメールが届きました。
`New Amazon EC2 On-Demand Instance limits now available`

本文は

```
Dear Amazon Web Services Customer,

We recently announced Amazon EC2’s vCPU-based On-Demand Instance limits, which simplify limits
for EC2 customers. Today starts a transition period, during which you can opt in to vCPU-based 
limits. The transition to vCPU limits will not have an impact on any of your running instances 
or on your ability to launch new instances. However, we recommend that you familiarize yourself
with the new On-Demand Instance limits experience and opt in to vCPU limits at a time of your 
choosing. Note that the transition will end on October 24, 2019, at which point all EC2 accounts
will switch to vCPU-based On-Demand Instance limits regardless of the account’s opt-in status 
or region.

You can opt-in to vCPU-based limits from the Amazon EC2 console, and you can also view your limits
and usage from the Amazon EC2 console or the Service Quotas console. Additional information on 
vCPU-based On-Demand Instance limits can be found in the FAQs and documentation. Please contact 
the AWS support team on the community forums or via AWS Premium Support if you have questions. 
Click below to opt in to vCPU limits now.
```


EC2インスタンスの制限方法が変わるよ！ということみたいです。

調べたところ、以下のfaq記事のようです。
[EC2 オンデマンドインスタンス制限](https://aws.amazon.com/jp/ec2/faqs/#EC2_On-Demand_Instance_limits)

今までは走らせるEC2インスタンスの数量に制限がありました。例えばm5.largeは２０個までとか。
これが10/24ころから *vCPU数の合計値（vCPUベースでの制限）* に変わるよ！とのことです。

そして、希望するなら9/24からvCPUベースでの制限にすぐ変更するよ！（オプトイン）とのことです。

気になるのはvCPUの合計数制限はどのくらいなのか？
上記のAWSのFAQを見る限り、デフォルトでは1152個あるみたいです。

今使ってるm5.largeは2vCPUしかないですね。私の環境には全く影響ないようです。

## この通知に対して何をすればよいか？
わからなかったらサポートに聞けとありますが、今回は私の環境に全く影響ないので、文末の
`Click below to opt in to vCPU limits now`
にあるように、「オプトインしてくださいね」に従います。

## EC2コンソールへ移動
### 左メニューの「制限」を選択
以下のように「Opt in」ボタンが表示されていますので、押します。
![Image05165.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495044/62605978-93b5-1cc6-67a7-a44cfa52598b.jpeg)

### あとは待つだけです。
１５分ほど完了するから待てというメッセージが表示されます。
![Image05166.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495044/0b146f7e-7533-43c8-438d-4957ac614e42.jpeg)

### vCPU制限のシミュレーション
オプトイン後は、「Calculate vCPU limit」というボタンが表示され、どのインスタンス毎にどのくらいvCPUが必要か、今どのくらいの制限になっているかなどがシミュレーションできるようです↓

![Image05167.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495044/f7f7a98b-f5e8-3dbe-23e8-cd0aed49dd34.jpeg)


![Image05168.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495044/064d8ea6-684d-63de-95fe-8f01ea83ab7a.jpeg)

そして、この画面から上限値変更申請もできるようです。
UIDocumentBrowserViewControllerがiOS13シミュレータでろくすっぽ動かない問題


# 起こった問題


|![Simulator Screen Shot - iPhone Xs Max - 2019-09-26 at 14.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817/ff2a627c-6d83-a163-1a02-793af56a8416.png)|
|:-:|

UIDocumentBrowserViewController、みなさん使ってますか？
使ってるわけないですよね。私は使ってます。

iCloudにファイル保存しようと思ったら、UIDocumentBrowserViewControllerを使うのが圧倒的に簡単なんです。とはいえ、マルチプラットフォームでアプリ開発しようと思うと、iCloudって微妙ですよね。だから人気がないんだと思います。だけど、Apple信者には関係のない話です。

さて、私の作っている小説エディタ「おめめライター」では、UIDocumentBrowserViewControllerでプレーンテキストファイルを取り扱っています。テキストファイルを新規作成するのには、以下のようなコードを書いてます。

```swift
    func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
        if let url = Bundle.main.url(forResource: "File", withExtension: "txt") {
            importHandler(url, .copy)
        } else {
            importHandler(nil, .none)
        }
    }
```

バンドルファイルのFile.txtという空テキストファイルをテンプレートにして、それをユーザが指定した場所にコピーするわけですね。

iOS13がリリースされたので、さっそくXCode11をインストールしてダークモード対応をしようと思ったのですが、シミュレータを立ち上げて新規ファイルを追加しようとしたところ、ウンともスンとも言わなくなってしまったのです。そして、以下のようなエラーが。


```
...
error Error Domain=NSPOSIXErrorDomain Code=22 "couldn't issue sandbox extension com.apple.app-sandbox.read for ...
```
`NSPOSIXErrorDomain Code=22`ってなんでしょう？

そんな大層なことをしているわけでもないのに、なぜこんなエラーが出るのかわかりません。というか、ファイルが追加できないなんてエディタとして終わってます。
慌てて実機で動かしてみると、iOS13でも問題なく動きます。

これは何かシミュレータの問題なんだろうなと思って調べたら、以下のような記事を見つけました。

[UIDocumentBrowserViewController error “Cannot create urlWrapper for url” on iOS13 simulator](https://stackoverflow.com/questions/57807670/uidocumentbrowserviewcontroller-error-cannot-create-urlwrapper-for-url-on-ios1)

>I have a very strange problem with UIDocumentBrowserViewController when testing on iOS 13. The importHandler(newDocumentURL, .move) seems to crash without any reason 
>>I've verified that the bug exists with Xcode 11.1 GM running on Mac OS Mojave.
>

Mojaveで動かすXCode11.1GMにバグがあるみたいです。
私の環境はXCode11.0 (11A420a)なんですが、まったく同じ現象が起きてますね。

というか、UIDocumentBrowserViewControllerを使っている人って私以外にもいたんですね。世界は広い。

#解決策

当面はCatalinaのベータを使うくらいしかないみたいです。
ていうか今投稿しようとしたら`UIDocumentBrowserViewController`のタグは長すぎるって言われたわ。

さあ、みんなも使おう、UIDocumentBrowserViewController！
Perlを使って指定したファイルを自動的にコピーしてみた

#はじめに 
大学の研究で膨大な量のファイルを扱う機会があったので、Perlでファイルのコピーを自動化してみました。
今回は指定した名前のファイルを選択し、ディレクトリにコピーする方法です。
以下のようなディレクトリ構成となっています。
xdir
|-xfile1
|-xfile2
|-xfile3
xxdir
|-xxfile1
|-xxfile2

#実行環境
- Ubuntu 18.4
- Perl v5.26.1

#ソースコード
ファイル名はFiles_cpy.plとします。
実行はスクリプトのあるディレクトリから
$perl Files_cpy.pl [コピーするファイル名]
で行います。

```Files_cpy.pl
#!/usr/bin/perl 

use strict; 
use warnings; 

use Cwd; 

use constant{ 
     TARGET_DIRECTORY => "コピー先のディレクトリ名", 
 }; 

my $name = $ARGV[0]; #コピーするファイル名
my $CurrentDir = Cwd::getcwd(); #カレントディレクトリを取得
DeployFiles($CurrentDir); #メイン処理

##DeployFiles 
sub DeployFiles{ 
    my $CurrentDir = shift; #ひとつの引数を受け取る 
    my @list = (); 

    #カレントディレクトリの一覧を取得 
    opendir(DIR, $CurrentDir) or die("Can't get directory.:$CurrentDir($!)"); 
    @list = readdir(DIR); 
    closedir(DIR); 
 
    foreach my $dir (sort @list){ #辞書順にソート 
    next if($dir =~ /^\.{1,2}$/); #カレントディレクトリ"."とひとつ上の階層のディレクトリ".."は処理しない 
    next if($dir eq TARGET_DIRECTORY); #コピー先のディレクトリ内のファイルは処理しない
    #ディレクトリのみにマッチ 
   if(-d "$CurrentDir/$dir"){ #ディレクトリの存在を確認 
      CopyFiles($CurrentDir, $dir); 
     } 
   } 
 } 

##CopyFiles 
sub CopyFiles{ 
    my $CurrentDir = $_[0]; 
    my $TargetDir = $_[1]; 
    my @list = (); 
    # ディレクトリ内のディレクトリ・ファイルを取得 
    opendir(DIR, "$CurrentDir/$TargetDir") or die("Can't get directory.:$CurrentDir($!)"); 
    @list = readdir(DIR); 
    closedir(DIR); 

    foreach my $file (@list){ 
      next if($file =~ /^\.{1,2}.*$/); 
      next if($file =~ /~/);
      #ファイルのみにマッチ 
      if(-f "$CurrentDir/$TargetDir/$file"){ 
         if($file =~ /$name/){ 
         #cpコマンドを利用
         my $cp = "cp $CurrentDir/$TargetDir/$file $CurrentDir/".TARGET_DIRECTORY; 
         system($cp) == 0 or die "Can't execute $cp: $!"; #ターミナル上での実行
       } 
     } 
   } 
 } 
```

#参考
以下の記事を参考にさせて頂きました。
https://www.eda-inc.jp/post-987/
TStringGridの表のセルデータをif文で使用するとエラーがでる。

（2019年9月27日 12:05追記）
とりあえずできるようになってきました。（＾＾；




（本文）
現在、複数のクライアントを接続できるようにするサーバの作成の勉強をしています。
https://github.com/KenjiMaehara/CppChatTCP/tree/master/TCPServer

クライアントがサーバに接続するたびに、リスト表の欄に1行ずつ、そのクライアントに付属するデータを表示するようにしたいと思っております。


（イメージ図）
![コメント 2019-09-26 115113.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190290/3d6b1949-b0f0-cb3c-a0dc-6ad0eb0b06b7.png)










そこで、クライアントの送信したデータを受信するChatServerExcuteのハンドラを次のようなプログラムにしました。

https://github.com/KenjiMaehara/CppChatTCP/commit/9cc5cff987ccf0ed9ebbbebaa7414e28fd199ecd

```ruby:Unit1.cpp
void __fastcall TTCP_Server::ChatServerExcute(TIdContext *AContext)
{


	AnsiString rcvdStr;


	rcvdStr = AContext->Connection->IOHandler->ReadLn(IndyTextEncoding(932));

	TList *threads;
	TIdContext *ac;


	// 受信元情報の表示
	String msg;
	msg = L"source IP:" + AContext->Connection->Socket->Binding->PeerIP;
	LMessage->Items->Add(msg);
	msg = L"\r\nsource port:" + IntToStr(AContext->Connection->Socket->Binding->PeerPort);
	LMessage->Items->Add(msg);
	LMessage->Items->Add(rcvdStr);  // 受信済の[rcvdStr]を使用


	threads = ChatServer->Contexts->LockList();

	for(int idx=0; idx < threads->Count; idx++){
		ac = reinterpret_cast<TIdContext *>(threads->Items[idx]);

		if (AContext->Connection->Socket->Binding->PeerPort == ac->Connection->Socket->Binding->PeerPort) {
			ac->Connection->IOHandler->WriteLn(rcvdStr);
			LMessage->Items->Add(threads->Count);


			for (int i = 0; i < StringGrid1->RowCount; i++) {
				if (AContext->Connection->Socket->Binding->PeerPort != StringGrid1->Cells[5][i]) {
					StringGrid1->RowCount += 1;
					StringGrid1->Cells[5][StringGrid1->RowCount] = AContext->Connection->Socket->Binding->PeerPort;
				}
			}
		}
	}

	ChatServer->Contexts->UnlockList();

}
//---------------------------------------------------------------------------



```

とりあえず、ChatServerExcuteのハンドラが起動したら、すでに接続済みならクライアント情報が表示されているはずのStringGrid1の全行の5列目にあるクライアントの接続元ポート番号とAContext->Connection->Socket->Binding->PeerPortとを比較して、不一致だったらば新規のクライアントであると判断して、1行加えて現在受信中のAcontextのデータを使ってStringGrid1にデータを追加したいと考えています。


ただ、ビルドは完了しましたが、デバッグ時に、クライアントから接続されると

```ruby:Unit1.cpp
-------（中略）---------------------------------------------------------------------
if (AContext->Connection->Socket->Binding->PeerPort != StrToInt(StringGrid1->Cells[5][i])) {
-------（中略）---------------------------------------------------------------------
```

デバッグで、ステップ実行していくと、この行でエラーが出て止まってしまいます。

（エラー画面）
![コメント 2019-09-27 102855.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190290/f9fcaeaf-4bcc-b9b0-20e7-12461877dbc5.png)

どうも、"StringGrid1->Cells[5][0]"内にある”接続元ポート”という文字データとPeerPortのデータ内容のデータ型が違うというようなエラー表示が出てきます。

このような場合のエラーの回避方法を教えて頂きますよう、よろしくお願い致します。
Cognitoが指示していないのに+12064350128にSMSを送っても心配は要らない

Cognitoの二段階認証用のSMSを受け取れないユーザーが居たので、
色々設定を弄りながらCloudWatchのログを監視していたところ、
何故かアメリカの番号(+12064350128)にSMSを送信しているログを発見しました。

まさか乗っ取られたか？と焦りましたが、特に問題はないようです。

# +12064350128はAwsのCognito teamの番号
Cognitoのユーザープールの設定を変えたタイミングで、
きちんとSMSが飛ぶことをAWS内部で確認するそうで、そのタイミングで飛ぶ番号がこれとのことです。

# まとめ
* Cognitoが指示していないのに+12064350128にSMSを送っても心配は要らない
@webpack-cli/init を使ってコマンドラインから webpack.config.js を作成する

webpack-cli を使い、コマンドラインから webpack.config.js を作成する方法です。
手作業で作成した場合の記入漏れなどを考えると、導入の手間はかかるものの @webpack-cli/init を使って作成した方が安全な気がします。

すでに node.js はインストールされているものとして話を進めます。
初めにコマンドライン上でwebpackを実行するためのツール **webpack-cli** をインストールします。
次にwebpack.config.js の作成に必要な **@webpack-cli/init** をインストールします。

```
npm install -D @webpack-cli/init
```

@webpack-cli/init がインストールできたら以下コードを実行し、webpack.config.js を作成します。

```
npx webpack-cli init
```

すると、以下のように対話形式で処理が進むため、必要な設定を指示。
設定に関する質問は6つです。

```PowerShell
i INFO  For more information and a detailed description of each question,
have a look at: https://github.com/webpack/web
pack-cli/blob/master/INIT.md
i INFO  Alternatively, run "webpack(-cli) --help" for usage info

? Will your application have multiple bundles? y
? Which will be your application entry point? index
? In which folder do you want to store your generated bundles? y
? Will you use one of the below JS solutions? ES6
? Will you use one of the below CSS solutions? SASS

conflict package.json
? Overwrite package.json? overwrite

force package.json
create index.js
create README.md
```

それぞれの質問内容を確認します。
下記の公式レファレンスとは質問内容が少し異なっているようです。
[webpack-cli/INIT.md at master · webpack/webpack-cli · GitHub](https://github.com/webpack/webpack-cli/blob/master/INIT.md)

1. **Will your application have multiple bundles?**
アプリに複数のエントリポイントがあるかどうかを問われています。
複数のエントリポイントが必要な場合は、**y(or yes)** と答えます。
1つだけにしたい場合は、**n(or no)** と答えましょう。


2. **Which will be your application entry point?**
アプリケーションのエントリポイントとなるファイル名を問われています。
これにより、webpack にアプリケーションのバンドルを開始するファイルを指示します。
デフォルトは **src / index** です。
これは、srcという名前のフォルダー内でindexというファイルを検索するようwebpackに指示します。


3. **In which folder do you want to store your generated bundles?**
生成されたバンドルをどのフォルダに保存するかを問われています。
このフォルダはバンドルされたアプリケーションがある場所を指します。
index.html は、通常 **dist**という名前のフォルダから生成されたバンドルを読み取ります。


4. **Will you use one of the below JS solutions?**
ES6、Typescript、いずれの JavaScript を使用するか選択します。
No は上記どちらも使わない場合に選びます。


5.  **Will you use one of the below CSS solutions?**
CSS、SASS、LESS、PostCSS、いずれを使用するか選択します。
No は上記どれも使わない場合に選びます。


6. **Overwrite package.json?**
@webpack-cli/init には package.json の自動作成機能もあります。
そのため、すでに package.json が存在する場合、以下6項目から回答を求められます。
`npm init` で package.json を作成済みの場合は「y」を選択します。
    - y) overwrite
    - n) do not overwrite
    - a) overwrite this and all others
    - x) abort
    - d) show the differences between the old and the new
    - h) Help, list all options

以上の質問を経て処理が進むと最終的に以下が表示され、プロジェクトディレクトリ内にwebpack.config.json が作成されます。


```PowerShell
Congratulations! Your new webpack configuration file has been created!
You can now run npm run start to run your project!
```


## 参考：
- [@webpack-cli/init - npm](https://www.npmjs.com/package/@webpack-cli/init)
- [webpack-cli/INIT.md at master · webpack/webpack-cli · GitHub](https://github.com/webpack/webpack-cli/blob/master/INIT.md)
AnacondaでGraphvizをインストールする

　Graphvizのインストールにつまる声を良く聞く+web上のリファレンスが何故かパスを通すところまでで終わっていることが多いのでまとめておきます。

　結論から言うと、Graphviz自体はPythonパッケージではないので、少なくともWinのAnaconda環境ではPython用ラッパークラスのインストールが必要です。
　しかも、Python用ラッパーには**本体が含まれていない**のでPython用ラッパーのインストールとは別に本体のインストールが必要です。なんでこんなトリッキーなんだ・・・

#手順
　[公式](https://graphviz.gitlab.io/)から本体をダウンロードして解凍後、任意の場所に解凍したフォルダを置いてパスを通します。Winの場合、環境変数＞ユーザー環境変数orシステム環境変数(Pythonのパスが通ってる方)のPATH変数にGraphvizフォルダの下にある`dot.exe`のパスの値を追加で貼り付けてください。
　C直下に置いた場合は`C:\Users\ユーザー名\graphviz\bin`あるいは`C:\Users\ユーザー名\graphviz2.38\release\bin`みたいな感じです。
　パスを通したら、**pipでpython用ラッパーをインストールします(重要)。**

```
$ pip install graphviz
```

　その後、Jupyterなどで以下のコードを打ってエラーが返ってこなければ成功です。
　※[公式ドキュメント](https://pypi.org/project/graphviz/)から引用したソースです。

```python
from graphviz import Digraph

dot = Digraph(comment='The Round Table')
dot
```

　ついでにグラフ描写までテストしたい人は以下も続けて実行してみてください。

```python

dot.node('A', 'King Arthur')
dot.node('B', 'Sir Bedevere the Wise')
dot.node('L', 'Sir Lancelot the Brave')

dot.edges(['AB', 'AL'])
dot.edge('B', 'L', constraint='false')

print(dot.source)
```

出力結果1
`// The Round Table
digraph {
	A [label="King Arthur"]
	B [label="Sir Bedevere the Wise"]
	L [label="Sir Lancelot the Brave"]
	A -> B
	A -> L
	B -> L [constraint=false]
}`

その後、以下のコードを実行して出力結果2のような図が描写されればOKです。

```python
dot.render('test-output/round-table.gv', view=True)
```
出力結果2
![round-table.gv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448703/9a0c16be-2847-b33f-7458-10716215bb2d.png)


#注意点
　Graphviz本体はcondaでもインストールできます。ですがcondaでインストールしようとすると、パスがうまく通りませんでした。これはたぶん環境によると思うので上手くいく人は上手くいくと思います。
　また、英語があまり強くないので断言できませんが、[公式](https://graphviz.gitlab.io/)からダウンロードできるのは**本体のみ**のようです。
　Python-graphvizはpipでインストールすることを推奨されています。以下の公式ドキュメントやPyPIもご参照ください。
　なお、Python-graphvizの最新バージョンは2019年9月現在0.13ですが、本体の安定バージョンは2.38で、当たり前ですが**別物**なのでバージョンがずれています。注意しましょう。

#参考
- [User Guide](https://graphviz.readthedocs.io/en/stable/manual.html)
- [PyPI](https://pypi.org/project/graphviz/)