OmniAICreator/Qiita-1.07M huggingface dataset:
3D Photo Inpaintingで画像をぐりぐりすーる（Windows10、Python 3.7）

# はじめに

一枚の画像からDepthを推定して、ぐりぐりしても、違和感なくインペイントする3D Photo Inpainting（以下、3DP）をやってみました。CPUでも動くよ。

# システム環境
- Windows 10
- Anaconda 2020.02
- Python 3.7
- MeshLab

# 導入
Anacondaをインストールします。pyenv派の人やもともとpython入ってる人（macとか）は、環境ぶっ壊すのでやめてね。

[3d-photo-inpainting](https://github.com/vt-vl-lab/3d-photo-inpainting)からクローンします。

Anaconda Promptを開き、3DP環境を作ります。

~~~
$ cd 3d-photo-inpainting-master
$ conda create -n 3DP python=3.7 anaconda
$ conda activate 3DP 
~~~

必要なライブラリをインストールします。Pytorchは、https://pytorch.org/ のpipコマンドを参考にしましょう。（condaとpipを混ぜるのはあんまり好きじゃないので僕はpipで統一するようにしています）

~~~
$ pip install -r requirements.txt
$ pip install torch==1.5.0+cu101 torchvision==0.6.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html
~~~

./download.shを実行します。もしくは、次の[color-model.pth](https://filebox.ece.vt.edu/~jbhuang/project/3DPhoto/model/color-model.pth) 、[depth-model.pth](https://filebox.ece.vt.edu/~jbhuang/project/3DPhoto/model/depth-model.pth)、[edge-model.pth](https://filebox.ece.vt.edu/~jbhuang/project/3DPhoto/model/edge-model.pth)の3つをダウンロードし、checkpointsフォルダを作成し、そこに置きます。もう一つ、[model.pt](https://filebox.ece.vt.edu/~jbhuang/project/3DPhoto/model/model.pt)をMiDaSフォルダへ置きます。

# 実行

imageフォルダにぐりぐりしたい画像を置き、下記コマンドを実行すると、videoフォルダに4つの動画が生成されます。（prof_circle、prof_dolly-zoom-in、prof_swing、prof_zoom-in）

~~~
$ python main.py --config argument.yml
~~~

argument.ymlの中にあるgpu_idsを-1にすればcpuで動きます。

ぐりぐりできました！

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今流行りの3D Photo Inpaintingやってみた。<br>もともとポートレートだけど笑<a href="https://t.co/NLq2Wsnm0a">https://t.co/NLq2Wsnm0a</a> <a href="https://t.co/emHtfc3DuA">pic.twitter.com/emHtfc3DuA</a></p>&mdash; 藤本賢志(ガチ本)@pixivFANBOXはじめました (@sotongshi) <a href="https://twitter.com/sotongshi/status/1253153279384551424?ref_src=twsrc%5Etfw">April 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

meshフォルダに3Dモデル(.ply)も生成されているので、MeshLabで見てみましょう。

<blockquote class="twitter-tweet"><p lang="und" dir="ltr">ply <a href="https://t.co/mPjmhjbp7W">pic.twitter.com/mPjmhjbp7W</a></p>&mdash; 藤本賢志(ガチ本)@pixivFANBOXはじめました (@sotongshi) <a href="https://twitter.com/sotongshi/status/1253200781336915968?ref_src=twsrc%5Etfw">April 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

お疲れ様でした。
【備忘録】課題解決テンプレート

# 何をしたかったか


# コード


# エラー文原文  


# エラー文訳（Deep L翻訳）  


# 原因


# 改善案


# 改善コード


# 参考文献


# Mark Down テンプレート
```
# 何をしたかったか


# コード


# エラー文原文  


# エラー文訳（Deep L翻訳）  


# 原因


# 改善案


# 改善コード


# 参考文献

```
Avatarifyで他人の顔を乗っ取り、web会議に出席する

#Zoom Hacking連載
[①FaceRig/SnapCamera+VT-4で参加したZoomをOBS経由でRTMP配信するまで](https://qiita.com/tetsuyaimagawa/items/86b843430011744a0602)
[②VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜](https://qiita.com/tetsuyaimagawa/items/dd82e2a3bf10488457bf)
[③Zoomで小技を出しつつも、こいつオタクなのかな？と思われたくない iVCam+DroidCamをOBS VCから流す方法](https://qiita.com/tetsuyaimagawa/items/d63db39dc42b466aa8ad)
[④Spark AR Studioで、他人の顔を自分の顔に被せてWeb会議に出席する]  (https://qiita.com/tetsuyaimagawa/items/dbdfe855756e3405c162)
[⑤Avatarifyで他人の顔を乗っ取り、web会議に出席する] (https://qiita.com/tetsuyaimagawa/items/8f180216712595071878)

#概要
昨今、Zoomを始めとするWeb会議システムの利用が増えており、それに関わる技術にも注目が集まっている。
今回は、自分の顔の動きに連動して、他人の写真が動くAvatarifyを利用し、ひげを剃らなくてもweb会議に出席できるようにする。

#Avatarify
https://github.com/alievk/avatarify
README.mdに従うだけなので、あまり書くことはありません。

私はMacbook Pro 2019ユーザーですが、GTX1080Tiを積んだWindowsがあったので、そちらを用いました。
素直に Miniconda Python 3.7 を入れ、下記の通り実行しました。

`git clone https://github.com/alievk/avatarify.git`
`cd avatarify`
`scripts\install_windows.bat'`

>Download network weights and place vox-adv-cpk.pth.tar file in the avatarify directory (don't unpack it).
Run run_windows.bat. If installation was successful, two windows "cam" and "avatarify" will appear. Leave these windows open for the next installation steps. If there are multiple cameras (including virtual ones) in the system, you may need to select the correct one. Open scripts/settings_windows.bat and edit CAMID variable. CAMID is an index number of camera like 0, 1, 2, ...

私はカメラ1だったので、scripts/settings_windows.batのCAMIDを0から1にしました。
写真の切り替えは、起動後に数字の0~9で行います。

その後のOBSVCの話は[②VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜](https://qiita.com/tetsuyaimagawa/items/dd82e2a3bf10488457bf)
で扱った内容ですね。

私の環境だと、まだまだ改善が必要そうです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/avatarify?src=hash&amp;ref_src=twsrc%5Etfw">#avatarify</a> GTX 1080 Ti ですが、実用には耐え難い。私が平たい顔族だからですね分かります。カメラに近付くともっと乱れます。 <a href="https://t.co/sj0aMtWRzH">pic.twitter.com/sj0aMtWRzH</a></p>&mdash; 今川哲矢 (@TetsuyaImagawa) <a href="https://twitter.com/TetsuyaImagawa/status/1252532489538564096?ref_src=twsrc%5Etfw">April 21, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


Fake Newsが誰でも簡単に作れる未来が近そうですね…
iOSアプリのPassword AutoFillでユーザーとパスワードの入力画面を分けるには

[前回の投稿](https://qiita.com/temoki/items/023364f15dd8a56874b1)に引き続き、iOSアプリのPassword AutoFillに関する投稿です。

## 一般的なログイン画面の場合

一般的なログイン画面を作ろうとすると、ユーザー（メールアドレス等）とパスワードを入力するフィールドが並んだこんな画面になると思います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/33fbc228-dd0e-0c1e-45e7-4656028b6a3e.png" width=200>

この場合、ユーザーとパスワードの [UITextField](https://developer.apple.com/documentation/uikit/uitextfield) の [textContentType](https://developer.apple.com/documentation/uikit/uitextinputtraits/1649656-textcontenttype) をそれぞれ [.username](https://developer.apple.com/documentation/uikit/uitextcontenttype/2866088-username), [.password](https://developer.apple.com/documentation/uikit/uitextcontenttype/2865813-password) にしておきます。そうすることで Password AutoFill 機能により Keychain 等のパスワードマネージャーから自動入力できるようになります。

具体的には、キーボードの Quick Type バーのところから自動入力するログイン情報を選択するという操作を行います。この場合、ユーザーの方で自動入力が動作すると、同時にパスワードの方も入力されるような動作となります。

また、上記のとおり設定しておくと、パスワードマネージャーに保存されていない新規のユーザー/パスワードでログインした場合に、ログイン後の画面にログイン情報を保存するためのアクションシート（下図）が自動で表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/6e9dc83c-1bd6-fd30-4927-53e6740ecaa0.png" width=200>

## ユーザーとパスワードの入力画面を分けた時の問題点

デザインやログインの仕様の都合で、ユーザーとパスワードの入力画面を分けたい場合があります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/72c12d7f-b63f-0c77-8c29-4f865bcb54f0.png" width=200> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/e6dbbeb4-4b2a-adcc-eeb1-6a2718bcb5d7.png" width=200>


これを単純に実装すると、以下の２つの問題が起きてしまいます。

- ユーザー入力とパスワード入力のそれぞれの画面で自動入力の操作を行う必要がある
- 新規のユーザー/パスワードでログインした場合にログイン情報を保存するためのアクションシートが表示されない

## 問題点の回避策

結論から言うと、それぞれの画面にユーザー/パスワード両方の UITextField を配置しておくことで、これらの問題を回避できます。以下、画面ごとの詳細です。

### ユーザー入力画面

画面中にひっそりとパスワード入力の UITextField を見えないように忍ばせておきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/72c0aa58-5e02-86d1-a32a-46ca175e0a3d.png" width=200>

ただ、以下のような普通の方法で隠してしまうと、パスワード入力フィールドはいないものと見なされてしまうようで、ユーザーの自動入力をしても、パスワード入力フィールドにパスワードが自動入力されません。

- :x: `passwordField.isHidden = true` で隠す
- :x: `passwordField.alpha = 0` で隠す
- :x: `passwordField.isEnabled = false` でユーザー操作を無効化する

ということで私は次のように設定しました。

- :o: `passwordField.borderStyle = .none` で枠を見えないようにする
- :o: `passwordField.textColor = .clear` で自動入力されたパスワードを見えないようにする
- :o: `passwordField.isUserInteractionEnabled = false` でユーザー操作を無効化する

こうして自動入力されたパスワードを、次のパスワード入力画面に引き継ぐようにします。

### パスワード入力画面

ユーザー入力画面で自動入力されたパスワードを、パスワード入力画面に引き継げばパスワードの自動入力操作をするのを省略できます。

そして、この画面でもユーザー/パスワード両方の入力フィールドを用意します。この例では前の画面で入力されたユーザー情報を表示しているため、これを UILabel ではなく、`.username` タイプを指定した UITextField にしています。

- `usernameField.borderStyle = .none` で枠を見えないようにする
- `usernameField.isUserInteractionEnabled = false` でユーザー操作を無効化する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16508/c83d3245-b4a6-6cd3-0e33-3a6ce55f4dc1.png" width=200>

## 参考文献

- [Apple Developer / Password AutoFill](https://developer.apple.com/documentation/security/password_autofill)
- [WWDC2017 / Introducing Password AutoFill for Apps](https://developer.apple.com/videos/play/wwdc2017/206)
Ruby on Rails 〜同率順位も含めたランキング機能〜

今回はいいね順に投稿内容を表示する方法を書いていきたいと思います
#前提
いいね機能を実装していること

https://qiita.com/MitsuguSueyoshi/items/18fa5e49a27e727f00b4
こちらの記事を参照にランキング機能を実装していること

上に載せている記事のcontrolleの記述では３番目まで投稿されるようになっているので今回は同率順位をわかりやすく表示するためにlimitの値を7にします

変数の値は自分のプロダクトに添って変更しました(ご了承ください🙇‍♂️)
#はじめに

まず`<% @all_ranks.each.with_index(1) do |ranking, i| %>`
この記述によってそれぞれのいいねされた投稿内容がいいね順に並びます。`<%= ranking.body %>`などにしてみるといいねが多い順に投稿されることが分かりますか？ですがいいねが同数の場合は先に投稿された内容が上の順位に来てしまいます。
今回はそこ順位を同率にしていきます！


|i   |    ranking.body|
|:---|---------------:|
|1   |１番いいねされた投稿|
|2|２番目にいいねされた投稿|
|3|３番目にいいねされた投稿|
|4|４番目にいいねされた投稿|
|5|５番目にいいねされた投稿|
|6|6番目にいいねされた投稿|
|7|7番目にいいねされた投稿|

#概要


```erb:index.html.erb
  <% lastFavorite = 0 %>
  <% j = 1 %>
 <% @all_ranks.each.with_index(1) do |ranking, i| %>
   <% if i == 1 %>
     <% lastFavorite = ranking.favorites.count %>
   <% end %>
   <% if ranking.favorites.count != lastFavorite %>
     <% j = i %>
     第<%= j %>位
     <%= ranking.body %>
     いいね数：<%= ranking.favorites.count %>
     <% lastFavorite = ranking.favorites.count %>
   <% else %>
     <% lastFavorite = ranking.favorites.count %>
     第<%= j %>位
     <%= ranking.body %>
     いいね数：<%= ranking.favorites.count %>
    <% end %>
  <br>
 <% end %>
```

#同率を考えるために
前のいいね数と今のいいね数を比べることで同率かそうでないかわかります。そのために前のいいね数を一時的に保存できる変数lastFavoriteを作ります。ちなみに変数名はなんでも構いません
次に順位を示す変数を決めてあげます。私はjにしました!!
###4~6行目　
```erb:
<% if i == 1 %>
  <% lastFavorite = ranking.favorites.count %>
<% end %>
```

一番初めのいいね数を考えたときにその１つ前のいいね数の値はないのでそこに値を仮に入れておくためにその一つ前だけ今のいいね数にする
###7~13行目
```erb:
<% if ranking.favorites.count != lastFavorite %>
  <% j = i %>
  第<%= j %>位
  <%= ranking.body %>
  いいね数：<%= ranking.favorites.count %>
  <% lastFavorite = ranking.favorites.count %> 
<% else %>
```
もし前のいいね数と今のいいね数が違うなら順位が変わったことを指すので変数jにiの値を入れます

その時のいいねがついている内容を表示して
最後に今のいいね数は次のいいね数と比べるためにに前のいいね数にします
###14~19行目
```erb:
<% lastFavorite = ranking.favorites.count %>
  第<%= j %>位
  <%= ranking.body %>
  いいね数：<%= ranking.favorites.count %>
<% end %>
```
もし前のいいね数と今のいいね数が同じなら同率の順位を示すのでjの値は変えずに普通に表示させてあげますですがこの後にも次のいいね数と比べるため前のいいね数に今のいいね数を代入してあげます

以上で同率順位の完成です！


コードの内容をみれば言いたいことを理解してくれる人もいるだろうと思い今回記事にしてみました
ご視聴ありがとうございます
CSSのまとめ

````
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="hoge/style.css">
    <title>Document</title>
</head>
<body style="margin: 0">
    <!--ノーマルスタイル、ボックススタイルの説明用 
        
        <div class="normal">ノーマルスタイル</div>
    <div class="box">ボックススタイル</div>

    <div class="margin">マージン相殺の説明用ブロック</div> -->

    <div>私はブロックです</div>
    <div>私はブロックです</div>
    <div>私はブロックです</div>
    <div>私はブロックです</div>
    <hr>
    <span>私はインラインです</span>
    <span>私はインラインです</span>
    <span>私はインラインです</span>
    <span>私はインラインです</span>

    <div class="exmple">ブロックは改行して他の要素を邪魔しない！
        ブロック内の<span>インラインです</span>インラインの場合にはマージン、パディング、ボーダーがきたときに他の要素の事は虫します</div>

</body>
</html>

/* h1::after{
    content: "!!!!!!!!!";
}

h1::before{
    content: "!!!!!!!!!";
}



article h1~p{
color: springgreen
;}


p::first-letter{
    color: red;
} 

カスケードは優先順位　基本はあとがち
詳細度、タグ　クラス　ID　優先順位が左程高いが違う
*/




/* .a {
    color:palevioletred !important;
}

#title{
    color: chocolate;
}

h1{
    color: red;
}

h1{
    color: black;
} */


/* 継承
li{
    color: red;
} 

li [href*="yahoo2"]{
    color: inherit;
}

li [href*="yahoo3"]{
    color: initial;
}

li [href*="yahoo4"]{
    color: unset;
} */

/* div{
    background-color: orange;
    border: 3px solid black;
}

.fix{
    all: unset;
} */




 .box{
    background-color: blanchedalmond;
    /*content box*/
    width: 200px;
    height: 200px;
    /*padding box top L bottm R*/
    padding:8px 12px 16px 20px;

    /*margin box top L bottm R*/
    margin:8px 12px 16px 20px;
    /* margin-bottom: 20px; */

    /* ボーダーボックス */
    border-top:10px solid black;

    /*paddingとボーダーを抜いて、実際のwihit200を166にしている！　直観的（すべてに対して使うときもある*/
    box-sizing: border-box;
} 

/*
.normal{
    background-color: red;

}

*/

/*マージン相殺 .margin{
    background-color:black;
    margin-top: 40px;
} */


/* div, span{
    background-color: orange;
    width: 100px;
    height: 100px;
} */

.exmple{
    /* display:inline; 　インラインをblockに変更することも出来る*/
    background-color: pink;
    padding: 20px;
}


.exmple span{
    display: inline-block;/* 改行されず他を邪魔しない、上書きしないで改行せずまわりをじゃましない*/
    margin: 20px;
    border: 1px solid black;
    padding: 20px;
    background-color: lightblue;
}
Railsチュートリアル備忘録　-Heroku編-

## Herokuをセットアップする
HerokuではPostgreSQLデータベースを使うため、本番環境にpg　gemをインストールする必要がある。
### SQLiteの設定
HerokuではSQLiteがサポートされていないため、sqlite3 gemが本番環境に導入されないようにしておく

```
group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end
```

### pg gemを本番環境に入れておく
```
group :production do
  gem 'pg', '0.20.0'
end
```
### クラウドIDE上でHerokuをインストールする
```
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
```
### ローカル環境では本番用のgemをインストールしない
＊この理由については調査する

```
bundle install --without production
```
### Herokuがインストールされているかどうか確認する
```
heroku --version
```
### Herokuへのログイン
```
heroku login --interactive
```
### Herokuへの公開鍵追加
```
heroku keys:add
```
### Herokuにアプリーケーションの作成
```
heroku create
```
## Herokuへのデプロイ
```
$ git push heroku ブランチ名
例　$ git push heroku master
```
## デプロイしたアプリ名の変更
```
heroku rename app名
```
## データベース動作
```
heroku run rails db:migrate
```
## 本番サイトでメンテナンスを行う場合
```
heroku maintenance:on
```
```
heroku maintenance:off
```
Spark AR Studioで、他人の顔を自分の顔に被せてWeb会議に出席する

#Zoom Hacking連載
[①FaceRig/SnapCamera+VT-4で参加したZoomをOBS経由でRTMP配信するまで](https://qiita.com/tetsuyaimagawa/items/86b843430011744a0602)
[②VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜](https://qiita.com/tetsuyaimagawa/items/dd82e2a3bf10488457bf)
[③Zoomで小技を出しつつも、こいつオタクなのかな？と思われたくない iVCam+DroidCamをOBS VCから流す方法](https://qiita.com/tetsuyaimagawa/items/d63db39dc42b466aa8ad)
[④Spark AR Studioで、他人の顔を自分の顔に被せてWeb会議に出席する]  (https://qiita.com/tetsuyaimagawa/items/dbdfe855756e3405c162)
[⑤Avatarifyで他人の顔を乗っ取り、web会議に出席する。] (https://qiita.com/tetsuyaimagawa/items/8f180216712595071878)

#概要
昨今、Zoomを始めとするWeb会議システムの利用が増えており、それに関わる技術にも注目が集まっている
今回は、他人の顔の3Dモデルを、自分の顔に被せて会議に出席する方法を扱う。

#Spark AR Studio
https://sparkar.facebook.com/ar-studio/download/
Downloadボタンを押します。インストールします。

Create NewでFace Decoration(メガネ)を選びます。
<img width="1070" alt="Screen Shot 2020-04-24 at 17.49.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/f066527f-9484-93b7-2401-45e53b71695b.png">

<img width="1276" alt="Screen Shot 2020-04-24 at 17.50.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/4fc925a0-ad37-2220-65ae-fc793c11a664.png">
こんな画面が出てくるので、FileからImport From Computer...を選び（後述する）3d objファイルを選択します。
ImportしたobjをdragHereのところにdragするだけでほぼ完成です。

<img width="262" alt="Screen Shot 2020-04-24 at 17.51.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/cea5456f-604f-1402-cfe4-1f856703563e.png">

#3Dモデルを持ってくる
objをはじめとする3dモデルファイルなら何でもよいのですが、sketchfabからbellus3dさんの[サンプル](https://sketchfab.com/3d-models/full-head-example-a5f8f0622c4946dcacf7f6f43405814c)を持ってきました。
前述のdragHereをしたら、右端のTransformationsで大きさを調整します。
<img width="274" alt="Screen Shot 2020-04-24 at 17.59.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/cdf87f6c-d25d-3836-ad58-1ae16988093b.png">




#OBSに表示する画面
OBS及びOBSVCについては過去記事ご覧ください。
CameraをBuilt-inかUSB webカメ等にすると、自分の顔にobjが上乗せされたstreaming動画が出てくるので、それをOBSで流します。
<img width="270" alt="Screen Shot 2020-04-24 at 17.54.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/f0fd67fb-eeb9-78bd-98fb-8e5fe9167c5a.png">

こんな感じになります。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">AvatarifyでZoomはまだ改善が必要ですが、人面3D objなら全然いけますね。ポーカーフェイスが要される商談でご利用ください。 <a href="https://t.co/NGZ7o3Ip3a">pic.twitter.com/NGZ7o3Ip3a</a></p>&mdash; 今川哲矢 (@TetsuyaImagawa) <a href="https://twitter.com/TetsuyaImagawa/status/1253531170635014154?ref_src=twsrc%5Etfw">April 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

応用で、静止画も、planeにmaterialを貼り付けるだけでできます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ビデオ会議が恥ずかしいので、自分の顔写真を貼り付けました。 <a href="https://t.co/D0gRPqSqmF">pic.twitter.com/D0gRPqSqmF</a></p>&mdash; 今川哲矢 (@TetsuyaImagawa) <a href="https://twitter.com/TetsuyaImagawa/status/1252891801947496449?ref_src=twsrc%5Etfw">April 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

口が動かないですが、とても簡単なのでぜひお試しください。
コマンドを簡略化したい

最近コマンドの抽象化・簡略化について色々と学ぶ機会があったのでそれについて書いていきます。

## きっかけ

同じチームの人とペアで作業している時に、その人がごく短いコマンドを実行したら

- 特定の作業ディレクトリで VSCode が起動
- ファイル名に今日の日付の入った markdown 形式のファイルが生成される

といったことが実現されており、サッとメモを取りたい時にすぐに VSCode が起動できる状態になっていることに気づき、ちょっと真似したくなったのでやってみました。

## 実装してみる

上記のことを実行したければ、それらのコマンドをまとめてシェルスクリプトにしてコマンドラインから実行できるようにすればいいので稚拙ながら書いてみたシェルスクリプトがこちら。

```shell:markdown.sh
#!/bin/sh

cd ~/Documents/markdown
if [ ! -d ./`date '+%Y%m'` ]; then
    mkdir `date '+%Y%m'`
fi
code ./`date '+%Y%m'` `date '+%m%d.md'`
```

単純に `cd` で作業ディレクトリに移動して、今月のディレクトリが存在していなければ作成して、今日の日付の markdown ファイルをオープンしています。
で、このシェルスクリプトに実行権限を付与し、 `~/.zshrc` に alias を追加すればいい感じに。

```shell
chmod 755 markdown.sh
```

`md` というコマンドを実行すれば上記のシェルスクリプトが実行されるようにしてみます。

```shell
alias md='sh ~/markdown.sh'
```

設定を反映

```shell
source ~/.zshrc
```

この状態で実際に `md` と実行してみると、以下のように今月のディレクトリの中で今日の日付のファイルが生成された状態で VSCode が起動しました。

![スクリーンショット 2020-04-24 16.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73844/62493d23-16ef-0636-57cc-11d8d9137905.png)

## 応用

これだけだと味気ないのでもう 1 つ具体例を。
例えば、業務で扱う AWS アカウントが複数あったりして Profile をその都度切り替えなければならないケースは結構あると思います。
S3 にファイルをコピーする場合、

```shell
aws s3 cp {file_path} s3://{bucket_name}/
```

のようなコマンドを実行します。
このコマンドの場合、オプションで Profile の指定を行っていないので実行環境でセットされているデフォルトの AWS アカウントのキーが使用されます。
デフォルトとは別の Profile を使う場合は

```shell
aws s3 cp {file_path} s3://{bucket_name}/ --profile {profile_name}
```

のように `--profile` オプションで対象の Profile を指定します。
この場合はそこまでコマンドが複雑じゃないのでそのまま書いて実行してしまえばいいですが、無理やりコマンド化してみます。

```shell
#!/bin/sh
function s3cp () {
    aws s3 cp ~/test_data/test.txt s3://sample_bucke_name/ --profile $1
}
```

引数に実行する AWS アカウントの Profile を指定する `s3cp` という関数を作りました。
これを `.zshrc` などに記述すると実行できるようになります。

この状態で

```shell
s3cp sample_profile
```

と実行すると、実際には

```shell
aws s3 cp ./test.txt s3://sample_bucket_name/ --profile sample_profile
```

というコマンドが実行され、 `sample_bucket_name` に `~/test_data/test.txt` がコピーされます。
ちょっと例があんまりよくなかった気もしますが、実行するコマンドの長さを比べるとだいぶスッキリしたと思います。

複雑なコマンドだったり、頻繁に実行するコマンドはこのような形で抽象化することができればコマンド実行時の typo や「このコマンドのオプション何だっけ…」と毎回 help を確認する手間が少しでも省けると思います。

## まとめ

今回、冒頭で述べた出来事がきっかけでコマンドの抽象化、簡略化について興味が湧いたのでごく簡単な内容ですがやってみました。
特に markdown の方は作業ログを付けながらやるときには大変便利になりました。

抽象化することで複雑なコマンドをいちいち書かなくてもよくなってコマンドを間違えるリスクも減りますし、誰が実行しても同じコマンドが実行されるようになるのでメリットも多いと思います。
【mysql】int型に空文字を入れると・・・

# 小ネタです
下記のようなテーブルに、空文字（''）をINSERTするとどうなるでしょうか？
※名前とかは適当につけました。ご了承ください。

```sql
create table int_test(
id bigint(20) DEFAULT NULL,
test_id int(11) DEFAULT NULL,
name varchar(255) DEFAULT NULL);
```

私、最初は`NULL`が入ると思ってました。
だって、`DEFAULT NULL`だし。。。

## ところが・・・
実際に空文字をINSERTしてみました。

```bash
mysql> insert into int_test (id, test_id, name)
     > values (1, 1, 'aaa'), ('', '', '');
Query OK, 2 rows affected, 2 warnings (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 2

mysql> select * from int_test;
+------+---------+------+
| id   | test_id | name |
+------+---------+------+
|    1 |       1 | aaa  |
|    0 |       0 |      |
+------+---------+------+
2 rows in set (0.00 sec)
```

なんと、0が入ってしまいました！
次から気をつけます。
~~バグを生んでしまったので懺悔のQiita投稿でした~~
UnionFindをPythonでサイズ（要素数）を取得する


しいです。自分向けノート第二弾

前回Union-Findの最低限の実装を書いて、これでUnionFindは無双できる！と思った矢先

ABC157 D-Friend Suggestion

https://atcoder.jp/contests/abc157/tasks/abc157_d


AtCoderさんのこの問題にボコされてしまいました。

サイズ（要素数）を取得する実装が出来てないのが原因ですね。実装し直しましょう。

## 実装コード

```python

    N,Q = map(int,input().split())
    par = [-1]*(N+1)
    def find(x):
        if par[x] < 0:
            return x
        else:
            par[x] = find(par[x]) #経路圧縮
            return par[x]
    def same(x,y):
        return find(x) == find(y)
    def unite(x,y):
        x = find(x)
        y = find(y)
        if x == y:
            return 0
        else:
          if par[x] > par[y]:
            x,y = y,x
            par[x] += par[y]
            par[y] = x
    def size(x):
        return -par[find(x)]
```

これが改定後のものです。



## 初期化
```python
    par = [-1]*(N+1)
```

注目すべきなのは最初の初期値をすべて−１とおいて管理していることです。

自分が親である場合負であるか否かで判断しています。

##結合（unite）

```python
    def unite(x,y):
        x = find(x)
        y = find(y)
        if x == y:
            return 0
        else:
          if par[x] > par[y]:
            x,y = y,x
            par[x] += par[y]
            par[y] = x
```

結合するときに両方の親の負の和を取ることです。

そうすることによってparの子の要素には親のノードの番号が入り

parの親の要素には木のサイズ（要素数）を負の値で保持することが出来ます。

### 例

![](https://paper-attachments.dropbox.com/s_B706646F2E46570F54A5D60103D61BE06DB92F5338A0C4EFED3C90340C127F72_1587718108520_image.png)


例えば、この画像だと[ -5 , 0,  0 , 0 , 0 ]　になります。

##size

これでsizeの関数の返り値の部分にマイナス’ー’がついてる理由が明らかですね！

```python
    def size(x):
        return -par[find(x)]
```

##まとめ

サイズを取得するだけなのにreturn の前にマイナスが現れたりと最初はびっくりしますが理解しちゃうとすごいわかりやすかった。

今度こそはUnionFind無双できるはず！
突然 AWS ECS / AWS Batch でジョブの実行に失敗するようになった件

# 状況
* 2020/4/24 約6:00(?)以降、突然 AWS ECS / AWS Batch でジョブの実行に失敗するようになった。（AWS Batchのステータス`RUNNABLE`で停止してしまっていた。）
* コンピューティング環境はEC2インスタンスを利用（非Fargate）
* 当日のAM3:00頃まではジョブが正常に稼働していたことを確認済み。
* 実行するdocker image、ジョブ定義などには一切変更を加えておらず、全くもって原因不明でした。しばらくハマったので、対処方法を記録しておきます。どなたかの手助けになれば幸いです。

# 結論（原因）
* AWS ECS / Batch 上でコンテナの死活管理などを司る`Amazon ECS コンテナエージェント`のコンテナが起動に失敗しており、EC2インスタンスを正常にコンピューティング環境のリソースとして認識できていなかったのが原因。
* 突然この時間から起動に失敗するようになった原因は不明だが、おそらくバージョンが古すぎたことが要因。`1.17.0`を利用していた。
* コンピューティング環境内のEC2インスタンスが0台となってしまっており、結果的にジョブが実行できず、ジョブが`RUNNABLE`で停滞していた。

# 対処方法
* `Amazon ECS コンテナエージェントバージョン`をバージョンアップすることで、正常にコンテナエージェントが起動してジョブが実行されることを確認した。
* バージョンアップのやり方にはいくつかの方法があるが、今回はコンピューティング環境で利用しているAMIを更新することで対応した。
* AWS Batchの場合はコンピューティング環境作成時点の最新のAMIが常に使われ続ける仕様であるため、コンピューティング環境自体を再作成した。

## 更新前後のAMIの情報など
* 詳細は以下の公式ドキュメントを参照
* https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-versions.html

#### 更新前に利用していたEC2インスタンスの情報
* AMI ID
  * ami-e3166185
* リリース
  * 2017.09.h
* Amazon ECS コンテナエージェントバージョン
  * 1.17.0
* ecs-initバージョン
  * 1.17.0-2

#### 更新後のEC2インスタンスの情報
* AMI ID
  * ami-031cb62cff0e27519
* リリース
  * 2018.03.20200402
* Amazon ECS コンテナエージェントバージョン
  * 1.39.0
* ecs-initバージョン
  * 1.39.0-1

# 調査時のログ

* ecs agentのコンテナが起動に失敗しており、リスタートしてもエラーになってしまった。

```bash
| [ec2-user@ip-XXX ~]$ docker container ls -a |
| CONTAINER ID        IMAGE                            COMMAND             CREATED             STATUS              PORTS               NAMES |
| dc4b71e9133b        amazon/amazon-ecs-agent:latest   "/agent"            4 hours ago         Created                                 ecs-agent |
| [ec2-user@ip-XXX ~]$ docker ps |
| CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES |
| # ecs agentの起動に失敗している |
| [ec2-user@ip-XXX ~]$ docker container start dc4 |
| Error response from daemon: OCI runtime create failed: container_linux.go:349: starting container process caused "exec: \"/sbin/docker-init\": stat /sbin/docker-init: no such file or directory": unknown |
| Error: failed to start containers: dc4 |
```

* 上記を確認後、原因の切り分けとして、起動中のAWS Batchインスタンスを「同様のものを起動」から複製起動した。
  * その際にAMIを最新版に更新
  * この手順を踏むことで、ジョブが正常に実行されることを確認
Python 競プロ　メモ書き

# Pythonメモ
これは自分用の競プロ用メモです


###小数点切り下げ
```python:floor
import math
num=1.234
print(math.floor(num))
```

結果　
１

###入力をリスト化
```python:input_list
a=list(map(int,input().split()))
```

###リストをprint

```python:list
a=[1,2,3,4]
a=[str(i) for i in a]
L=' '.join(a)
print(L)
```

もともとstr型の場合３行目から

```python:list
a=[1,2,3,4]
print(*a)
```



###絶対値を求める

```python:abs
a=5
b=7
c=a-b
print(abs(c))
```

結果
2




今後も勉強の過程で調べたことをメモ書きしていきます
Zoomで小技を出しつつも、こいつオタクなのかな？と思われたくない iVCam+DroidCamをOBS VCから流す方法

#Zoom Hacking連載
[①FaceRig/SnapCamera+VT-4で参加したZoomをOBS経由でRTMP配信するまで](https://qiita.com/tetsuyaimagawa/items/86b843430011744a0602)
[②VMCをOBS VCでZoom〜バ美声をVACしたものを添えて〜](https://qiita.com/tetsuyaimagawa/items/dd82e2a3bf10488457bf)
[③Zoomで小技を出しつつも、こいつオタクなのかな？と思われたくない iVCam+DroidCamをOBS VCから流す方法](https://qiita.com/tetsuyaimagawa/items/d63db39dc42b466aa8ad)
[④Spark AR Studioで、他人の顔を自分の顔に被せてWeb会議に出席する]  (https://qiita.com/tetsuyaimagawa/items/dbdfe855756e3405c162)
[⑤Avatarifyで他人の顔を乗っ取り、web会議に出席する] (https://qiita.com/tetsuyaimagawa/items/8f180216712595071878)

#背景と概要
昨今、Zoomを始めとするWeb会議システムの利用が増えており、それに関わる技術にも注目が集まっている。
あまり技術に走りすぎると、VRMアバターやバ美声の利用などでサブカル色が強くなり、時には業務に支障をきたすことになりかねない。
そこで、今回はあえてオタ認定リスクをヘッジする形で、スマートに変なことをしたいと思う。

#もちもの
iOS端末、Android端末、OBSの入ったPC

#iVCam
iOSをWebCameraとして使うアプリ。
https://www.e2esoft.com/ivcam/
iOS, PCそれぞれにアプリを入れる。

一台のPCに対し、複数iOSが利用可能。
>Then find the driver_install.bat file in the iVCam installation folder (for example: C:\Program Files\e2eSoft\iVCam) and run it, adding an iVCam driver each time you run it.
https://www.e2esoft.com/ivcam-multi-instance/

#DroidCam
AndroidでもiVCam使えるらしいので、不要ですが、せっかくなのでAndroid専用アプリ使ってみました。
こちらもAndroid, PCそれぞれにアプリを入れます。

Android App
https://play.google.com/store/apps/details?id=com.dev47apps.droidcam&hl=ja
Windows
https://www.dev47apps.com/droidcam/windows/

#OBS
https://obsproject.com/ja
おなじみのOBSを用います。
Video Capture DeviceにiVCam/DroidCamが出てくるので、表示して並べます。

<img width="1466" alt="obs_multi_cameras.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142638/14a57ac9-8aeb-61e8-b546-b5f43b4bd888.png">

とりあえず並べましたが、かっこいい配置で固定すると、かっこいい感じになります。
前回記事同様、OBS Virtual CameraでZoom等に出力します。


これでゆめにもオタクだとは思われないでしょう。
Cloud Functions 「HTTP のチュートリアル」でPermission denied on 'locations/asia-northeast1-a' (or it may not exist)のエラー

[Cloud Functions 「HTTP のチュートリアル」](https://cloud.google.com/functions/docs/tutorials/http)をやってた時に詰まったのでメモ



## 実行内容
デプロイをしようとした時に下記コマンドを実行した

```
gcloud functions deploy helloGET --runtime nodejs8 --trigger-http --allow-unauthenticated
```

## エラー内容
```
ERROR: (gcloud.functions.deploy) ResponseError: status=[403], code=[Forbidden], message=[Permission denied on 'locations/asia-northeast1-a' (or it may not exist)]
```

## 対策
参考資料によるとregionの指定が間違っている(?)らしいので、regionを明記するようにした

```
gcloud functions deploy helloGET --runtime nodejs8 --trigger-http --allow-unauthenticated --region asia-northeast1
```

デプロイできた


## 参考資料

https://blog.n-t.jp/cloudrun-error-permission-denied/
AWS Lambda「スロットリング」からの復活方法

# 再帰的にLambdaを起動するプログラムを作ってしまった
S3バケットでのオブジェクト作成イベントをトリガーに実行するLambdaを作ったのだが、結果格納先を同じS3バケットにしてしまったため、無限にLambdaが起動してしまう状態になった。
# 緊急対応策
マネジメントコンソールのLambdaの画面上部に[スロットリング]というボタンがある。これを押すことで、とりあえず実行中のLambdaは停止する。
#スロットリング状態から復旧する方法
**Lambdaの「同時実行数」を変更すればよい。**
スロットリングボタンは、Lambdaの同時実行数をゼロにする。
同時実行数はマネジメントコンソールから変更できる。
Lambdaの初期状態である「予約されていないアカウントの同時実行の使用」に変更してもいいし、同時実行数に正の数を入れてもいい。「保存」ボタンを押すのを忘れずに。
# さいごに
ググったもののすぐには分からず、パニクった状態でAWSサポートに聞いてしまいました。丁寧に回答していただき感謝しています。ありがとうございました。
Flutter アプリからLineを起動

Flutterのプラグイン[url_launcher](https://pub.dev/packages/url_launcher) を使用してSMSを起動したり電話をかけたりする方法は結構お見かけするのですがLINEがなかったので備忘録として残しておきます。

## 環境

### 1.プラグインのインストール
プラグインのインストールです。pubspec.yamlを編集します。執筆時点で最新のバージョンを指定しています。

```yml
name: 
description: 
　　~省略~

dependencies:
  flutter:
    sdk: flutter
    url_launcher: ^5.4.1

dev_dependencies:
  flutter_test:
    sdk: flutter
```

### 2.コード

```dart
class Sample extends StatefulWidget {
  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {

  @override
  void initState() {
    super.initState();
  }

  final linePath = "https://line.me/R/msg/text/?";


  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('サンプル画面'),
          backgroundColor: Colors.white,
        ),
        body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[
            RaisedButton(
              child: Text("Line"),
              color: Colors.green,
              shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
              ),
              onPressed: () {
                sendLine(linePath);
              },
            ),
          ],
        ),
      ),
    );
  }
  void _sendLine(String path) async {
    var _status = 'Ready';
    if (await canLaunch(path)) {
      await launch(path);
    } else {
      setState(() {
        print('Chat','Unable to launch url $path');
      });
    }
  }
}

```

## 参考文献
[LINE URLスキームを使う](https://developers.line.biz/ja/docs/line-login/using-line-url-scheme/#%E5%8B%95%E4%BD%9C%E7%92%B0%E5%A2%83)
[URL でプログラムを起動する方法](https://flutter.keicode.com/basics/urllauncher.php)
Railsチュートリアル備忘録　-Git編-

## 初めに
railsチュートリアルに出現するGitの使い方に関する備忘録
## 新たなブランチを作成
```
$ git checkout -b modify-README
```
## 変更を一括でコミット
```
$ git commit -a -m "コミットメッセージ"
```
## マージ
### ブランチの切り替え
```
$ git checkout master
```
### マージの実行
```
$ git merge トピックブランチ名
```
### トピックブランチの消去（しなくてもいい）
```
$ git branch -d トピックブランチ名
```
## push
```
$ git push リポジトリ ブランチ名
例　git push origin master
* git pushのみでも大丈夫な場合が多い
```
JavaScriptの条件分岐を簡単に理解する方法

# 条件分岐って何？
rubyでいうところのif文です。JSでもその概念はあります。
普通ならサンプルコードみたいなのを見せられて
はい、終わりだと思うのですが、
簡単に理解するために細々としたところまで見ていきたいと思います。

# JSで条件分岐を書くために（前提条件）
以下、２つのファイルを用意。
:page_facing_up:index.html
:page_facing_up:script.js
今回もconsole.log()を用いてどのような結果になるのか検証していきます。
**console.log()って何？って思った人は事前にこの記事を読んでください。**
[JavaScriptでのconsole使用方法](https://qiita.com/Nyanmaru-12/items/fc430a1ee28c26901e91)

# Rubyと違うところ
もちろん、rubyとはいくつか違う箇所があります。
それを先に抑えてしまいましょう。
以下４つです。
①条件式は（）でくくる。
②処理の内容は{}でくくる。
③endはいらない
④elsifではなく、else ifと記述すること。

# 実際に書いてみる
script.jsに、以下の記述をします。

```javascript
let num = 100;

if (num % 5 ==0){
  console.log(num + "は５の倍数です。")
} else if (num % 3 ==0){
  console.log(num+ "は３の倍数です。")
} else {
  console.log(num + "は３の倍数でも５の倍数でもありません。")
}
```
%や ==についてはrubyを触れた方ならわかると思います。
index.htmlをブラウザで開き、検証ツールを使ってコンソールを見てみると以下のようになってます。
<img width="1035" alt="9DA28B68-C95B-40E9-9176-53D4D30F11D0_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/1f416e4b-c13c-dfba-aacd-8374cb3088b6.jpeg">
当たり前ですが、100の数字をいじると、結果は変わってきます。
コンソールって本当に便利です。
rubyとの違いだけは注意ですね。
vim-goでlinter実行時に"cannot import absolute path"

## 問い
vim-goで.vimrcに`let g:go_metalinter_autosave = 1`と設定していると保存時に自動でlinterを実行してくれるが、ここで次のようなエラーが出た。

```text
Can't run linter goanalysis_metalinter: asmdecl: analysis skipped: errors in package: [-: import \"/absolute/path/to/project\": cannot import absolute path]
```

## 答え
`GOPATH`にないプロジェクトをimportできないことが原因だった。次を実行して解決。

```
go mod init github.com/name/project
```
C/C++のフォーマット指定子『%[^\n]』とは？？ その3: 応用編(最後)

※これは<a href="https://qiita.com/Sankyuri/items/c7fb52658c45b8757b5c" target="_blank"><code><b><font color="red">これ</font></b></code></a>の続きの続きです。先にこれを読んでおいた方が<b>絶対</b>良いです。
※因みにこれの前回は<a href="https://qiita.com/Sankyuri/items/10b1ab4aac35751602cd" target="_blank"><code><b><font color="red">これ</font></b></code></a>です

#本題は<code>fscanf()</code>で読み込む事

(; ･`д･´)はっ！<sub>…もう<b>満足して本題を忘れかけてました</b>。危ない危ない…。</sub>


今回この様なテキストファイル(.txt)を作ってみました

``` text:test用.txt
Kenji^Hello, world and Mami!

```
パラメータ<code>Kenji</code>と値<code>Hello, world and Mami!</code>が記述されたファイルです。
何だかノベルゲームのスクリプトの様ですが、区切り文字が<code>^</code>になっていて見慣れない感じですね。

``` c:main.c
//プリプロセッサは省略
int main(void) {
	FILE *fp;
	char str[2][64] = { { '\0' } };
	fp = fopen("./test用.txt", "r");
	fscanf(fp, "%[^^]%[^\n]", str[0], str[1]); //読み込み
	fclose(fp);
	printf("%s says \"%s\"\n", str[0], str[1]); //出力
	system("pause");
}
```
``` result:実行結果
Kenji says "^Hello, world and Mami!"
続行するには何かキーを押してください . . .
```
おっ出来……<b>ん？？？？？</b>
<code>^</code>が文章に含まれてしまいました。うーんこの…。

<p>
それもその筈。
<ol>
  <li><code>head</code>から<code>^</code><b>の直前</b>迄を読み込む</li>
  <li><code>^</code>から<code>\n</code>迄を読み込む</li>
</ol>
という風に処理された結果、当然 2 の先頭の<code>^</code>も格納されます。
<br><br>
</p>
ではどうすれば回避できるでしょうか？少し考えてみて下さい。

###区切り文字が読み込まれるバグを修正
分かりましたか？　…そうですね。

例えば、標準入力から<code>sage, true</code><sub>(ただし値はchar*)</sub>という様に入力する場合は

``` c:例.c
    scanf("%s, %s", str1, str2);
```
という風に記述すると思います。
そうです。<code>%[^\n]</code>についても同じ事がいえます。

``` c:'^'が読み捨てられるmain.c
	fscanf(fp, "%[^^]^%[^\n]", str[0], str[1]); //読み込み
```
``` result:実行結果
Kenji says "Hello, world and Mami!"
続行するには何かキーを押してください . . .
```
ちゃんと<code>^</code>が読み捨てられました。
皆は分かったかな？


###僕がやりたいのはスクリプトの読み込みだから……
今度は複数行が読み込まれるようにしました。

``` c:'^'が読み捨てられるmain.c
int main(void) {
	FILE *fp;
	char str[2][64] = { { '\0' } };
	fp = fopen("./test用.txt", "r");
	while (1) {
		fscanf(fp, "%[^^]^ %[^\n]\n", str[0], str[1]); //読み込み
		if ('0' == str[0][0] &&  '0' == str[1][0]) { //終了チェック
			break;
		}
		printf("%s says \"%s\"\n", str[0], str[1]); //出力
	}
	fclose(fp);
	system("pause");
}
```
``` text:test用.txt
KenjiEX ^ Hello, world and Mami!
song1   ^ Shades of Light in a Transcendent Realm
song10  ^ world.execute(me);
0^0

```
テキストファイルには曲名を追加してみました(「～ says ...」と出力されるけど)。
え？どっかで見たことある曲名だって？偶然だよ偶然、あはは…。

``` result:実行結果
KenjiEX  says "Hello, world and Mami!"
song1    says "Shades of Light in a Transcendent Realm"
song10   says "world.execute(me);"
続行するには何かキーを押してください . . .
```
<b>な　ん　と　い　う　こ　と　で　し　ょ　う<sub>(BGM:TAKUMI／匠 / 松谷 卓)</sub></b>
誰かさんがインデントした所為で、パラメータが<code>^</code>の直前のスペース迄読み込まれているではありませんか(<b>バグ</b>)。

…まあ、パラメータは普通は綴りに空白なんて入れないので、これへの対応は難しくは無いでしょう。

##結局
``` c:これでいいや…….c
    scanf("%s %[^\n]\n", str[0], str[1]);
```
この様に、<code>^</code>みたいな区切り文字は無くし、半角空白で区切る事にしました。
読み込み方法を、パラメータは其の儘に、値を<b>改行文字迄</b>にしたので区切り用の記号が必要無くなったのです。


#まとめ
<b>フォーマット指定子<code>%[...]</code>は使い辛い！</b>以上！

<hr>

<font color="silver">
<sup>あっやめて四角括弧ちゃん！ごめんって！僕が悪かったから！うわなにをするやめｒくぁｗせｄｒｆｔｇｙふじこｌｐ</sup>
</font>













<br><br><br><br><br><br><br>
GraphQLとは (概要)


# Graph QLとは
- 単なる仕様群
    - プラットフォームや技術に依存せず利用できる
- REST APIの課題を解決すべく開発された

# Graph QLのメリット

### 1回の通信で、必要なデータのみ取得できる
    - 不要なデータの削減
    - 通信回数の削減
        - ユーザ体験が良くなり、売上に繋がる

    上記の点でREST APIから乗り換えられている


## 例

### 要求したデータのみ取得
    - user_id:5
        - name
        - birthday

### 関連オブジェクトも取得可能
    - user_id:5
        - name
        - birthday
        - Orders
            - order
                - product_name
            - order
                - product_name

# 解決できるREST APIの課題

###  1. 不要データの取得を抑えられる
    - user_id:5
        - user_name
        - password
        - mail_address
        - created
        - updated
          etc...

### 2. 何回も問い合わせる必要がなくなる
- user_idの注文情報を取得 → 商品毎に商品名を問い合わせ


# 採用事例
- Facebook
- Twitter
- Github
- New York Times
- IBM
- Yelp
吉里吉里Z+KAG3でH.264(mp4)のムービーを再生したい。

#吉里吉里Z+KAG3でH.264(mp4)のムービーを再生したい。

吉里吉里ZはH.264(mp4)をサポートしている。
しかしKAG3を利用すると、再生することができない。
かといって、AVIやWMVファイルでエンコードするとファイルが大きくなり画質の低下を招いてしまう。
このような理由から、KAG3でH.264(mp4)ムービーを再生できないか試してみた。

<font color="Red">
※手探りでの対策のため、不備があるかも知れません。
　参考程度にお使いください。
</font>

##解決策
KAG3に同梱されていた`Movie.tjs`に手を加えることで問題なく再生できるようになる。

対策済みファイル : https://alicey.dev/share/qiita/Movie.tjs(h264).zip

##原因と対処
H.264(mp4)のムービーを吉里吉里Zで再生する際に利用するモードはvomMFEVRである。
しかし、KAG3に同梱されている`Movie.tjs`で利用できるモードにvomMFEVRは含まれていない。
これが再生できない原因となる。
よって、vomMFEVRを呼び出せるコードを追記してやれば良い。

上記の対策ファイルでは、197行目から以下のコードを追加することでvomMFEVRに対応している。

```Movie.tjs_197~
opened = false;
if(mode == vomOverlay){
 mode = vomMFEVR;
 try{
  super.open(storage);
  opened = true;
  }
 catch(e){
 dm("ムービーを Mixer モードで開くことができません : " + e.message);
 dm("オーバーレイモードで開きます");
 mode = vomOverlay;
 }
}
```
##最後に
吉里吉里やKAGは「難しい」「とっつきにくい」「資料が少ない」という認識が大きいかと思います。
しかし、商業ゲームにも使われるほど、安定し軽く、拡張性のあるものだと思います。
これから、沢山の人が吉里吉里やKAGに触れ、たくさんの情報が公開され、開発しやすくなることを願っています。
（そしたらびしょうじょげーむいっぱいできるやったー
CSS : hover時に他の要素の操作をしたい時の注意点

cssのhover操作で、hoverする要素とは別の要素のスタイルを変更したいと思ったときに、色々調べたので、メモとして残します。

<h2>hoverで別の要素のスタイリングをする</h2>
hoverして、別の要素を動かしたい時

<code>要素:hover +別要素</code>

と書きます。 '+' は、他の要素を指定するときに書きます。
hoverする要素の子要素の時は書かなくても良いです。

&nbsp;

これから書く説明は、以下のコードを参照してください。
cssに番号をコメントでつけています。
<p class="codepen" data-height="338" data-theme-id="dark" data-default-tab="css,result" data-user="rea-jin" data-slug-hash="pojevWb" style="height: 338px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="hover１">
  <span>See the Pen <a href="https://codepen.io/rea-jin/pen/pojevWb">
  hover１</a> by rea-jin (<a href="https://codepen.io/rea-jin">@rea-jin</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
説明：
()内は、hover要素->スタイリングしたい要素　となっています。

以下、場合分けをして、ある要素をhoverしたときの、ある要素のスタイルを変えていきます。
<h3>1.通常のhover　親要素 (oya1-&gt;oya1)</h3>
oya1をhoverして、oya1の色を変えている。

&nbsp;
<h3>2.通常のhover　子要素 (ko1-&gt;ko1)</h3>
oya1の中にある子要素ko1をhoverして、それ自体を操作したい。

これは可能だが、oya1まで変化している。

子要素をhoverした時、親要素もhover対象となる。
<h4></h4>
<h3>3.子要素の同階層への操作 (ko1-&gt;ko1-2)</h3>
ko1をhoverして、ko1-2を操作したいが、できない。

これは同階層にある子要素。

コードや2の結果からわかるように、

親要素の中に入っており、親要素をhoverしているので、子要素から子要素へはhover操作できない。

&nbsp;
<h3>4.親要素をhoverして子要素を操作 (oya2-&gt;ko2)</h3>
oya2をhoverしたとき、ko2の色を変えている。

これは可能である。

さらに、ko2をhoverするということは、oya2もhover対象なので、これもko2の色が変わる。

&nbsp;

次は、以下のコードを参照してください。
<p class="codepen" data-height="349" data-theme-id="dark" data-default-tab="css,result" data-user="rea-jin" data-slug-hash="vYNxLLa" style="height: 349px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="hover2">
  <span>See the Pen <a href="https://codepen.io/rea-jin/pen/vYNxLLa">
  hover2</a> by rea-jin (<a href="https://codepen.io/rea-jin">@rea-jin</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
&nbsp;
<h3>5. 親要素をhoverして同階層の親要素を操作 (oya3-&gt;oya4)</h3>
oya3をhoverして、oya4の色を変更。

これも可能である。2や3のように、親要素に囲われておらず、自身だけがhover対象となっている。

&nbsp;
<h3>6. 親要素をhoverして、他の親の子要素を操作 (oya3-&gt;ko4)</h3>
もう気づいたかもしれないが、oya3をhoverした時に、ko4も色が変わっている。

これは、要素の指定の仕方が重要で、'+.ko4'だけでは変化しない。

'+.oya4 .ko4' というように、どの親か指定する。半角スペースも入れる。

わかりづらければ、5の操作をコメントアウトして見てください。

&nbsp;
<h3>7. 子要素をhoverして、他の親や他の子要素を操作 (ko4-&gt;oya5 or ko5)</h3>
これはどちらもできない。

子要素をhoverすると親要素もhover対象といったが、きちんと親要素を指定して、hoverしないと他は操作できない。


&nbsp;
<h3>8. 親要素をhoverして、他の親を操作 (下から上) (oya5-&gt;oya4)</h3>
できない。
&nbsp;

これが、なぜこれができないのか結構調べました。

しかし、全然見つからず、自分で気づきました。

HTMLはドキュメントツリー構造で、上から下へ処理されるからなのでは？　と。

これは、常識ですが、初学者は忘れがちなことかもしれません。

cssみたいに、順番気にせず書いてたら、できそうな気がするものです

。

処理された後に、操作しようといっても、cssじゃできないと言うことですかね。

参考
<blockquote>https://techacademy.jp/magazine/19418</blockquote>





*初学者による、初学者向けの記事です。間違いがあれば、ご指摘いただけると幸いです。
コメントお待ちしております。*
【備忘録】ARM-FirstボードをMacで使うための環境構築：純正＋Arduino編

##トラ技ノール2020年３月号掲載のARM-First買ってみた
ので解説動画を見ながらセットアップしてみたがつまづき放題なので備忘録として書いておく。
環境は次のとおりです。
MacBookPro（mid2014）
OSX Mojave（10.14.6）
STM32-IDE（1.3.1）※この時点で最新
CubeProgrammer（2.4.0）

##STM32-IDE編
インストールからつまづきます。
stマイクロのサイトからバイナリをDLし、dmgファイルを開いてインストーラなりアプリのコピーなりしますが、セキュリティ設定で弾かれます。
で、システム環境設定＞セキュリティとプライバシー＞一般で見てみると昔合ったはずのすべてのアプリケーションを許可ボタンが消えている。
<img width="489" alt="この図のようにすべてのアプリケーションを許可がボタンがいつのまにかない" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207819/27ca242a-3848-74e4-ebcf-e8f5d95e10db.png">
ので許可ボタンを出します。
これをやっておかないとSTマイクロだけでなく他のアプリもインスコできまへん。
ターミナルから下記を入力します。
`$sudo spctl --master-disable`

そうするとシステム環境設定で実行許可に実行したはずのインストーラなどが出てくるので「このまま開く」を押すと開くはずです。
しかし、私の環境ではこれでもだめだったのでインストール後のアプリ起動でもまたセキュリティ設定がもとに戻っていたりと面倒なのでアプリのフォルダ配下の拡張属性を削除して起動しました。
これもターミナルで下記のように実行します。
`$xattr -cr /Users/hoge/Downloads/SetupSTM32CubeProgrammer-2.4.0.app/`
※同様にIDEもインストール後に行います
`$xattr -cr /Users/hoge/Applications/STM32CubeIDE.app/`

これで起動しました。
####起動後のアップデート
起動するとアップデートがあるので入れておきます。
2GB以上あったので往年の「CoffeBreak」で待ちます。

####サンプルを動作させてみる
付録のサンプルプログラムをProgrammerで「Arm_First_Test_lcd.bin」を書き込むときにはUSBに挿したあとでDFUモードに移行します。
・BOOT/RESET同時押し
・RESET離す
・BOOT離す

でDFUモードに移行します。移行したらUSBの接続は切れてしまうので"/dev/cu.usbmodem0000000******"のようなデバイスファイルは消えます。
その代わり、CubeProgrammerでUSBが認識されます。
<img width="1201" alt="PortのところにUSB1と記載" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207819/0d55daac-9faa-6d51-2ef1-637b97f8eda3.png">
こうなれば右のConnectボタンを押して接続して、左の上から2番めの書き込みボタンを押しサンプルを指定して「StartProgram」で書き込みます。

ただしこれは単体で書き込む方法なので実際はST-Link2デバッガを使ってIDE上で「Run」ボタンを押すと書き込みから実行〜デバッグまでシームレスに見ることができます。
なので実際はST-Link2を使ったほうが断然楽です。

ST-Link2は単体でも買うことができますが、イベントなどでSTマイクロさんのブースにて応募するともらえるボードなどにはついていますのでぜひSTマイクロさんのセミナーなどに参加してゲットするのが良いでしょう。
※首都圏以外の方は単体購入のほうが絶対安いです
とはいえ2020年の今年は新型肺炎ウイルスの影響でイベント皆無＆リアル秋月電子も休業（ECはやってる）なのでいろいろ厳しいですね。

ちなみに私がゲットしているのはこちらのボードです。
http://akizukidenshi.com/catalog/g/gM-07723/

あとは記事や付録DVD通りにやっていけば問題なくコンパイル〜実行できます。

##Arduino環境に関して
Macの場合は結論から言うとST-Link2経由でないと書き込みできません。

これは、記事中で紹介しているライブラリSTM32GENERIC
https://github.com/alto0126/STM32GENERIC
のドキュメントによれば専用のbootloaderのバイナリを取ってきて読ませてからDFUモードでやれと書いてありますが、すでにST-Link2を持っているのでST-Link2経由でアップロードすれば何ら問題なく実行できます。

そのまま実行するとArduinoIDEで書き込み時にエラーが出て書き込めません。
ST-Link2経由で接続していればツールメニューで次のように設定してやれば問題なく書き込めます。
<img width="387" alt="Upload MethodをSTLinkにする" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207819/1c5eafb9-d5b3-f1a1-12dc-b07fde4108ae.png">

＃ひとまず学習を進められるには
これらの設定でできると思います。
書面の都合だと思いますが、Macでの方法も一部書いてほしいなと思います。
サポートページのリンクでもいいんだけど・・・

余裕が出てきたらVSCode＆PlatformIOでも試してみたいですが、CubeMXとかとの連携どうすんの問題はもうちょい落ち着いてからやろう。
このあたり知っている方がいれば教えていただけるとめちゃくちゃ嬉しいです。
ドメインとDNSの役割とは

# ドメインとDNSって何なの？
・ドメイン＝IPアドレスを文字化したもの
・DNS＝IPアドレスをドメイン化するその仕組み
これだけ言われてもイマイチだと思うのでもっと噛み砕いて説明します。
ちなみにIPアドレスって何なのよって思った方は以下の記事を読んでください。
[IPアドレスって一体何？？](https://qiita.com/Nyanmaru-12/items/1ef10091e8fe1f641ebb)
## ドメインとDNSの具体例
このQiitaを例にします。
このQiitaのIPアドレスは「18.178.181.245」です。
でも、この数字を覚えて毎回検索するのはダルいし、分かりにくいですよね。
そこで、**もっと分かりやすくこの数字を文字にしようとしたのがドメイン**です。
そして**その仕組みをDNS（Domain Name System）**と言います。
では18.178.181.245のドメインは何なのか…。
それが「qiita.com」なのです。
![E86C2F52-56E8-458B-B3CA-49B4D2818093_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625088/d018dc79-78c8-cff1-16e2-5ebccea4a784.jpeg)
ちなみにqiitaの部分はセカンドレベルドメイン、.comはトップレベルドメインと呼ばれたりしますがここは割愛します。
ただここでどうやってQiitaのIPアドレスを知れたのかという疑問が湧いてくると思います。
# ドメインを利用してIPアドレスを調べる方法
ターミナルで**digコマンド**を使います。
入力はdig ドメインでOKです。

```terminal
% dig qiita.com
```
検索結果は次の通り。

```terminal
<省略>
;; ANSWER SECTION:
qiita.com.		58	IN	A	18.178.181.245
qiita.com.		58	IN	A	18.180.153.140
qiita.com.		58	IN	A	13.230.142.0
<省略>
```
このANSER SECTIONの中にあるのがドメインとそれに対応するIPアドレス。
あれ？同じドメイン名が何で３つあるの？と思ったと思います。
結論いうと、サーバーが３つあるからです。
IPアドレスは住所みたいなものですが、それが３つあるということは家が３つあるということです。
**つまり家（サーバー）３つもたないとパンパンになっちゃう！**ということなのでしょうね。
大所帯のサイトにいくとサーバー複数持っている可能性が大です。
気になった方はぜひ調べて見てください。
concrete5 インストールを繰り返したり定時リセットするデモサーバーをセットアップしたい時


concrete5 をローカルでテストしている時に、何度も同じ環境をアンインストールしてインストールしたいときがあります。

そんな時、コマンドラインツールで簡単にインストールを繰り返すことができる使える方法です。

お客さん向けにデモサーバーを使いたい時に

# インストール用の config PHP ファイルを作成する

concrete5 のインストールには、PHP の配列形式で保存したファイルを使います。

## フォーマット

下記のようなフォーマットで作成します。

```install_config.php
<?php
return [
    'db-server'=>'【DB のアドレス】',
    'db-username'=>'【DB のユーザー名】',
    'db-password'=> '【DB のパスワード】',
    'db-database'=> '【DB の名前】',
    'timezone' => '【タイムゾーン】',
    'starting-point' => '【スターティングポイント】',
    'admin-email'=> '【admin ユーザーのメールアドレス】',
    'admin-password' => '【admin のパスワード】',
    'language'=> '【管理画面の既定言語】',
    'site-locale'=>'【サイトの既定言語】',
];
```

他にも入力できるオプションがあります。
コマンドラインツールでオプションを確認してみてください。

8.5.2 時点では以下のようになります。

```
$ concrete/bin/concrete5 c5:install

c5:install [--env ENV] [--allow-as-root] [--db-server DB-SERVER] [--db-username DB-USERNAME] [--db-password DB-PASSWORD] [--db-database DB-DATABASE] [--timezone TIMEZONE] [--site SITE] [--canonical-url CANONICAL-URL] [--canonical-url-alternative CANONICAL-URL-ALTERNATIVE] [--starting-point STARTING-POINT] [--admin-email ADMIN-EMAIL] [--admin-password ADMIN-PASSWORD] [--demo-username DEMO-USERNAME] [--demo-password DEMO-PASSWORD] [--demo-email DEMO-EMAIL] [--language LANGUAGE] [--site-locale SITE-LOCALE] [--config CONFIG] [--attach] [--force-attach] [-i|--interactive] [--ignore-warnings]
```

## サンプル

例えば、私のローカルだったらこんな感じの設定ファイルになります。


```install_config.php
<?php
return [
    'db-server'=>'127.0.0.1',
    'db-username'=>'concrete5',
    'db-password'=> 'concrete5',
    'db-database'=> 'c5demo',
    'timezone' => 'Asia/Tokyo',
    'starting-point' => 'elemental_full',
    'admin-email'=> 'admin@example.com',
    'admin-password' => '123456',
    'language'=> 'ja_JP',
    'site-locale'=>'ja_JP',
];
```

これを、`install_config.php`というようなファイルで、concrete5 のルートフォルダにおいておきます。

# インストールコマンド

```
$ cd [concrete5 インストール場所]
$ concrete/bin/concrete5 c5:install --config=【さきほどの config ファイル】
```

## 実行サンプル

```
$ cd ~/Sites/concrete5
$ concrete/bin/concrete5 c5:install --config=install_config.php
```

# アンインストール

アンインストールする時のコマンドはこちら

```
$ concrete/bin/concrete5 c5:reset

```

# 例:アンインストールしてすぐにインストール


アンインストールしてすぐにインストールする時は、下記のコマンドをコピペして実行するとリセットできます。


```
concrete/bin/concrete5 c5:reset -f
concrete/bin/concrete5 c5:install --config=install_config.php
```

c5:reset の -f オプション (force) オプションで、確認なにしリセットが実行されます。

うまく使いこなして、パスワードを適宜違うものに変更するとか、
オリジナルのスターティングポイントを作成して、ホスティングサイトを作るとか、可能性は無限大です！
jquery スクロールでフェードイン、フェードアウトメモ

```javascript

$(function(){
      $(window).scroll(function (){
        $(".fade_off").each(function(){
          var imgPos = $(this).offset().top;
          var scroll = $(window).scrollTop();
          var windowHeight = $(window).height();
          if (scroll > imgPos - windowHeight + windowHeight/5){
            $(this).addClass("fade_on");
          } else {
            $(this).removeClass("fade_on");
          }
        });
      });
    });

```
python3のprint()で改行しない方法

# print関数のendオプションを使う
Python3 で print()すると、　通常改行される。
print("hello world", end="")  とすれば、改行されない。


Arduino IDEだと　println() と print()を使い分けて　
print文で出力した値のあとに改行するかしないかを指定しているけど、
pythonだとどうしているのかなぁと思って調べてみた。

end オプションは、奥が深そうだ。　cr、lfとかのコントロールもできるのかな？
ほかにも、sep 区切り文字、　　file ファイルの指定、　flush　バッファの強制出力、などがあるようだ。
ハードウェアに近い部分のプログラムを作るときに関係ありそう。
今の時点は、この程度の調査でどどめておこう。
（現場からは以上です。）
bs4で画像を文字列に置換する

##前提
###環境
MacOS Catalina(10.15.3)
python 3.7.5
BeautifulSoup 4.9.0
###実現したかったこと
"@"等の特定の文字列が画像置換されているサイトのスクレイピングにおいて，その画像を元の文字列に置き換える処理．
##解決
BeautifulSoupにはreplace_with(置換先)というメソッドがあるのでこれを使えば良い.ただし，取得した置換元の画像タグはリストになっているので，その個数でループを回して扱った．
###コード
今回は一種類の画像を置換するだけだったので，手を抜いて全ての画像に処理を施すことにした．

```python
def replaceImg(soup):
	numOfImg = len(soup.find_all("img"))
	for i in range(numOfImg):
		soup.img.replace_with("@")
	return soup
```
##終わりに
python素人かつプログラミング素人なので，もっと良い実装をご存知の方はご教示いただけると嬉しいです．
###参考
[bs4のドキュメント（日本語訳)](http://kondou.com/BS4/)
React+Redux学習への道のり。～Reactを知る～

# はじめに・・・
React +　Reduxを学ぼうとしましたが、Reactが謎すぎて環境の構築すらできませんでした。
なので、40%でもいいのでReactを理解するための私的なメモです。

※タイトルに「Redux」って書いていますが、今回はReactのみです。

#自分のスペック
- なーんちゃってJavaプログラマー(バージョンは1.5．フレームワークはStruts1系しか知らない)
- javaScript(jQuery)・HTML・CSSはボチボチ触ってた。
- Dockerを独学で勉強中。

# Reactって何なん？！ってかNode.jsって何なん？！
まずReactを学ぶのだからコードを書きたい気持ちになります。
そこで「React 入門」でググりますが、でてくる記事全てに**Node.js**というキーワード。
まず**Node.js**すら知らなかったのでそこから調べます。

## Node.jsとは？
完全に理解はできてないです。現在は・・・
「サーバーサイドで動くJavaScriptの環境」
で落ち着いています。

## Reactとは？
これまた完全に理解はできてませんが、javaScriptのライブラリーらしい。
javaScriptのライブラリーってことは、ただのjavaScriptじゃない？ってなりました。
**それじゃNode.jsいらなくない？**ってなりました。

## けれども必要となるわけ。１
「Reactで開発するにはBabelでコンパイルしないとダメだからNode.jsが必要となる！」
・・・私の中ではこれで胸落ちしてます。

経緯としては・・・
Reactの公式チュートリアルもNode.js使ってて？？？
↓
公式を読んでいくとReactは**JSX**というjavaScript拡張言語で記述する様子。
↓
JSX ≠ javaScriptなので**JSXをjavaScriptに変換する**必要がある。
この変換をするのが**Node.js製のツールBabel**に行き着くって感じです。

### 余談
コンパイルする前のコードをローカル上で起動してみましたが画面は真っ白。
コンパイルしたソースを手直しすると画面が表示されました。

### 参考資料
以下のスライドが私的にはわかりやすい説明で理解しやすかったです。
[おっさんES6/ES2015,React.jsを学ぶ](https://www.slideshare.net/dcubeio/es6es2015reactjs)
## けれども必要となるわけ。２
「Reactアプリをnpm(npX)で作るから。」

Reactアプリを作成するにはかなりの量のモジュールが必要となる。
これらのモジュールをどっから取ってくるよ？問題 と バージョン管理問題がある。
それを解決してくれるのが**npm**。
mavenみたいなもんと認識してる。


#おわりに・・・
javaScriptの進歩半端なくてビビってます。
無法地帯だったjavaScriptが進化してES6？とかなってるので、これについても勉強がいるなぁと実感。
そもそもラムダ式にも慣れていないのに、基本ラムダ式オンパレードで泣きそう。

もし認識に誤りがあれば訂正お願いします。
aws  の備忘録

## 概要
AWSを使うときによくハマるバグなどを自分用に書いて行く備忘録。

## メモ

- auth error
```
An error occurred (UnrecognizedClientException) when calling the GetAuthorizationToken operation: The security token included in the request is invalid.
Error: Cannot perform an interactive login from a non TTY device
```

https://teratail.com/questions/220857 で解決

```
export AWS_ACCESS_KEY_ID=***
export AWS_SECRET_ACCESS_KEY=*****
export AWS_DEFAULT_REGION=ap-northeast-1
```

これが定義されていると、```aws configure```したものより優先される。


- ecr ログイン
 
```
aws ecr get-login --no-include-email
```

を実行して、出てきたコマンドをそのまま実行。