OmniAICreator/Qiita-1.07M huggingface dataset:
mysql2がldflagsのオプション使ってもbundle installできない

# 以前試した奴がうまくいかなかった。

以前解決した方法はこちら。
[Rails 5.2.3でmysql2がbundle isntallできない
](https://qiita.com/Nedward/items/dc5eae7449f3238ff14e)

下記のようになってconfigの中身を書き換えて、何度もやっていると当然っちゃ当然ですがリプレイスされただけの結果しか生まれない

```
You are replacing the current local value of build.mysql2, which is currently "--with-ldflags=-L/usr/local/opt/openssl/lib"
```

## ほう？お前、別件エラーだな？
どうやらまたmysql2の別のエラーのようです。
散々探し回ってようやく見つけた答えがこちらです。

```Gemfile
mysql2 (>= 0.3.13, < 0.5)
```
を

```Gemfile
mysql2 (~> 0.4.10)
```

にバージョンをあげてあげることです。

githubの方にもissueが上がっておりました。
[Support mysql2 0.4.x and 0.5.x #32310
](https://github.com/rails/rails/pull/32310)
【Rspec】railsでテスト用のDB作成

railsでテスト用のDBを作成します。

database.ymlにtest用のDBを記述します。

```yml:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: sample_development

test:
  <<: *default
  database: sample_test
```

test環境を指定して、migrationしてあげます。

```
$ bundle exec rake db:migrate RAILS_ENV=test
```

以上です。

参考: https://qiita.com/tocomi/items/2dba0de52eefdcf33fd7
githubのFind Fileがリポジトリ内ファイルのあいまい検索ができてとても便利

github上でリポジトリ内のファイル検索する際に１つずつクリックしていくと結構手間なこともあります。
そんな時は``Find File``を使うと早くて便利。

<img width="1088" alt="スクリーンショット 2019-10-04 11.25.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/4ca7f1ad-c591-3ead-a8bf-41fe846abddb.png">


ファイル名だけでなく、パス全体であいまい検索がされるのでとても便利です。

<img width="1096" alt="スクリーンショット 2019-10-04 11.25.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/97b6ae19-602b-7856-374c-531fa4e44df5.png">

１文字ずつシームレスに検索が反映されるので速度も早くてとても使い勝手がいいです。
RxJSを使用せずにswitchMap(flatMapLatest)を実現する

APIにリクエストした時に最後のリクエスト結果だけを取得したいと思う時があり、RxJSのswitchMapに頼ることがあったけど、少し考えてみればなんてことのない処理で実現できた。

```javascript:最新のPromiseの結果だけを実行する関数
function createPromiseLatest(callback) {
    let latestPromise = null; // 最後に実行したいPromiseを管理
    return function promiseLatest(promise) {
        latestPromise = promise; // 追加されたPromiseを取得
        promise.then((value) => {
            // 最後に実行したいPromiseと追加されたPromiseが一致したら実行
            if (latestPromise === promise) {
                callback(value);
            }
        });
    }
}
```

```javascript:使い方
function sleep(ms, value) {
  return new Promise((resolve) => setTimeout(() => {resolve(value);}, ms));
}

const callback = (value) => {
    console.log('Hello ' + value);
}
const promiseLatest = createPromiseLatest(callback);

// 1件目、２件目は処理されるが出力対象にはならない
promiseLatest(sleep(1000, "Mike"));
promiseLatest(sleep(2000, "Henry"));
promiseLatest(sleep(3000, "Bob"));
// console log: Hello Bob
```

ちなみに最初のPromiseだけ処理したい場合なら下記でできる。

```javascript:最初のPromiseの結果だけ実行する関数
function createPromiseFirst(callback) {
    let firstPromise = null; // 最初に実行したいPromiseを管理
    return function promiseFirst(promise) {
        if (firstPromise !== null) return; // Promiseがすでにあるなら処理しない
        firstPromise = promise;
        promise.then((value) => {
            callback(value);
        });
    }
}
```

```javascript:使い方
function sleep(ms, value) {
  return new Promise((resolve) => setTimeout(() => {resolve(value);}, ms));
}

const callback = (value) => {
    console.log('Hello ' + value);
}
const promiseFirst = createPromiseFirst(callback);

// 2件目、3件目は処理されるが出力対象にはならない
promiseFirst(sleep(1000, "Mike"));
promiseFirst(sleep(2000, "Henry"));
promiseFirst(sleep(3000, "Bob"));
// console log: Hello Mike
```

便利なものを知りすぎると、すぐにそれにばっかり頼ってしまうので、気をつけたい😭
機械学習の再現性のためのチェックリスト

# 概要

深層学習の論文を読んで再現実験を行うときに、あっさりうまくいくこともあるが、全然再現できないことのも多い。ベースラインからほとんど変わらないとか、そもそもこの論文、ベースライン手法のチューニングしてないじゃんとか、いろいろ問題が出てくる。

機械学習分野の論文は再現性が低い、という問題を少しでも解決するために、[NeurIPSが論文投稿者に求めているチェックリスト](https://www.cs.mcgill.ca/~jpineau/ReproducibilityChecklist.pdf)を読んでみた。

Andrew Ng先生のdeeplearning.aiがやっているニュースレターである[The Batch](https://info.deeplearning.ai/the-batch-global-surveillance-survey-ais-crisis-of-reproducibility-construction-drones-bots-cheat-at-hide-and-seek)で、紹介されていた。

# 意訳

## アルゴリズムについて
提示しているアルゴリズムについて、以下の事項を満たしていること。
    
- 数学的な設定、アルゴリズム、およびモデルの明確な説明をする。
- 任意のアルゴリズムに対する複雑さ（時間、空間、サンプルサイズ）の分析をする。
- 外部ライブラリを含む、すべての依存関係を特定している、ダウンロード可能なソースコードへのリンクを提示する。

## 理論的な主張について
理論的な主張については、以下の事項を満たしていること。

- 結果がどうだったのかについての明記する。
- 仮定を明確に説明する。
- 主張の完全な証明を提供する。

## 図と表について
経験的な結果（つまり、実験結果）を示す図と表については、以下の事項を満たしていること。

- サンプルサイズなど、データ収集プロセスに関する完全な説明を行う。
- データセットまたはシミュレーション環境のダウンロード可能なバージョンへのリンクを貼る。
- 除外されたデータの説明、前処理ステップの説明。
- Training/Validation/Testのためにサンプルがどのように割り当てられたかの説明をする。
- 考慮されるハイパーパラメーターの範囲、最適なハイパーパラメーター構成を選択する方法、示している結果で使用されたすべてのハイパーパラメーターを明記する。
- 評価実行の正確な回数を明記する。
- 実験の実行方法の説明をする。
- 結果の報告に使用される特定の指標または統計の明確な定義を提示する。
- エラーバーを明確に定義する。
- 中心的な傾向（例：平均）と変動（例：標準偏差）を伴う結果の説明を行う。
- 使用されるコンピューティングインフラストラクチャの説明を行う。

# PyTorch周辺の補助ツール（2020年01月10日追記）

[Facebook AIのブログ記事](https://ai.facebook.com/blog/how-the-ai-community-can-get-serious-about-reproducibility/)で、このチェックリストに関する言及がなされていました。その記事の中で、一部とはいえ再現性をサポートするためのツールやサービスが紹介されていましたので、簡単に列挙しておきます。

- PyTorch Hub: Colabの組み込みサポートとPapers With Codeとの統合が組み込まれている。これにより結果をより迅速かつ簡単に評価できるようになっている。
- PyTorch Lightning: 研究ワークフローの多くを自動化し、最新のベストプラクティスを保証してくれる。
- sotabench: GitHubの実際のコードと、研究を再現するための透過的で継続的な統合のようなインフラストラクチャを使用して、論文の自動比較を提供している。

再現性の保証のためには個々の研究者の努力だけではなく、このあたりのツールやサービスの整備や、コミュニティの成熟が必要であるという書き方がなされていて、なるほどなあと思いました。

# 感想
再現実験マンにとっては、以下が重要かなと思った。

- 外部ライブラリを含む、すべての依存関係を特定している、ダウンロード可能なソースコードへのリンクを提示する。
    - ソースコードは公開しないより公開するほうがはるかにマシなわけですが、「githubにソースコード置いとくよ（ただしMNISTの実験のぶんだけね）」、みたいなものも多いので、すべての実験に関する完全なソースコードの共有をしてほしいもんです。
  
- 中心的な傾向（例：平均）と変動（例：標準偏差）を伴う結果の説明を行う。
    - 精度評価の表に「±」が入っていないと悲しくなる。
    - 精度の分布を示してほしい。深層学習はどうしても訓練の過程にランダム性が入るので、極端に悪かった結果は、平均や標準偏差の計算から除いてもいいと思うが、outperformな結果が2回に１回くらいの割合で得られるのか、10回に１回しか得られないのか、で再現する人にとっての物理的・心理的負担がぜんぜん違う。
flake8についてのアウトプット

こんにちは！
現在インターン先でプログラミングの勉強をしている大学三回生です。
今回はflake8について勉強する機会があったので、それについてアウトプットしていこうと思います。
基本調べたことを書いているだけなので、詳細を知りたい方は参考文献を載せておくのでそちらを御覧ください。

##flake8と何なのか
flake8とは「pep8のチェック、pyflakesのチェック、及び循環的複雑度をチェックできるラッパー」→（[引用元](https://blog-ja.sideci.com/entry/python-lint-pickup-5tools)）のことらしいです。
つまり、広範囲カバーしてくれるPythonのコードチェックツールですね！
flake8は下記コードチェックツールのラッパーとなります。

・`PyFlakes（pyflakes : コードのエラーチェック）`
・`pycodestyle（pycodestyle : PEP8に準拠しているかチェック）`
・`Ned Batchelder’s McCabe script（mccabe : 循環的複雑度のチェック）`

##flake8を使ってみよう！
では実際にflake8を使ってみましょう!
そのためには、まずflake8をインストール必要があります。
下記コマンドでインストールできます。

```
$ pip install flake8
```
実際に使用するときは

```
$ flake8 ファイル名 
```
で実行できます。
また、ファイル名だけではなく、ディレクトリ名でも実行できます。
実際に僕のdjangoのblogsというアプリケーションで試してみたいと思います。

```
$ flake8 blogs
blogs/views.py:3:1: E302 expected 2 blank lines, found 1
blogs/views.py:4:47: W292 no newline at end of file
blogs/urls.py:7:2: W292 no newline at end of file
blogs/admin.py:5:1: W391 blank line at end of file
blogs/models.py:4:1: E302 expected 2 blank lines, found 1
blogs/models.py:11:26: W292 no newline at end of file
blogs/tests.py:1:1: F401 'django.test.TestCase' imported but unused
blogs/migrations/0001_initial.py:17:80: E501 line too long (114 > 79 characters)
```
このような結果が出てきます。
また、--show-sourceオプションをつけるとどこを修正すればいいのかわかりやすくなります。
では、実際に実行してみましょう。

```
$ flake8 --show-source blogs
blogs/views.py:3:1: E302 expected 2 blank lines, found 1
def index(request):
^
blogs/views.py:4:47: W292 no newline at end of file
    return render(request, 'blogs/index.html')                                              ^
blogs/urls.py:7:2: W292 no newline at end of file
] ^
blogs/admin.py:5:1: W391 blank line at end of file

^
blogs/models.py:4:1: E302 expected 2 blank lines, found 1
class Blog(models.Model):
^
blogs/models.py:11:26: W292 no newline at end of file
        return self.title                         ^
blogs/tests.py:1:1: F401 'django.test.TestCase' imported but unused
from django.test import TestCase
^
blogs/migrations/0001_initial.py:17:80: E501 line too long (114 > 79 characters)
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
```
このようにさっきよりもわかりやすくなりました。

##まとめ
flake8を使用することで、より間違いも少なくでき、コードもきれいになるので頻繁に使っていこうと思います。
最後までお読みいただきありがとうございます。
もっと詳しく知りたい方は参考文献をお読みください。

##参考文献
[Vimメモ : flake8でPythonのコードをチェックする](https://wonderwall.hatenablog.com/entry/2017/02/05/214004#flake8%E3%81%A8%E3%81%AF)

[Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ！](https://blog-ja.sideci.com/entry/python-lint-pickup-5tools)

[flake8を使ってPythonプロジェクトを自動コードレビューする](https://blog-ja.sideci.com/entry/2017/06/20/110000)
左に画像があって、真ん中にタイトルと説明があって、右に日付があるようなカードのHTML/CSSでの表現はGridが便利だった

こういうのHTML/CSSで書く時どうしてます？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117615/11f710fe-c171-e2ad-afa8-498a758b32c5.png)

最低限必要な中身はこんな感じだと思います

```html
<div class="class">
  <img class="image" />
  <h2 class="title" />
  <p class="description" />
  <p class="date" />
</div>
```

Twitterでも聞いてみました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">こういうのHTML/CSSで書く時どうしてます？<br>画像と右側の文字群を親にdisplay: flex指定してレイアウトするか、画像と日付をpositionで指定するか、grid？を使うかあたりで悩んでおります、、 <a href="https://t.co/XEC96mfaFP">pic.twitter.com/XEC96mfaFP</a></p>&mdash; こばしゅん (@ksyunnnn) <a href="https://twitter.com/ksyunnnn/status/1179354779589513218?ref_src=twsrc%5Etfw">October 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

なんとなく思いつくのは `display: flex`じゃないですかね。

ただその場合 `h2.title`と `p.description`を更に`<div/>`で囲ってあげる必要がありますね。それでも問題ないんですが、どうせならHTMLはこのままで、CSSのみでデザインを反映したくないですか？

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自分はgrid使いますかね。<br>grid-template:<br> &quot;image title date&quot; 30px<br> &quot;image description description&quot; 1fr /<br>40px 180px 50px;<br><br>的な感じでしょうか。</p>&mdash; ザリガニデザインオフィス (@zarigani_design) <a href="https://twitter.com/zarigani_design/status/1179357551353307138?ref_src=twsrc%5Etfw">October 2, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Twitter最高。display: grid使えばいい感じにできそうということが模範解答つきで教えてもらえました。神かよ..:pray:

更にこのあたりを参考にして、実装してみました。

https://webdesign-trends.net/entry/9526

※gridに関する記述のみ抜粋

```css
.card {
  display: grid;
  row-gap: 8px;
  column-gap: 16px;
  grid-template:
    "image title date" 30px
    "image description description" 1fr /
    80px 1fr 90px;
}

.image {
  grid-area: image;  
}

.title {
  grid-area: title;  
}

.description {
  grid-area: description;
}

.date {
  grid-area: date;
}
```

grid-templateの箇所だけ、最初は吐き気を催すかもしれませんが、落ち着いてください。何度みても吐き気がします。

なんとなくテーブルのような構造をイメージしながら読めばわかりやすいのかな、と個人的に思っているのですが

```css
grid-template:
    /* 1行目の高さ(row)と、1行目に含む内容 */
    "image title date" 30px
    
    /* 2行目の高さ(row ※1frは残りの長さを指定するgridでの表現)と、2行目に含む内容
       スラッシュ(/)以降は、縦の列(column)の幅をそれぞれ指定
     */
    "image description description" 1fr /
    80px 1fr 90px;
}
```

まあこんな感じです、、。まあ雰囲気で使っていきましょう、、


結果がこちら〜

<p class="codepen" data-height="300" data-theme-id="29715" data-default-tab="result" data-user="ksyunnnn" data-slug-hash="wvwVPWQ" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Grid Card">
  <span>See the Pen <a href="https://codepen.io/ksyunnnn/pen/wvwVPWQ">
  Grid Card</a> by Kobashi syunsuke (<a href="https://codepen.io/ksyunnnn">@ksyunnnn</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

それでは、Happy Gridライフを〜:wave:
FreeBSDでiocageを使ってJailを管理する

## 始めに

FreeBSDのJailを管理するのに、qjailとかを使ってたけど、iocageと言うZFSをベースにしたツールが使いやすかったのでmemo
ほぼ参考サイトに記載されている、Slideshareのままです。

## 環境

* FreeBSD 13R
* ZFS root(プール名 zroot)
    * ZFS rootでなくてもZFSのプールがあれば使える

## 環境構築

iocageのコマンド郡をインストールして、iocageを有効にします。

```
# pkg install py38-iocage
# iocage activate zroot
# mount -t fdescfs null /dev/fd
# iocage list
```

mount コマンドを永続化するため、 fstab に追記

```/etc/fstab.
fdescfs /dev/fd  fdescfs  rw  0  0
```

## Jailを作るとき

iocage create コマンドで作成します。
利用するバージョンを始めて利用する際に、該当バージョンのバイナリファイルがダウンロードされ、freebsd-updateにて最新のパッチが当てられます。

* -n ： Jail名
* -r ： バージョン

```
# iocage create -n asterisk -r 13.0-RELEASE
```

## JailにIPv4アドレスを割り当てる

```
# iocage set ip4=new  [Jail名]
# iocage set ip4_addr="lo1|10.100.100.11/24" [Jail名]
# iocage set defaultrouter=10.100.100.254 [Jail名]
// pingを打てるようにするにはこれも必要
# iocage set allow_raw_sockets=1 [Jail名]
```

* IPアドレス複数割り当てる場合は , で区切る
    * iocage set ip4_addr="lo1|10.100.100.11/24, lo1|10.100.100.12/24" [Jail名]
* 複数のパラメタを続けて指定することも可能
    * iocage set ip4=new ip4_addr="lo1|10.100.100.11/24" [Jail名]

## Jailを起動する

```
# iocage start [Jail名]
```

## Jailを停止する

```
# iocage stop [Jail名]
```

## Jailの自動起動

```
# iocage set boot=on [Jail名]
```

## iocageの自動起動

```
# sysrc iocage_enable="YES"
```

## スナップショット

### スナップショットを取る

* -n ： スナップショット名は省略可能でその場合は YYYY-MM-DD_hh:mm:ss (UTC) となります。

```
#  iocage snapshot [Jail名] -n [スナップショット名]
```

### スナップショット一覧

```
# iocage snaplist [Jail名] -l
+------------------------------------------------+-----------------------+-------+------+
|                      NAME                      |        CREATED        | RSIZE | USED |
+================================================+=======================+=======+======+
| zroot/iocage/jails/[Jail名]/root@20191004_init | Fri Oct  4 10:45 2019 | 1.37G | 0    |
+------------------------------------------------+-----------------------+-------+------+
| zroot/iocage/jails/[Jail名]@20191004_init      | Fri Oct  4 10:45 2019 | 92K   | 0    |
+------------------------------------------------+-----------------------+-------+------+
```

## 外側のIPアドレスが1つしか無い場合

VPSなどで構築する際に、グローバルIPアドレスが1つしか無い場合があります。
その場合、pfなどでNAPTすれば 外 ・ ホスト ・ jail の通信が出来るようになります。

```/etc/rc.conf
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"

cloned_interfaces="lo1"
ifconfig_lo1="inet 10.100.100.254 netmask 255.255.255.0"
```

```/etc/pf.conf
ext_if="vtnet0" # 外側のI/F
int_if="lo1"

scrub in all

table <private> const {10.100.100.0/24}

nat on $ext_if inet from ($int_if) to ! <private> -> ($ext_if)

# 必要に応じて、ポートフォワーディングする
rdr on $ext_if proto tcp from any to ($ext_if) port 80-> 10.100.100.11 port 80
```

## 参考サイト

- [Yuichiro NaitoさんのIocage - Slideshare](https://www.slideshare.net/YuichiroNaito/iocage)
【Laravel】スマホでのForm入力時に数値入力パッドを使えるようにする

# スマホの数字入力時に数値専用パッドを使えるようにする
これはそもそも Laravel 関係なく、HTML5の仕様の方で策定されており。
対応ブラウザ、スマホであれば使うことができる。

## 実装は非常に簡単、type="tel" を利用する
最終的に出力されたHTMLの type に tel が設定されていれば
スマホの数値入力パッドが利用できる。

```html:
<input placeholder="123-4567" size="8" maxlength="8" type="tel" name="zip">
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/0d35ee29-03a0-f20d-1ebf-c82787a9789c.png)

## Laravelでの実装方法
Laravelの Form Facade を利用する場合 '第一引数' に type 属性を指定することができる。

```php
{{ Form::input('tel', 'zip', null, ['placeholder' => '1020082', 'size' => 8, 'maxlength' => 8]) }}
```

Form::textの引数に type="tel" と指定しても HTMLに吐き出される時に type="text" に書き換えられてしまうので注意だ。

## numberを使うのか、telを使うのか
郵便番号の入力に `tel` を使うのは流石に違和感があると思う方も多い
しかし type="number" を利用するとこのような入力パッドになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69647/a8821c28-3df9-9642-70b2-abeb5b04f1b4.png)

* フリック入力で数値以外も入力できてしまう。
* ブラウザごとの挙動が結構違う

という点からあまりお勧めできない、もちろん pattern="[0-9]*" などを指定して入力を制限することもできるが
そこまでするなら普通に tel で良いのではないだろうか。
Azure Multi-Factor Authenticationが新ポータルで制御可能になっていた

# Azure Multi-Factor Authenticationが新ポータルで制御可能になったっぽいので試してみる

Azure Multi-Factor Authentication（以下 Azure MFA）が

Microsoft Azure Portal（以下 新ポータル）で制御可能になっていました。

同時に、旧 Microsoft Azure Portal（以下 旧ポータル）へのリンクも場所が変更されていたので、

方法をまとめてみることにします。

## 前提条件と必要なライセンス

### 前提条件

- Azure Active Directory + Azure MFAを利用している

### 必要なライセンス

- Azure Active Directory Premium P1 , P2ライセンスを所持
- 上記 または Microsoft 365 Businessライセンスを保有

※ 一部上記以外でも適用可能な場合があります

## 試してみる

### 新ポータルで制御可能になったところ

- Azure MFAの再設定
- Azure MFAのセッション取り消し

### 実際に新ポータルでやってみる

[Microsoft Azure Portal - Azure Active Directory ブレード](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/Overview) を開きます。

![スクリーンショット 2019-10-04 10.15.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/d9e66944-a722-f221-0b7a-41d087f39eaa.png)

### ユーザーを選択する

ブレードの左側にあるメニューから [ユーザー](https://portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/AllUsers) を選択します。

![Screen Shot 2019-10-04 at 10.37.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/a3f175c9-180a-b04f-4f69-1ad860fd5ad2.png)

[すべてのユーザー](https://portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/AllUsers) から、MFAを制御したいユーザーの概要を開きます。

![Screen Shot 2019-10-04 at 10.40.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/853d84d7-1b19-60fa-89a8-7fbe564c22c3.png)

ブレードの左側にある `認証方法` を開きます。

![スクリーンショット 2019-10-04 10.50.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/8a2539a4-f876-395e-fdc2-001229cd1cef.png)

ブレードの上部には、 `MFAの再登録が必要` `MFAセッションを取り消す` というボタンが出現します。

これだけで、MFAの再設定（旧ポータルでは無効化・有効化操作）

MFAセッションを取り消す（旧ポータルではMFAの無効化）操作が可能となりました。

## 旧ポータルへアクセスする方法

上記の手順にある [すべてのユーザー](https://portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/AllUsers)のブレードを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/cecf11df-eacb-741f-b63f-3f2819f4bb55.png)

ブレード上部にある `その他` を押すと、[Multi-Factor Authentication](
https://account.activedirectory.windowsazure.com/usermanagement/multifactorverification.aspx) というリンクが出現します。

画面が見切れている場合に `その他` になる仕様っぽいので、画面が広い人はそのまま出てきそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/ce8869a7-3528-850e-17f1-a66302cb08bc.png)

リンクをクリックすると、旧ポータルで従来通りMFAを制御することが可能になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127585/a692e3e7-4949-f5cf-5daf-de555aa645f6.png)

##  念の為リンクをまとめておきます

誰かもやっていましたが、リンクもまとめておきます👀

旧ポータル
https://account.activedirectory.windowsazure.com/usermanagement/multifactorverification.aspx

新ポータル（すべてのユーザー　ブレード）
https://portal.azure.com/#blade/Microsoft_AAD_IAM/UsersManagementMenuBlade/AllUsers
gcloud コマンド チート

### GCE SSH

テンプレート

```bash
gcloud beta compute --project "%project_id%" ssh --zone "%region%" "%user_name%@%hostname%"
```

※%user_name%は自由に決められる、省略も可。省略した場合OSにログインしているユーザ名になる。

例

```bash
gcloud beta compute --project "xxxxx-xxxxxxx-123456" ssh --zone "asia-east1-a" "develop"
```

### Check Config
```bash
gcloud config list
```
ロバスト制御のお気持ち

今回はロバスト制御のお気持ちについて簡単に説明したいと思います。

## ロバスト制御とは
多くの制御理論では、制御対象を数式で表現する**モデリング**を行う。
現実の制御対象を正確にモデリングできていれば、設計時に要求した性能通りの挙動を示すことになるはずである。
ただし実際には、完全に正確にモデリングすることは不可能である。必ずモデル化に伴う誤差やモデル化ができない外乱や観測誤差などによりモデルと制御対象の間には乖離が生じてしまう。
そこで、制御対象の不確かさや変動に対しても強い、ロバストな制御のことをロバスト制御という。

## そもそもロバストって？
> ロバストネス
> 頑強性（がんきょうせい）や頑健性（がんけんせい）やロバストネス（英: robustness）やロバスト性とは、ある系が応力や環境の変化といった外乱の影響によって変化することを阻止する内的な仕組み、または性質のこと。
> (引用元：[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%90%E3%82%B9%E3%83%88%E3%83%8D%E3%82%B9))

## なぜロバスト制御をする必要があるのか
前々項でも説明した通り、制御対象のモデルには必ず誤差や外乱が付きまとうからである。
制御対象の経年による劣化や環境による性能の変動、モデル化の際に行なった近似や仮定などがモデルの誤差となる(制御対象のもつ不確かさや変動のことを**摂動という**)。
そのほかにも、制御器によってモデル化の際に近似などによってモデルに含まれなくなった共振モードなどを励起してしまう現象(**スピルオーバー**)や、制御器のゲインを上げることで外乱や観測誤差による影響が大きくなってしまったり、そもそも制御対象が応答できる周波数を超えてしまったりなどの問題が挙げられる。

以上の問題を制御対象のモデリングの際に考慮に入れることで、具体的にはモデルを変動や不確かさを持った集合として取り扱うことによって、摂動による影響がなるべく出ないような制御系設計を行うことで解決する(逆に確定的なものとしてモデリングしたものをのみなるモデルという)。
簡単に言い換えると、モデルにばらつきがあっても性能が出るように設計するということである。

## もうちょっと詳しく
ロバスト制御の代表的な手法として、主に二つ、$H_\infty$制御と$\mu$設計法を取り上げる。

- $H_\infty$制御
    - 設計者が決めた外部入力から制御量までの$H_\infty$ノルムが小さくなるように制御系を設計する
        - $H_\infty$ノルムは1入出力伝達関数ならばゲインの最大値に相当する
    - 摂動があっても制御系の内部安定性が必ず満たされるような設計問題(ロバスト安定化問題)を取り扱うことができる
    - ただし、制御系の性能自体は摂動によって変動しうるノミナル性能しか取り扱えない

- $\mu$設計法
    - $H_\infty$制御と異なり摂動による影響を抑える、ロバスト性能問題を取り扱うことができる
    - ただし、設計手順が複雑な上に制御器の次元が上がってしまう傾向にある

設計手順とそれに対応する性能のコスパの高さから、$H_\infty$制御が使われることが多いよう。

## まとめ
ロバスト制御のお気持ちについて軽くまとめてみました。
もう少し踏み込んだ内容は後日シミュレーションとともに投稿しようと思ってます。
ご質問、ご指摘等あればコメントお願いします。

## 参考文献
[実践ロバスト制御(コロナ社)](http://coronasha.co.jp/np/isbn/9784339033113/)
Linux基礎(ShellScript)

#シェルスクリプトとは
スクリプト(特定の処理を行うために作成したプログラム)をシェルプログラムで記述したもの。このシェルスクリプトを使用することで一連のコマンドライン作業を自動化することもできる。シェルスクリプトを記述するためには１行目に実行するシェルを宣言する。

```shell
#!/bin/bash
```

#実行コマンド(4種類)

```shell
# sourceコマンド
$ source testing.sh

# bashコマンド
$ bash testing.sh

# コマンドは省略してスクリプトファイルの前に「 . 」と入力してスクリプトを実行することも可能
$ . testing.sh

# シェルスクリプトファイルに実行権を与えた場合は、ファイル名を入力するだけで実行可能
$ ./testing.sh
```

#シェルスクリプトの特殊変数理解

|変数名|説明|
|---|---|
|$0|シェルスクリプトファイル名|
|$1|1番目の引数　※2番目の引数の場合は$2とする|
|$$|現在のシェルのプロセス番号|
|$#|コマンドラインに与えられた引数の数|
|$?|シェルが最後に実行したコマンドの終了ステータス(0=正常終了, 1=異常終了, それ以外はエラー)|
|$@|全ての引数(区切りはスペース)|
|$*|全ての引数(区切りは環境変数IFSで指定したもの))|

#ユーザ入力
##readコマンド
readコマンドはユーザからの入力値を受け取り、変数に格納してそれを次の処理で使用したい場合に使用するコマンド。

```shell
#!/bin/bash
echo -n "名前を入力してください。"
read yourname
echo "${yourname}さん。入力ありがとう。"
```


#条件分岐処理
条件分岐が行われる条件式の真偽を判断して結果を返す。

##条件式理解

- ファイル/ディレクトリに関する条件式

|条件式|実行結果|
|---|---|
|-d ディレクトリ名|指定したディレクトリがあれば真|
|-f ファイル名|指定したファイルが通常ファイルであり、存在すれば真|
|-s ファイル|指定したファイルのサイズが0より大きいファイルであれば真|
|-L ファイル|指定したファイルがシンボリックリンクであるファイルであれば真|
|-r ファイル|指定したファイルが存在して、かつ読み込み可能であれば真|
|-w ファイル|指定したファイルが存在して、かつ書き込み可能であれば真|
|-x ファイル|指定したファイルが存在して、かつ実行可能であれば真|
|-e ファイル|指定したファイルがあれば真|
|ファイル1 -nt ファイル2|指定したファイル1が、指定したファイル2よりも修正時刻が新しければ真|
|ファイル1 -ot ファイル2|指定したファイル1が、指定したファイル2よりも修正時刻が古ければ真|

- 文字列に関する条件式

|条件式|実行結果|
|---|---|
|-n 文字列|文字列の長さが0より大きければ真|
|-z 文字列|文字列の長さが0であれば真|
|文字列1 = 文字列2|文字列1と文字列2が等しければ真|
|文字列1 != 文字列2|文字列1と文字列2が等しくなければ真|

- 数値に関する条件式

|条件式|実行結果|
|---|---|
|数値1 -eq 数値2|数値1と数値2が等しければ真|
|数値1 -ne 数値2|数値1と数値2が等しくなければ真|
|数値1 -ge 数値2|数値1が数値2以上であれば真|
|数値1 -gt 数値2|数値1が数値2より大きければ真|
|数値1 -le 数値2|数値1が数値2以下であれば真|
|数値1 -lt 数値2|数値1が数値2より小さければ真|

- 論理結合に関する条件式

|条件式|実行結果|
|---|---|
|!条件|条件式が偽であれば真|
|条件1 -a 条件2|条件1と条件2の両方の条件式が真であれば真|
|条件1 -o 条件2|条件1と条件2のどちらかの条件式が真であれば真|

##if分岐
コードサンプル

```shell
#!/bin/bash
read number

if [ $number -gt 10 ]
then
  echo "10より大きい"
elif [ $number -eq 10 ]
then
  echo "10と等しい"
else
  echo "10より小さい"
fi
```

#繰り返し処理
##for文
繰り返しの処理を実行するためには for 文を使用。指定したリストに沿って処理を繰り返す。

コードサンプル

```shell
#!/bin/bash
Levels=("Level1" "Level2" "Level3")
echo ${Levels[@]}
for VAR in ${Levels[@]}
do
  echo LinuC $VAR
done
```

```shell
#!/bin/bash
for NUM in `seq 1 10`
do
  echo LinuC ${NUM}
done
```

##while文
条件文が真である間は、繰り返しの処理を実行するためには while 文を使用。

```shell
#!/bin/bash
while read LINE
do
  echo "LinuC Level ${LINE}"
done < test.txt
#リダイレクション　<　でテキストファイル test.txt からの入力に切り替えています。done < test.txt
#により、test.txtファイルの内容を読み込む処理を実行。そのファイル内容はLINE変数に1行
#ごとに読み込まれて格納される。readコマンドで読み込まれるLINE変数が空になるまで「真」と判断
#されて、最終行まで読み込んだ後は「偽」と判断されたwhile文が完了する。

```

##繰り返し処理で活用するコマンド
###seqコマンド
シェルスクリプトで、数値を1つずつ増加または減少させる処理を行うために利用するコマンド
 
```shell
# seq 開始数値 終了数値
$ seq 1 5
1
2
3
4
5

# seq 終了数値
$ seq 5
1
2
3
4
5
```

#その他
[シェルについてはこちら](https://qiita.com/kakkie/items/b690854ab1629d97c22f)
Videojs 7 + RTMP の使用法

##はじめに
こんにちは streampack チームのメディです。
https://cloudpack.jp/service/option/streampack.html

<img width="670" alt="Screen Shot 2019-10-04 at 10.39.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/9de4310f-2b02-1332-4d85-55fc9fb67a19.png">

<img width="670" alt="Screen Shot 2019-10-04 at 10.52.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/f6a1c7be-ebd6-7d76-8538-a68ba4bce168.png">

<img width="670" alt="Screen Shot 2019-10-04 at 10.51.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/5323b4de-029a-0f8c-e83d-520543cd2ffa.png">





##Objective・目的
Learning how to use videojs + RTMP through a simple example.
videojs + RTMPの簡単な例を学ぶこと。



##A simple implementation ・ 簡単な実装
<img width="669" alt="Screen Shot 2019-10-04 at 10.40.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229807/be07f494-a0ca-2e6d-043f-2921687db3f4.png">

```html
<!DOCTYPE html>
<html>

<head>
  <title>Videojs 7 + RTMP  (flash)</title>
  <meta charset="utf-8">
  <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/video.js/7.6.5/video-js.min.css" />
  <script src="//cdnjs.cloudflare.com/ajax/libs/video.js/7.6.5/video.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/videojs-flash/2.1.2/videojs-flash.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/videojs-flashls-source-handler@1.1.2/dist/videojs-flashls-source-handler.min.js"></script>
</head>

<body>
  <video class="video-js vjs-default-skin" id="video-container" controls muted autoplay >
    <source src="rtmp://fms.105.net/live/rmc1" type="rtmp/mp4">
  </video>
</body>
<script>
  var options = {
    flash: {
      swf: '//cdnjs.cloudflare.com/ajax/libs/videojs-swf/5.4.2/video-js.swf'
    },
    fluid: true
  };
  var player = videojs('video-container', options);
</script>

</html>
```

#### Compatibility ・ウェブブラウザの互換性
|       Browser |    Compatibility   |
|:-----------------:|:------------------:|
|Safari 12 Desktop|YES|
|Firefox 69 Desktop|YES|
|Chrome 74 Desktop|YES|




##Information sources ・ 情報源
https://www.wowza.com/community/questions/50896/live-247-rtmp-stream-demo-url.html
https://github.com/videojs/video.js
JavaScript　覚えておくべき注意点！（２）　条件分岐について　if文で条件分岐　例・ピザ屋注文

# if文は条件文の基本

if文は「もし～ならば～する」で、基本文です。「～ならば」という部分を「条件式」と言います。

```javascript:if.js
var budget = 2000;
if (budget >= 1500) {
    alert('ピザを注文します');  // budgetは2000で、1500以上なのでこの行は実行されます。
}
/* 上の文は、「所持金：budget」は2000ですと、宣言し。
「if(もし)」「budgetが1500以上（ならば）」、「alert（'ピザを注文します'）」
という意味を表わしています。 */
```

条件式の結果は「true」か「false」になります。

#条件式の基本は、左辺と右辺の比較です。
if (budget >= 1500) { }
例えば上記の >= が比較演算子といいます。
下記は比較演算子一覧です。

```javascript:hikaku.js
===  // 厳密に等しい
==   // 等しい
!==  // 厳密に等しくない
!=   // 等しくない
>    // ～より大きい
>=   // ～以上
<    // ～より小さい
<=   // 以下
```

#所持金に応じて注文結果を分岐させてみる
入力ダイアログボックスで受け取ったデータは全て文字列です。
そのため正しい計算が出来ない場合があります。
こうした場合、データ型を変換する便利な関数があります。
a = parseFloat(a);　です。


```javascript:app.js
var budget = prompt('所持金を数字で入力してください');
budget = parseFloat(budget);
if (budget >= 1500) {
    alert('ピザを注文しました');
}
```

#if文の応用的な書き方を学びましょう
「if~else文」「if~else if文」「if文の組み合わせ」

```javascript:if-else.js

//　「if ~ else 文」 
if (条件式) {
    条件式が真のとき行う処理
} else {
    条件式が偽の時に行う処理
}

// 「if ~ else if 文」
if (条件式１) {
    条件式が１のときに行う処理
} else if (条件式２) {
    条件式が１で偽で、条件式２が真のとき行う処理
  ⋮
}

// 「if文の組み合わせ」
if (条件式１) {
  条件式１が真のときに行う処理
    if (条件式２) {
　　　　条件式１～２真のときに行う処理
    } else if(条件式３) {
       条件式２が偽で、条件式１、３が真のときに行う処理
    } else {
       条件式２～３が偽で、条件式１が真のときに行う処理
    }
}
```

#ケースごとに条件を分けてみる

```javascript:pizza.js

var budget = prompt('所持金を数字で入力してください');
budget = parseFloat(budget);
if (budget >= 1500) {
    alert('ピザを注文しました');
} else if (budget >= 500) {
    alert('ポテトを注文しました');
} else {
    alert('節約、節約...');
}

```
UnityでOSC受信をつかう備忘録

OSC経由でUnityを動かしたい。

いろいろやり方があるかと思いますが、
keijiroさんのOscJackを使った場合の備忘録になります。

環境；
Unity 2017.4.28f1
Mac 10.14.6

# OscJackのインストール
https://github.com/keijiro/OscJack
からReleseのリンク先にあるunitypackageをダブルクリックしてUnityにインポート。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/6185e49b-6da4-caf1-c3d1-b95d0f7d485a.png)

Assetsの下にOscJackのフォルダが追加される。

# Unityの準備

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/48b88de0-64aa-b90a-c4ee-cefb5bdf7dfd.png)

ADX2の操作をOSC経由でしたかったので、スクリプト名が
Adx2OscConnectになってますが、用途に合わせた名前にしておくとよいです。

空のオブジェクトを作って、スクリプト追加します。

## スクリプト

``` Adx2OscConnect.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using OscJack;

public class Adx2OscConnect : MonoBehaviour {

    public GameObject go;

    private OscServer _server;
    private Vector3 _pos;
    private string _dspBusName;

    // Use this for initialization
    void Start () {

        _server = new OscServer(9002); // Port number

        _server.MessageDispatcher.AddCallback(
            "/pos/x",
            (string address, OscDataHandle data) =>
            {
                _pos.x = data.GetElementAsFloat(0);
            }
        );
        _server.MessageDispatcher.AddCallback(
            "/pos/y",
            (string address, OscDataHandle data) =>
            {
                _pos.y = data.GetElementAsFloat(0);
            }
        );
        _server.MessageDispatcher.AddCallback(
            "/pos/z",                   
            (string address, OscDataHandle data) =>
            {
                _pos.z = data.GetElementAsFloat(0);
            }
        );
        _server.MessageDispatcher.AddCallback(
            "/dsp",
            (string address, OscDataHandle data) =>
            {
                _dspBusName = data.GetElementAsString(0);
                CriAtomEx.AttachDspBusSetting(_dspBusName);
            }
        );
    }

    private void OnDestroy()
    {
        _server.Dispose();
    }

    // Update is called once per frame
    void Update()
    {
        //_light.color = _color;
        //_light.transform.eulerAngles = _rot;
        go.transform.localPosition = _pos;
        //Debug.Log(_pos);
    }
}

```
ポートを決めて、メッセージがきたら、内容を書き換えるという動作。

Updateで
関連されたCubeの座標が更新されます。

# 送信側のMax

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96808/0ed1f56f-5444-add8-1110-0282bf4e6c4a.png)

いろいろ書いてありますが、
udpsend オブジェクトにoscの文字列を流し込むことで、OSCが飛ばせます。

OSCが飛ばせるツールで同じような内容で接続して飛ばせばいろいろな端末から動かせます。

## 実際に動かしている様子

https://twitter.com/tatmos/status/1167700277916397568?s=20




#2021年に使ってみた

- 最近のはインストールの仕方が違う（PackageManagerのjsonを書き加える）

サーバースレッドで動いているので、UniRx使うと楽にメインスレッドに持っていけます
Updateで値変えなくてもいける

``` .cs
        _server.MessageDispatcher.AddCallback(
            "/pos/x",
            (string address, OscDataHandle data) =>
            {
                _pos.x = data.GetElementAsFloat(0);
                MainThreadDispatcher.Post (_ => go.transform.localPosition = _pos, null);
            }
        );
```
Linux基礎(Shellについて)

#シェルとは
コマンドを解釈して実行するプログラムのこと。Linuxシステムの作業は端末で行うがLinuxシステムへのログイン時に端末ごとに入力するコマンドを解釈し、実行するプログラム(シェル)が動作し始める。シェルはいくつかの種類があり、ユーザは好みに応じて実行するシェルを選択できる。
Linuxで利用できるシェルには以下のような種類がある。一般的にはBashが利用される。

|シェル|プログラム名称|説明|
|---|---|---|
|Bシェル|sh|UNIX V67(1978年リリース)から標準添付されているUNIXの基本的なシェル|
|Cシェル|csh|C言語スタイルの構文を持ったUNIX系OSの代表的なシェル|
|TCシェル|tcsh|Cシェルの派生版の中で特にユーザーインターフェイス部分を中心に拡張されたシェル|
|Kシェル|ksh|Bシェルと上位互換を保ちながら、Cシェルなどから優れた機能を取り込んだシェル|
|Bash|bash|UNIX系のシェルの一つであり、Linuxで用いられている標準のシェル|

システムへのログイン直後に起動するシェルは、ログインシェルと呼ばれていて、これはユーザごとに定義できる。ユーザごとのログインシェルは、/etc/passwdファイルに記述されている。以下では、adminというユーザのログインシェルが「bash」であることがわかる。

```shell
# ログインシェルの確認
$ more /etc/passwd
admin:x:500:500:CentOS-6.4-i386:/home/admin:/bin/bash

# 現在ログインしている自身が使用しているシェルは ps $$ コマンドで確認すること
$ ps $$
　PID　　 TTY 　　STAT　 TIME　 COMMAND
　17264 pts/1　S 　　　 0:00 　-bash
```

作業終了を通知しシェルを終了するためにはlogoutコマンドを入力。exitコマンドでもシェルは終了。

#コマンドの入力方法

|入力キー|説明|
|---|---|
|Tabキー|コマンドやディレクトリ名などをの文字列を補完する|
|Ctrl + A|行の先頭へカーソルを移動する|
|Ctrl + C|実行処理を中断する|
|Ctrl + D|カーソル上にある文字列を1文字削除する|
|Ctrl + E|行の最後へカーソルを移動する|
|Ctrl + H|カーソルの左側の文字列を1文字削除する|
|Ctrl + L|画面をクリアして、現在の行だけ再表示する|
|Ctrl + Q|画面への出力を再開する|
|Ctrl + S|画面への出力を停止する|
|Ctrl + Z|実行処理を一時停止する|

シェルがbashである場合、以下の特殊記号(メタキャラクタ)を使用してディレクトリの移動が可能。

|メタキャラクタ|説明|
|---|---|
|.|カレントディレクトリを表す|
|..|一つ前のディレクトリを表す|
|~|ホームディレクトリを表す|

#メタキャラクタとは
複数のファイルを簡単に指定する際に使用する特殊な記号のこと。メタキャラクタにより個別にファイルを指定することなく複数のファイルを指定できる。メタキャラクタには次の記号がある。

|メタキャラクタ|説明|
|---|---|
|*|任意の0文字以上の文字列<br>例｜111.txt、abc.txtのファイルは「*.txt」と表せれる|
|?|任意の1文字の文字列<br>例｜1.txt、a.txtのファイルは「?.txt」と表せれる|
|[ ]|[]の任意の1文字の文字列<br>例｜aa.txt、ab.txt、abc.txtのファイルは「[abc].txt」と表せれる|
|{ }|カンマで区切られた文字列<br>例｜data1、data2は「data{1,2}」と表せれる|
Ruby の fork と spawn を試す

/proc/{PID}/ 配下の情報について Ruby で fork/spawn をした時の違いを確認した時のメモ
(あくまで個人用のメモです）

# 環境

+ OS:amzn2-ami-hvm-2.0.20180810-x86_64-gp2 (ami-08847abae18baa040)


```bash
$sudo amazon-linux-extras install ruby

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
```

# /proc{PID} 配下の情報について

以下にまとまった情報あり

[E.3. /proc/ 内のディレクトリ](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/deployment_guide/s1-proc-directories)


+ /proc/配下には様々な情報があるが、/proc/{PID} という形式でプロセスが生成されるとディレクトリが作成され、配下にプロセスに関わる情報が格納されている
+ {PID} = プロセス ID。プロセスを生成すると生成される ID
+ プロセスが終了すると、そのプロセスの /proc/ プロセスディレクトリはなくなる

なお、今回確認したかった `cmdline` は以下のように書いてある

> cmdline — プロセスを起動した際に発行されたコマンドが格納されています。 


# fork してみる

[module function Kernel.#fork](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/fork.html)

>fork(2) システムコールを使ってプロセスの複製を作 ります。親プロセスでは子プロセスのプロセスIDを、子プロセスでは nil を返します。ブロックを指定して呼び出した場合には、生成し た子プロセスでブロックを評価します。 


内部的には fork(2)のシステムコールを呼び出しているようであり、確認。
上記のサンプルコードを少し修正。

```fork.rb
child_pid = fork do
  puts "child process. pid: #{Process.pid}"
  sleep(1)
end

puts "parent process. pid: #{Process.pid}, child pid: #{child_pid}"
r = `cat /proc/#{child_pid}/cmdline`
puts r

Process.waitpid(child_pid)
```

実行すると以下のような感じ

```bash
$ruby fork.rb
parent process. pid: 2794, child pid: 2795
child process. pid: 2795
rubyfork.rb
```

`/proc/{PID}/cmdline` は `rubyfork.rb`となっている。
上記のコードの場合、処理しているのは sleep だが、実行しているのは Ruby のコードという為だと思われる（違ったらご指摘下さい）

# spawn してみる

[module Process](https://docs.ruby-lang.org/ja/latest/class/Process.html)

>関数 Kernel.#spawn と同じです。 

[module function Kernel.#spawn](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/spawn.html)

>引数を外部コマンドとして実行しますが、生成した 子プロセスの終了を待ち合わせません。生成した子プロセスのプロセスIDを返します。 

こっちの場合どうなるのか。

```spawn.rb
child_pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, 'sleep 10')
puts "parent process. pid: #{Process.pid}, child pid: #{child_pid}"
r = `cat /proc/#{child_pid}/cmdline`
puts r

Process.waitpid(child_pid)
```

```bash
$ruby spawn.rb
parent process. pid: 2894, child pid: 2895
sleep10
```

こうなる。
こっちの場合、`spawn(env,command)`でよばれて command が cmdline に指定されているという点が違う。
親プロセスID と生成された子プロセスIDが違うのは同じ。

`spawn` は Linux のコマンドとして存在する。
一方、 fork はシステムコールという所が違うのだろうか。

# TODO

以下辺りの情報など関連する情報を集めてもう少しまとめたい。。。
(fork,spawn,thread...)

+ [fork](https://ja.wikipedia.org/wiki/Fork#Fork-Exec)
+ [コンピューター：C言語講座：マルチスレッドについて](http://www.ncad.co.jp/~komata/c-kouza28.htm)
strlen()の挙動について

#strlen()

##事件
本番稼働中のシステムの改修をしてると
以下の記述がありました。
（変数名は実際のものから変更しております。）

```
if (isset($data['content']) && strlen($data['content'] > 0)) {
    // うんたらかんたら
}
```

```
strlen($data['content'] > 0)
```

えっなにこれ
こわい

なにがこわいって本番稼働してるうえに今のところバグとされる報告もないし、
テストしても問題なかったんですよね。

#挙動を試す

##値がある場合

```
$array = array('content' => 'こんてんと', 'title' => 'たいとる');
echo '正：';
echo strlen($array ['content']) > 0 ? 'true' : 'false';
echo '<br>誤：';
echo strlen($array ['content'] > 0) ? 'true' : 'false';
```
結果

```
正：true
誤：true 
```

ふぇーっ

##値がある場合（数値）

```
$array = array('content' => '10', 'title' => '0');
echo '正：';
echo strlen($array ['content']) > 0 ? 'true' : 'false';
echo '<br>誤：';
echo strlen($array ['content'] > 0) ? 'true' : 'false';
```
結果

```
正：true
誤：true 
```

うーん。。。

##値がない場合

```
$array = array('content' => '', 'title' => 'たいとる');
echo '正：';
echo strlen($array ['content']) > 0 ? 'true' : 'false';
echo '<br>誤：';
echo strlen($array ['content'] > 0) ? 'true' : 'false';
```
結果

```
正：false
誤：false 
```

えっいいのこの書き方で。。。？

##値が0

```
$array = array('content' => 0, 'title' => 10);
echo '正：';
echo strlen($array ['content']) > 0 ? 'true' : 'false';
echo '<br>誤：';
echo strlen($array ['content'] > 0) ? 'true' : 'false';
```
結果

```
正：true
誤：false 
```

まあそうなりますわな。

#結論

括弧の閉じる位置には気をつけましょう。
今回はUI上数値ではなく文字列が入るか入らないかという作りをしていたのでたまたまよかったようです。
優秀なプログラマーになるために！

◎とても参考になるいい記事です。


私的な重要ポイント！

『自己満』と、
『自分を開示する』、
『続ける』

これが、
優秀なプログラマーになるための
キーワードです！

詳細は下記のURLから
ご閲読いただけましたら、
幸甚にございます。

ご閲読ありがとうございます。

https://gist.github.com/shyouhei/266178ffedab5767a5b69b972c76f88a
AWS Lambda + SSM Parameter Store でカウンターを作る

事の発端はこのツイートを見たこと。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">目的外利用な気はしますが SSM Parameter Store はどうでしょう</p>&mdash; fujiwara (@fujiwara) <a href="https://twitter.com/fujiwara/status/1174550086111485955?ref_src=twsrc%5Etfw">September 19, 2019</a></blockquote>

今まで Lambda を使っていて「データベースを用意するほどじゃないけどちょっとした情報を保存したい」と思うケースが多々あって、もっともカジュアルな方法はなんだろうかと考えていたところだった。

「ちょっとした情報の保存先」として SSM Parameter Store を使うアイデアは面白そうだと思ったので、試しに AWS Lambda + SSM Parameter Store でカウンターを作ってみた。

## Lambda Function の実装
SSM Parameter Store に値を保持してカウントアップするだけの素朴な Lambda Function を作った。ランタイムは Python 3.7。

``` python
import boto3

ssm = boto3.client('ssm')

def get_param(key: str) -> str:
    global ssm
    try:
        return ssm.get_parameter(Name=key)['Parameter']['Value']
    except ssm.exceptions.ParameterNotFound:
        return None

def set_param(key: str, value: str):
    global ssm
    ssm.put_parameter(Name=key, Value=value, Type='String', Overwrite=True)

def lambda_handler(event, context):
    key = 'counter'
    count = int(get_param(key) or 0)
    count += 1
    set_param(key, str(count))
    return count
```

## Role の設定
このままでは Lambda Function から SSM Parameter Store にアクセスする権限がないので、以下のようなポリシーを持つ IAM Role を作成して Lambda Function に割り当てる。

``` json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                "ssm:GetParameter"
            ],
            "Resource": "arn:aws:ssm:*:*:parameter/counter"
        }
    ]
}
```

権限を最小限にするために `counter` という名前のパラメータの読み書きのみができるようにした。

## 実行
Lambda Function を実行するたびにカウンターの値が 1 ずつ増えていくことが確認できると思う。

DynamoDB や S3 に保存するよりもはるかに簡単にできたので、「ちょっとした情報の保存先」として SSM Parameter Store を使うアイデアはかなりアリだなと思った。
Python is と == の違い

# はじめに
投稿した記事のコメントで **is と == の違い** について教えていただきましたので、それについてまとめたいと思います。
（ミュータブル/イミュータブルとかの値のややこしい話とかは抜きにしてまとめてみました。）

# １．== で比較しているもの
今まで vba や C を書く機会が多く、比較するときには==を使う習慣が身についてしまっていたわけですが、、、
pythonにおいて**==で比較しているのは変数の値そのもの**だそうです。

ですので、次のような場合はTrueとなります。

```Python:code.py
a=[1,2]
b=[1,2]
print(a==b)
```


```Python:Result
True
```

#２．is で比較しているもの
Pythonに限らずオブジェクト指向のプログラミング言語には、オブジェクト、クラス、インスタンスといった概念があります。ざっくりいうと、オブジェクトは枠、クラスは設計書、インスタンスはモノといったイメージになると思います。
（オブジェクト＝焼き菓子、クラス＝クッキーの作り方、インスタンス＝クッキー（完成品）的な関係）

インスタンスとかややこしいことを言っていますが、 a = 10 とか何気なく変数に値を代入するだけでもインスタンスが作られています。

Pythonでは、**isは、インスタンス同士のidが同じか否かを判断**します。
idはid(変数)で調べることが出来ます。


```Python:code.py
a="cookies" #"cookies"のidをaに格納
b="cookies" #"cookies"のidをbに格納
A=["cookies"] #動的にメモリを確保し、確保したメモリに"cookies"を格納 → idは動的に確保した場所を示す
B=["cookies"] #動的にメモリを確保し、確保したメモリに"cookies"を格納 → idは動的に確保した場所を示す

print(id(a),id(b))
print(a is b) #idの比較
print(a==b) #値の比較
print(id(A),id(B))
print(A is B)
print(A==B)
```


```Python:Result
2737112766312 2737112766312 #ここの二つの値が同じ
True
True
2737112556296 2737111787336 #ここの二つの値が異なる
False
True
```

#まとめ
is と == の二つの目線で変数を比較出来ることを学びました。
 is は変数の id を比較し、 == は 変数の値そのもの を比較するようです。

C言語とかのポインタとかアドレスとかの話を、オブジェクト指向プログラミングで話すと今回の内容のような話になりそうですね。すごくややこしい反面、こうゆうところを気にしてコーディングできると綺麗なコードがかけるんだろうな～とか思いました！
Thinkpad X240 on Ubuntu18.04 で TouchPad のボタン機能以外を無効化する 


「ワークショップ用PCを USB起動の Ubuntu で構成する」
https://qiita.com/nanbuwks/items/785a28b6baf3a77cae5b

「Ubuntu18.04 で MINECRAFT」
https://qiita.com/nanbuwks/items/df10bba9f0ed473827d7

などのために、ここ数年は中古の ThinkPad X220 や X230 を20台ぐらい運用していました。

しかしそろそろ X240 以降に世代交代することを考え、ThinkPad X240 の中古を購入してみました。


Ubuntu18.04 で使ってみます。

# TouchPad が殺せない

当然ながら TouchPad は BIOSで無効化し・・・なんて事だ、BIOS設定しても、Ubuntu だと ToudhPad が動作してしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/174c0b8e-c4ad-5239-6e69-7338431719a9.png)


# 設定を探してみました。

まずは先人の知恵を拝借しようとしてみました。しかし、Ubuntu17以前とUbuntu18以降とは動作が異なっていてそのままでは使えそうにありません。
また、ぐぐった内容自体も、真ん中ボタンを有効化する方法が多く、TouchPadを無効化するのはあまりありません。

TouchPadを無効化したらボタン機能も無効化してしまうなど。意外と難しいことがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4d51de52-e41f-7ba7-de73-d17c2b1670a5.png)
Helplessness.jpg  Creative Commons Attribution-Share Alike 4.0 International
# いかがでしたか？

やっぱりみんな苦労しているみたいですね。でも、これだけ関心があるなら誰か解決していても不思議ではありませんね。
これからも、ウォッチしていきたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/aea4b514-ab23-8bc8-ffed-0f310baa5ccd.png)
Smile.jp.jpg Creative Commons Attribution-Share Alike 4.0 International

・・・というところで終わりにしようと思いましたが、やはりTouchPadの挙動は気が狂いそうになるので、気合で解決しました。

# 行った設定

結論のみ述べると、以下のようにしてOKとなりました。

```

$ xinput --set-prop "SynPS/2 Synaptics TouchPad" 279 0
$ xinput --set-prop "SynPS/2 Synaptics TouchPad" 281 0
$ xinput --set-prop "SynPS/2 Synaptics TouchPad" 144 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 1.000000


```
[Power BI] ドリルスルーとツールヒント

#Power BI でのドリルスルーとツールヒント
今回は短編です。最新情報でもありません。でも良く質問を頂くことなので、Tips 的に載せておきます。
Power BI でもドリルスルーとツールヒントが使いたいという方はご参考に。

#出来上がりのイメージ
##まずはデータ
今回は Excel で簡単なデータを作ってみました。画像は Power BI Desktop で読み込んだデータの画像です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152946/8402a189-ffc2-6dd9-4c1a-00d6ac6104d3.png)

##次にドリルスルー
**ドリルスルー** は **テーブル** と **マトリックス** を **ドリルスルー元** に、**ページ** を **ドリルスルー先** にすることができます。
ドリルスルー元のテーブル上で **[特定の行を右クリック]** - **[ドリルスルー]** - **[ページ名(今回はドリルスルー先というページ)]**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152946/c5fc4861-9731-a483-f43f-646957854f28.png)

ドリルスルー先のページに飛ぶ。
**Power BI Desktop 上** だと **Ctrl + 左上の←** をクリックすると、**ドリルスルー元** に戻ります。
**Power BI Service** に発行すると、**左上の←** をクリックするだけで、**ドリルスルー元** に戻ります。この動作をカスタマイズすることも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152946/3e36c58a-4a18-a7e0-f680-a51009ace7b1.png)

#そしてツールヒント
**ツールヒント** は **テーブル** や **マトリックス** ではもちろん使えますし、**その他のビジュアル（グラフ）** でも全てではないですが使えます。
ビジュアルにマウスを載せると紐づくデータをホバーで表示してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152946/da852f55-73f9-77a9-ec52-f21875d4be79.png)


#本題
Japan Power Platform User Group (https://power.users.community/) で

[カウントにドリルスルーしてその人たちの目録を見たい]
https://power.users.community/forums/topic/%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AB%E3%83%89%E3%83%AA%E3%83%AB%E3%82%B9%E3%83%AB%E3%83%BC%E3%81%97%E3%81%A6%E3%81%9D%E3%81%AE%E4%BA%BA%E3%81%9F%E3%81%A1%E3%81%AE%E7%9B%AE%E9%8C%B2%E3%82%92/

こんな質問がきてたので試しにやってみました

[内容]
データソース: 
Drill Through と Toolhint.xls
https://www.facebook.com/groups/JapanPBUG/permalink/2124131571227639/

Power BI レポート: 
Drill Through と Toolhint.pbix
https://www.facebook.com/groups/JapanPBUG/permalink/2124130857894377/

pbix には メイン、ドリルスルー先、ツールヒント という３つのページがあります。
メインのマトリックスにドリルスルーとツールヒントを設定してあります。

#ドリルスルーとツールヒントの設定方法
以下のページを見てください。一度やると簡単に覚えられます。

[Power BI レポートに ドリルスルー ページを設定するには by Takeshi Kagata ( @PowerBIxyz )]
https://qiita.com/PowerBIxyz/items/eeb0b422113be27b85ec

[Power BI Desktop でドリルスルーを使用する]
https://docs.microsoft.com/ja-jp/power-bi/desktop-drillthrough

[Power BI Desktop のレポート ページを基にしてヒントを作成する]
https://docs.microsoft.com/ja-jp/power-bi/desktop-tooltips

ご参考までに！
Visual Studio Code初期設定

# VSCode初期設定
再セットアップしたので初期設定メモ

## 設定
setting.jsonの中身

```json:setting.json
{
    "files.autoSave": "afterDelay",
    "files.insertFinalNewline": true,
    "files.trimFinalNewlines": true,
    "files.trimTrailingWhitespace": true,
    "editor.renderControlCharacters": true,
    "editor.wordWrap": "on",
    "editor.renderWhitespace": "all",
    "breadcrumbs.enabled": true,
    "workbench.useExperimentalGridLayout": true,
    "workbench.colorTheme": "Tomorrow Night Blue",
    "workbench.iconTheme": "vscode-icons",
    "workbench.sideBar.location": "left"
}
```

## 拡張パッケージ

- indent-rainbow
- Markdown Preview Enhanced
- Output Colrizer
- Prettier - Code formatter
- Ranbow CSV
- vscode-icons
- Docker

# Color Theme

`Ctrl + Shift + p`で`Preferences: Color Theme`
または、`Ctrl + K` -> `Ctrl + T`

お気に入りはdark系の`Abyss`
k8sのような略語

技術文章では、k8s(Kubernetes)のような用語はよく見られますね。
ちなみに、以外にも以下の略語があります。
18n = internationalization 
l10n = localization 
a11y = accessibility 
k8s = Kubernetes 
i14y = interoperability 
o16n = Operationalization
m11y = measurability 
o11y = observability
数字は省略したアルファベットの数らしいです。
FirebaseAnalytics イベント名のバリデーション

FirebaseAnalyticsのイベント名は使用できる文字に制約があるが、無効な文字列が使われてても気づかないので、Unit Testで検知するようにした。
FirebaseAnalyiticsの導入に関しては記載しない。

* Xcode11.1
* Swift5

イベント名はenumでどこかに纏めて記述しておく。
送信箇所が多いと結構長いリストになる。

```Swift
enum EventName: String, CaseIterable {
    case tapHoge = "tap_hoge"
    case tapFuga = "tap_fuga"
    ...
}
```

# :books: バリデーション

制約はframework内の `FIRAnalytics` に以下の記述がある。

```
Should contain 1 to 40 alphanumeric characters or underscores.
The name must start with an alphabetic character.
Some event names are reserved. See FIREventNames.h for the list of reserved event names.
The "firebase_", "google_", and "ga_" prefixes are reserved and should not be used.
```

* 1 ~ 40文字の英数字か_（アンダースコア）で構成されていないとならない
* アルファベットで始まらなければならない
* いくつかのイベント名は `FIREventNames.h` で定義されている
  * 被っても問題なさそうなのでスルー
* "firebase_", "google_", "ga_" から始まってはいけない

# :green_heart: テストコード

上記条件をそのままテストコードにした。

```Swift
func testLogEventNames() {
    let analyticsReservedPrefix = ["firebase_", "google_", "ga_"]
    EventName.allCases.forEach { (name) in
        // !length.isEmpty && length <= 40
        XCTAssertTrue(!name.rawValue.isEmpty && name.rawValue.count <= 40, "Length error: \(name.rawValue)")
        // alphanumerics or "_"
        XCTAssertTrue(name.rawValue.isAlphanumericOrUnderscore, "String error: \(name.rawValue)")
        // has prefix alphabetic
        XCTAssertTrue(name.rawValue.hasPrefixLetter, "Prefix error: \(name.rawValue)")
        // not has prefix "firebase_", "google_", and "ga_"
        XCTAssertTrue(analyticsReservedPrefix.filter({ name.rawValue.hasPrefix($0) }).isEmpty, "Prefix error: \(name.rawValue)")
    }
}
```

```Swift
private extension String {
    var isAlphanumericOrUnderscore: Bool {
        // _でCharacterSetを用意
        let underscoreCharacterSet = CharacterSet(charactersIn: "_")
        // 英数字と_のCharacterSetを結合
        let characterSet = CharacterSet.alphanumerics.union(underscoreCharacterSet)
        // 空じゃない、且つ用意したCharacterSet以外が含まれない
        return !isEmpty && rangeOfCharacter(from: characterSet.inverted) == nil
    }

    var hasPrefixLetter: Bool {
        let prefix = self[startIndex...index(startIndex, offsetBy: 1)]
        // 空じゃない、且つアルファベット以外が先頭文字ではない
        return !isEmpty && prefix.rangeOfCharacter(from: CharacterSet.letters.inverted) == nil
    }
}
```

Unit TestはCIでプルリク時点で走るようになってるので
新規にenumにイベント名を追加したプルリク生成時にバリデーションされるようになった。

FirebaseAnalyticsのイベント名の制約仕様に変更があった場合に追随できないのでそこはご注意。
大量のgit branch を断捨離するなら

#過去のbranchを漁りたいのに...

```
$ git branch
feature-a
feature-b
feature-c
feature-d
feature-e
feature-f
feature-g
feature-h
...
```

### ブランチ切りすぎ、残しすぎ

いらないのを消したい...あれ？どのbranchが生きてるんだっけ？作業してたbranchどれだっけ？

### とにかく直近作業してたブランチだけを参照したい場合
```
$ git branch --sort=authordate
```


### mergeされてないものは無条件で -d
```
$ git branch --merged|egrep -v '\*|develop|master'|xargs git branch -d
```

なるべく早めにbranch整理しましょう。
swift開発備忘録①

#概要
swift開発を始めた際に、覚えていたほうが良さそうなものを備忘録としてまとめていきます。
まだまだ駆け出しなので、分かっていないことも多いかと思いますが、参考程度になればと思います。

#プロジェクト作成時に、デフォルトで生成されるファイル
####AppDelegate.swift
アプリが起動した時や、バックグラウンドに行った時などの状態に応じて何らかの処理を書くためのファイル
####ViewController.swift
画面に対する処理を書くためのファイル
####Main.storyboard
画面の編集をするファイル
####Assets.xcassets
アイコンや画像などを管理するフォルダ
####LaunchScreen.storyboard
アプリが立ち上がったときにつらっと表示される画面を作るためのファイル
####Info.plist
アプリに関する設定をまとめていくためのファイル
pipで更新可能なパッケージを一括でアップデートする

次のコマンドを使うと，pipでアップデートがあるパッケージの一覧を表示することができます．

```bash
pip list -o
```

このコマンドの出力を使って，パイプでコマンドをつなげることで，一括アップデートのワンライナーを作りました．これを実行することでpipで更新可能なパッケージを一括でアップデートすることができます．

```bash
pip list -o | tail -n +3 | awk '{ print $1 }' | xargs pip install -U
```

コマンドのaliasを追加するとより便利に使えます．`~/.bash_profile`, `~/.zprofile`などに次の一行を追加すると，`pip-upgrade-all`ですべてのパッケージをアップデートできます．

```bash
alias pip-upgrade-all="pip list -o | tail -n +3 | awk '{ print \$1 }' | xargs pip install -U"
```