OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Elastic Load Balancing(ELB) 概要

AWS Elastic Load Balancing(ELB)の概要をまとめる。学習目的兼備忘録。

## Elastic Load Balancing とは

* アプリケーションへのトラフィックを複数のターゲットに自動的に分散するAWSのロードバランシングサービス

* ３種類のロードバランサーを提供

  * Application Load Balancer(ALB)
    * リクエストレベル (レイヤー 7)で動作
    * リクエストがどのように転送されるかを条件とアクションで定義可能(コンテンツベースルーティング)
  * Network Load Balancer(NLB)
    * 接続レベル (レイヤー 4) で動作
    * 高度なパフォーマンスと静的IPが必要な場合に使用
  * Classic Load Balancer(CLB)
    * 旧世代LB
    * EC２-Classic ネットワーク内で構築された既存のアプリケーションがある場合に使用
      * 互換性などの問題がなければ、ALB or NLBを選ぶのがよい。

* 全体イメージ

![ELB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/3ea2a485-7ebd-91f2-2256-8b3fd35a8a9f.png)

  * リスナー
    * ロードバランサーがListenするプロトコル及びポート番号
    * ロードバランサーからターゲットへの接続用のプロトコル及びポート番号
  * ターゲット
    * ロードバランサーがトラフィックを転送するEC2インスタンスなどのリソースやエンドポイント



## ELBの特徴

### 高可用性と負荷分散

#### 複数AZへの分散

1. DNSラウンドロビンで各AZ内のELBに振り分け
2. 負荷が均等になるように、ターゲットへそれぞれのルーティングアルゴリズムで振り分け

#### クロスゾーン負荷分散

* リージョン内の複数AZに負荷分散可能
* AZごとのターゲット数が異なっても、負荷を均等に振り分けることができる

#### 複数ポートへの負荷分散

* 同一インスタンス内の異なるポートにバランシング可能

* サーバーの冗長化と組み合わせ、サービスの可用性を向上
  * 受信トラフィックが複数のAZにある複数のターゲットに分散され、正常なターゲットのみトラフィックを受信
  * リージョン内での負荷分散が可能となり、異なるアベイラビリティーゾーンにある健全なターゲットにトラフィックをルーティング
  * SLA：99.99％ 

#### スケーリング 

* ELB自体も負荷に応じてキャパシティを自動増減
  * スケール時には、NLB以外はIPアドレスが変化するため、ELBへのアクセスには必ずDNS名を指定



### ヘルスチェック

* 正常なターゲットにのみ、トラフィックをルーティング
* ターゲットに対して定期的にヘルスチェックを実施し、正常なターゲットかを判定



### コネクション

#### コネクションタイムアウト

* 無通信状態が続くとそのコネクションを自動切断
  * タイムアウト時間は設定可能

#### スティッキーセッション

* 同一ユーザーから来たリクエストを同じターゲットに送信
* アプリケーションのセッション情報などをターゲットが保持する構成の場合に必要



### セキュリティ

#### SSL/TLSTemination

* ELB側でSSL/TLS認証を行うことが可能

##### 通信パターン

1. ELBでSSL Terminationし、バックエンドとはSSLなし
   * バックエンドでSSL処理をしなくて良いので、負荷軽減可能
2. ELBでSSL Terminationし、バックエンドとは別途SSL
3. SSLをバイパスしてバックエンドにTCPで送信
   * クライアント証明書認証などを利用するためにはTCPとして扱う

|      | ELB       | バックエンド(EC2など) |
| :--- | :-------- | :-------------------- |
| 1    | HTTPS     | HTTP                  |
| 2    | HTTPS/SSL | HTTPS/SSL             |
| 3    | TCP       | TCP                   |

#### TLSサーバー証明書

* AWS Certificate Manager(ACM)を使用して証明書管理が可能



### AWSサービスとの連携

* AutoScaling:インスタンス増減時にELBへの追加・削除が可能
* ECS:ECSタスク(サービス)をターゲットグループに登録することで、ECSの各タスクに対して負荷分散を実施(動的ポートマッピング)
* AWS WAF:IPアドレス制限やリクエスト内容のマッチングなどの条件でALBを保護可能

...



## 参考情報

* [Elastic Load Balancing](https://aws.amazon.com/jp/elasticloadbalancing/)
* [[AWS Black Belt Online Seminar] Elastic Load Balancing(ELB)](https://d1.awsstatic.com/webinars/jp/pdf/services/20191029_AWS-Blackbelt_ELB.pdf)
Chrome OS(Chromiumではない)をsurface GOに入れた話

#目次
1.始めに
2.Chrome OSを実際に入れてみた。
3.ネットワークファームウェアとの格闘（問題編）
4.ネットワークファームウェアとの格闘（解決編）
5.Chrome OSの使用感
6.最後に
#始めに
これは投稿日時点の情報です。
前の記事（[色々なandroidx86派生OSの紹介](https://qiita.com/pinnsann/items/defd6532fa59a2422c21)）でandroidx86の派生OSについて紹介しました。
プロキシサーバー下でYoutubeを見たいという強い気持ちでいろいろ試したのでしたが、結局アンドロイドをPCに入れると熱暴走する（たぶんPCを正しく制御できない）ので諦めたのですが、
Chrome OSという救世主の存在を確認したので、記事を書きました。
※純正のChrome OSをChrome book以外でインストールをするのはあまりやってはいけないらしい
#Chrome OSを実際に入れてみた。
一応やってはならないことなので、やり方が複雑になっている。
まずlinux Mintのisoをダウンロードし、USBにrufus等で焼付て、
Chrome OSのイメージファイルとBrunchというのをインストールしたものをinstall.shを
先程焼き付けたusbに突っ込んでbootする。
詳細やリンク等は（[https://beebom.com/how-install-chrome-os-on-pc/](https://beebom.com/how-install-chrome-os-on-pc/)）に書いてあります。
そうしてMintをインストールせず /cdromかどこかにあるinstall.shをスーパーユーザーで起動すればOK（インターネット接続が必要）
このインターネット接続が曲者でlinux mintではsurface goのwifi接続にデフォルトで対応していない。
#ネットワークファームウェアとの格闘（問題編）
wifi接続が無理というのはどういうことかというとファームウェアが入っておらずwifiのデバイスが対応できてないっぽい（詳しくは知らん）。
前の記事（[LinuxでWiFiが使えない時の対処法](https://qiita.com/pinnsann/items/beb03a25b7e1bed86e38)）で紹介したとおり、ネットワークファームウェアを入れること自体は解決済みだ。しかしここでだめだったのはusbで起動しなきゃいけなくて、ファームウェアを入れたとしても再起動時にすべてのデータが消えてしまう点だ。
どうやって解決したかというと無理やりファームウェアを入れたisoファイルを作ってしまったのだ。
#ネットワークファームウェアとの格闘（解決編）
isoファイルにどうやってファームウェアを打ち込んだかというとcubic(Custom Ubuntu ISO Creator)
を使った。どういうものかというと、linuxのisoファイルにいろいろファームウェアなりソフトなりを追加したり削除したりすることができるソフトだ。それを使いファームウェアを入れ、無事にChrome OSを入れることに成功した。
#Chrome OSの使用感
Chrome OSの一番の魅力は数年前に対応したandroidアプリに対応していることだろう。
念願のYoutubeを入れることにも成功した。
もう一つの利点はGoogleの後ろ盾があるのがものすごい安心感があること。
~~linuxにも対応しているらしいがなにしろgentoo OS対応しているソフトが少なすぎたので、開発用かなといった感じ。~~
linuxもdebファイルに対応しており、ほとんのアプリケーションに対応可能。しかしIMEなどを最初から設定しなければならないのと、動作が変に感じたので、どちらにせよ微妙かなといった感じ。
#最後に
かなり黒に近いグレーだがものすごく便利なので皆さんも試してみては？
VR おすすめのゲーム

今回はおすすめのVRゲーム紹介します。

# 「Beat Saber」
[Beat Saber Release Trailer](https://www.youtube.com/watch?v=vL39Sg2AqWg#action=share)

これは、VRゲームの中で、一番知られたゲームかもしれません。
両手のコントローラーは光る剣になり、音楽に合わせてブロックを斬る音ゲーです。
2018年5月で発売されたゲームなんですが、未だに結構な人気を持っています。
シンプルにVRの魅力を発揮出来るゲームだと思います。
なお、キャラクターは固定の為、VR酔いは一定程度で防ぐと思います。
# 「Moss」
[Moss Launch Trailer](https://www.youtube.com/watch?v=vL39Sg2AqWg#action=share)

絵本のような世界で旅するゲームです。
プレイヤーは俯瞰視点で主役のネズミ「Quill」を導き、謎をといたり、戦ったりするADVゲームです。
2018年2月で発売された、ゲームなんですが、
私は2019年の5月ではじめて知りました。

個人的に結構おすすめのゲームです。
今までよくあるゲームの形式は、プレイヤーが操作するキャラクターは主役になり、
プレイヤー　＝　キャラクター（主役）なっています。
視点も無論キャラクターの視点になっています。

が、VRの場合は、キャラクター視点だと、距離感がコントロールしずらい上で、酔いやすい、
戦う場合は、敵キャラが近すぎで、画面が混雑し、何も見えない、状況は全然わからなくなる問題が存在します。

「Moss」は、プレイヤーは「神視点」でQuillを導くことになっている同時に、
ゲームの世界を溶け込みような、連携プレイも必要となっていって、
視点の問題を解決した同時にゲーム体験も更にアップした感じです。

操作は難しくないので、プレイしやすいゲームだと思います。
# 「SUPER HOT」
[SUPERHOT: MIND CONTROL DELETE | Launch Trailer | Out Now](https://www.youtube.com/watch?time_continue=12&v=rFAqvOASQrs)

先ず、「SUPER HOT」は色んなバージョンがあります。VRだけではなく、PCやPS4もプレイ可能となります。
正確かどうかはわかりませんが、何年か前の「Ludum Dare」で、このゲームを見た事があるような気がします。
今はもはや確認できなかったので、感想まとめていいます。

一番の特徴は「自分が動いた時だけ時間が進む」です。
パット見ると、シューティングゲームだと思いますが、違いました。
ジャンルはアクションでした。

 ~~Ludum Dare時期の発言は完全に記憶頼りです、間違い可能性が充分にあります。
参考まででお願いします。~~
最初に見た時（Ludum Dare時期）画質と音声は普通より下だと思いますが、ゲームの遊び方とデザインは凄かった、
ゆっくり考えながら遊んでもいいし、はい速度で移動しながら遊んでもよい。
自分のスタイル合わせて遊べるゲームの感じです。

現在は画質、音質、アップし、デザインも強化しました、武器なのも豊富になっています。
元々は第一人者視点なので、VRとの相性は抜群です。
遊ぶ程、面白さが分かるゲームだと思います。
# 「The Climb」
[The Climb | Oculus Quest Trailer](https://www.youtube.com/watch?v=CEWJJzH229k&feature=emb_title)

「The Climb」最大な特徴を一言表すと、「壮大な大自然が美しい」です。
これは、絶壁を登るゲームです。
すごっくシンプルですが、素敵な光景とリアルの音声体験は没入感抜群。
ゲーム性が想像以上があります。
# その他
勿論、他に優秀なゲーム沢山ありますが、私はプレイした事ないので、詳しく紹介出来ません。
軽く書きます、興味ある人はご自由に。
「東京クロノス」
長編VRミステリーアドベンチャーゲームです。ゲーム性と物語の構成は抜群という評価が多いらしいです。

「ASTRO BOT」
2018年「The Game Awards 2018」に、Best VR/AR Gameを受賞したゲームです。
画面が安定し、初心者にも優しいです。
多分、一番知られているVRゲームかもしれません。

以上となります。
【Nuxt】エラーページ作成

# はじめに
layoutsディレクトリの配下に```error.vue```を作成することでエラーページが作れる。
エラーページはページコンポーネントにエラーが発生した時に表示される（サーバーサイドレンダリング中には発生しない）
※エラーページはlayoutsディレクトリに配置されているが、レイアウトではなくページとして扱う。


[layoutsディレクトリについてはこちら](http://...)

今回は存在しないURLにアクセスがあった場合に表示するエラーページを作成していく。

```layouts/error.vue
<template>
  <div class="ErrorPage">
    <div class="ErrorPage__content">
      <div class="ErrorPage__inner">
        // error.statusCodeでエラーコードを取得
        // エラーコードが404（アドレスのページが見つからない）だったら表示
        <template v-if="error.statusCode === 404">
          <span>ERROR</span>
          <h2>ページが見つかりません。</h2>
          <p>URLに間違いがないかご確認ください。</p>
          <nuxt-link to="/"> TOP</nuxt-link>
        </template>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ['error']
}
</script>
```

## props
error.vueはpropsとして```error```を受け取る。errorオブジェクトは下記の値を持つ。

**message**
型：String
エラーのメッセージが入る

**path**
型：String
エラーが発生したページのパスが入る

**statusCode**
型：Number
エラーコードが入る
statusCodeの状態によって表示するメッセージを切り替えることが可能。

## エラーコード(HTTPステータスコード)
HTTPステータスコードとはWebサーバーからのレスポンスの結果を表す3桁の数字コードのこと。

### ステータスコードの主なカテゴリと意味
#### 100番台：情報
102　処理を継続中

#### 200番台：成功
200　正しく表示されている

#### 300番台：リダイレクション
302　一時的にページを転送
304　リソースが未更新

#### 400番台：クライアントエラー
400　リクエストが不正
401　認証が必要
403　アクセス禁止
404　ページが見つからない
410　リクエストが消滅

#### 500番台：サーバーエラー
500　サーバー内のエラー
503　サーバーが一時的に使用不可

## 動的ルーティングでのエラーページ（API通信なし）
`pages/users/_id.vue`のような動的なページにアクセスした際、idが`undefind`で500エラーが返ってきてしまった場合
500エラーを404エラーとしてエラーページに飛ばす。

```UsersDetailPage.vue
<template>
  <!--  detailがあるか判別  -->
  <div v-if="detail">
    <h3>{{ detail.name }}</h3>
  </div>
</template>
<script lang="ts">
import Vue from 'vue';
import { Users } from '@/types/interface.d';
import { users } from '@/data/users';

interface Data {
  detail: Users | undefined;
}

export default Vue.extend({
  name: 'UsersDetailPage',
  data(): Data {
    // id にルートのパラメータを代入
    const { id } = this.$route.params;
    // データ users の中から先ほど定義したidとusersのidが一致したオブジェクトをdetailに代入
    const detail: Users | undefined = users.find((_) => _.id === id);
    // 値がない場合、statusCode 404 としてエラーページに飛ばす
    if (!detail) {
      // errorメソッドでstatusCodeを指定してエラーページへ飛ばす
      this.$nuxt.error({
        statusCode: 404
      });
    }
    // 値があればdetailを返す
    return {
      detail
    };
  }
});
</script>
```

↑ data（）内でerrorメソッドを実行してエラーページに飛ばしているが、それと同時にtemplate内のレンダリングも始まっており、レンダリングの途中でdetailオブジェクトのキーがないとエラーが出て処理が止まってしまうので、最初にdetailがあるかないか判別（`v-if="detail"`）してあげる。

### errorメソッド
errorメソッドを実行するとエラーレイアウトにリダイレクトされる。
引数として、statusCodeとmessageを渡すことができる。

```sample.js
error({
  statusCode: 404,
  message: 'エラー 404'
})
```
バグを事前に防ぐテスト設計

#**テスト設計について学んだこと**

今回テスト設計の案件にアサインしてみて学んだことや疑問点やプログラムを見る視点が変わりました。
ソフトウエアを作るにあったてどうしても付きまとうのが**バグ**だと思います。
このバグの原因関しては設計書が間違っていたり様々な要因でバグが発生すると思います。
その多く8割はヒューマンエラーだと考えます。
今回のテスト設計は、テスト項目書の作り方でバグを生み出さないように誘導することを第一に考えて作成してます。このことについてまとめます。

#**試験方針と重要ポイント**
**試験の方針として重要なポイントが３つあります。**
##**範囲**
テスト計画で大まかなテスト範囲を定め、具体的にどのシステム内のどの機能をテストするのかを決めます。
すべての機能をテストすることが理想ではありますが時間や工数の問題的に現実的ではないので重要度の高いものや新しく追加されたものなどを中心に範囲を設定することが重要です。
##**観点**
各テストの範囲と目的を鑑みて、テストで確認すべきことを定めます。
例えば、仕様書通りに動作するか、類似システムや機能と比較したときに一般化されている動作をするかなどを確認します。観点が定まらなけれ統一性のないバラバラなテスト項目書ができてしまうので作成者全員が共通の観点で作成する必要があります。
##**条件**
テスト観点を確認するために必要な入力データや操作などのバリエーションを決めます。バリエーションは範囲と同じで多いほうがバグは検出しやすくなりますが、多すぎると工数やスケジュール、予算を圧迫することになるのでバランスが必要です。
例えば検索の抽出条件が10個あるとします。ここで10個抽出条件を1つ1つ確認してしまうと工数も手間も多くなってしまいます。このような場合は下記のようにすると網羅的にかつ工数も少なくできます。
**例**
**試験１**　すべて条件が抽出できる場合データ
**試験２**　すべての条件が抽出できない場合のデータ
**試験３**　抽出条件のうち1つだけ抽出できない場合のデータ（抽出できない項目は任意で選択）
**試験４**　複数の抽出条件が抽出できない場合のデータ

**データシート**
データシート作成するとより見やすくわかりやすいと思います。
データシート作成関しては今後また別でまとめます。

##**試験方針に関してまとめ**
上記の3つのポイント抑えることがとても重要だと思いました。
よくある課題としては、属人的になりやすいことが挙げられます、作成者の知識や経験の差によりテストとしての妥当性に疑いが出てしまう場合やテストケースに漏れがでたり、反対に無駄なテストケースが増えてしまう場合などテスト品質に大きな影響を及ぼします。この３つ重要ポイントをしっかり定めテストの定型化をすることで属人的にならず作成者ごとに差が出ることが少なくなると思います。

#**テストケースの作成**
テスト方針を定めた後、テストケースの作成に入ります。
確認すべき項目の欠如やテスト結果の基準の正誤が発生してしまうとバグの原因になると思います。
そのためテストケースには、下記の４つを記載し漏れや重複などが発生しにくい状況を作ります。
##**テスト観点（確認内容）**
これは当たり前ですが、確認内容の記載をします。テスト実行者がシステムの動き方の理解の有無に関わらずどうゆう意図で観点をつくり、どこを確認したいかを具体的に明確に記載します。
例えば、コンボボックスとそれに連動するテキストボックスのテスト観点だと、選択したコンボボックスの項目に該当する内容がテキストボックスに表示されること。このように具体的に記載することが需要です
##**テスト条件**
テストの条件としてはテスト観点どおりの動作をするデータを事前に指定しておいたり、テスト事項者に用意してもらうデータの条件を記載しておきます。ダイアログが出るようなシステムなどではダイアログ内の動きの記載してあげるとよりわかりやすいと思います。
##**テストの手順**
テストを実行するための手順を記載しておくことも重要です。
これを記載しておかないと類似したテストなどで見たい観点は共有できているのに手順が違うせいで違う結果が出てしまいテストの妥当性を保てなくなるからです。
実行者にも記載してあげることで有識者でなくてもスムーズにテスト実行できることにもつながると思います。
##**期待値**
これは簡単に言ううとテストの結果です。
しかしこの書き方によってはテスト結果としてほしいエビデンスを間違ってしまう可能性も出てくるので注意が必要です。この期待値の書き方でバグを減らすことも誘導できると思います。例えば、「この正しい値がでること」とだけ記載してしまうとその数字が出ることしか確認させることができません。しかし書き方を工夫して、「〇〇テーブルの××項目の値が出ること」記載すれば、テーブルの動きや該当の項目まで確認させることができるので書き方でバグを事前に防ぐことができます。

#**まとめ**
今回はテスト構築に関して重要な方針とテストケースについてまとめました。
テスト方針はバグを事前に防ぐためには重要なことでテストケースでそれを具体的に示すことができます。
テストの定型化を進めることでだれでも網羅的にテストをできるようになると思います。
期待値の書き方やデータシートやテストパターン表について理解が深まりしだいまとめたいと思います。
[Flutter] Navigatorを利用した画面遷移時の標準トランジション (エフェクト) を変更する方法

# 1. はじめに

`Navigator`を利用した画面遷移時の標準エフェクト (トランジション) の使い方とその種類についてまとめています。

なお、AndroidやiOSアプリの標準の画面遷移時のエフェクトを指定して簡単に利用できますが、`Hero`ウィジェットを利用した時のようなカッコいいアニメーションではないので、本記事で説明する標準の選択肢で満足できない場合は自前のトランジションを作成する必要があります。これについては別途記事を書きたいと思います。

# 2. 使い方

`MaterialApp`に`pageTransitionsTheme`というプロパティが用意されていますので、これを利用します。

引数のbuildersプロパティにはターゲットプラットフォーム毎のテーマを指定する感じになります。なので、ターゲットのプラットフォームの値を目的のトランジションに上書きする感じです。

## サンプルコード

```Dart:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Navigator Transitions Themes',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
          // ↓ これ！ デフォルト値は以下です。
          pageTransitionsTheme: const PageTransitionsTheme(
              builders: <TargetPlatform, PageTransitionsBuilder>{
                TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(),
                TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
                TargetPlatform.linux: FadeUpwardsPageTransitionsBuilder(),
                TargetPlatform.macOS: CupertinoPageTransitionsBuilder(),
                TargetPlatform.windows: FadeUpwardsPageTransitionsBuilder(),
              }),
        ),
        initialRoute: '/page0',
        routes: <String, WidgetBuilder>{
          '/page0': (_) => MyHomePage(num: 0),
          '/page1': (_) => MyHomePage(num: 1),
        });
  }
}
```

# PageTransitionsBuilder

ソースコードはここにあります。これを参考にすればカスタムなテーマが作れそうです。
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/page_transitions_theme.dart

# 3. 標準トランジション

数は多くありませんが、それぞれを紹介しておきます。

### CupertinoPageTransitionsBuilder

iOS向けトランジションです。
![CupertinoPageTransitionsBuilder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/9afa7c9b-72a2-e42c-c0d4-565da23e2239.gif)

### FadeUpwardsPageTransitionsBuilder!

Android向け標準トランジションです。
![FadeUpwardsPageTransitionsBuilder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/1ce080e4-053e-ea5a-66b6-49a7aeca2ddc.gif)

### OpenUpwardsPageTransitionsBuilder

Android 9ライクなトランジションです。
![OpenUpwardsPageTransitionsBuilder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/b538209c-e9c2-3f3e-0a22-868ffeecb1df.gif)

### ZoomPageTransitionsBuilder

Android 10ライクなトランジションです。
![ZoomPageTransitionsBuilder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259963/3ee58b41-83a1-4b4c-5d41-f07f2d73276d.gif)
マッチポンプデバッグ

上司「この機能の単体テストのバグ報告少なすぎない？」

わい「ああ、それ別の似たような既存機能をコピーして少し変えただけだから、バグ出ないですよ」

上司「あー、それじゃあ困るんだよねえ。監査上、バグが出てない場合、無いんじゃなくて見つけられてないってことになっちゃうから。単体テストでバグが一番出て、結合テスト、完全テストとどんどんバグが少なくなっていくってシナリオにしないと。」

わい「そうはいっても無いものは無いですよ」

上司「・・・・・・作ろうか」

わい「・・・・・・え？」

上司「無いなら作ろう」

わい「・・・・・・」

上司「バグ票だけあげられると虚偽だとバレるから、ちゃっとバグったコードコミットしてログ残してね」

----

監査とか厳しいとこういう不条理が行われたりするので、監査を厳しくすれば品質が保たれるというのは幻想です。

ちなみにこの大規模プロジェクトでは各チームでこんなことが行われていたのですが、後にバレて大問題になりました。
VSCodeで "ctrl+s" を押してしまいターミナルが反応しなくなったが、"ctrl+q" のシグナルが送信できず解除できない

# 経緯

VSCodeのターミナルからLinuxマシンにSSHしている場合において、ターミナルにフォーカスしたまま `ctrl+s`を押すと、ターミナルの出力がロックされる（[詳細](https://www.itmedia.co.jp/help/tips/linux/l0612.html#:~:text=%E3%81%A4%E3%81%84%E3%81%A4%E3%81%84Windows%E4%B8%8A%E3%81%A7%E4%B8%80%E8%88%AC,%E3%83%AD%E3%83%83%E3%82%AF%E3%81%95%E3%82%8C%E3%82%8B%E3%81%9F%E3%82%81%E3%81%A0%E3%80%82)）。

通常 `ctrl+q` を入力することで この出力ロックの状態を解除することができるが、`ctrl+q` はVSCodeのデフォルトショートカットとして割り当てられているため、解除ができない。

# 解決方法

`keybindings.json` に以下のように追記することで、`ctrl+q` のデフォルトショートカットを無効化することができる。

```diff
 // Place your key bindings in this file to override the defaults
 [
+    { "key": "ctrl+q", "command": "-workbench.action.quickOpenView" }
 ]
```

Command Paletteに以下のように打ち込んで、JSONを開き、上記を追記する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124948/e6a3eac2-eae2-0c02-c090-3f9b86e9663c.png)

ショートカットを無効化した状態で `ctrl+q` を押すと、ターミナル出力のロックを解除することができる。

# 詳細

デフォルトで割り当てられているキーボードショットカットは、同様にJSONファイルを開いて確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124948/0d990eb4-d781-7289-f778-ecc4bb42a955.png)


今回の設定であれば、以下のように記載されていることを確認できる（一部略）

```json
{
  { "key": "ctrl+q", "command": "workbench.action.quickOpenView" },
}
```

デフォルト設定は書き換えられない。
そのため、ショートカットキー設定において頭に `-` をつけ、今回はこのショートカットを無効化している。

```diff
 // Place your key bindings in this file to override the defaults
 [
+    { "key": "ctrl+q", "command": "-workbench.action.quickOpenView" }
 ]
```

# 余談
この `ctrl+s`ですが、以下のような経緯で実装されているようです。

<blockquote>
<blockquote>この「Ctrl+S」による画面出力の停止ですが、起源は「テレプリンター」にあります。かつて、コンピューターからの文字出力は「ディスプレイへ表示」ではなく「プリンターへ印字」されていました。プリントを一時的にストップしたい場合に「Ctrl+S」で停止し、「Ctrl+Q」で再開していたわけです。その後、ディスプレイへと置き換わった後も、今の端末ほどスクロール機能は充実していなかったことから、「Ctrl+S」で出力を止めて内容を確認し、「Ctrl+Q」を押して出力を再開するという形で使われました。
</blockquote>
https://linuxfan.info/disable-ctrl-s
</blockquote>

引用元の記事ではこれを停止する方法について解説されているので、そもそも `ctrl+s`を押しても出力が停止しないよう、設定を変更するという解決方法のほうが望ましいかもしれません。

# 参考
- [Remove a keyboard shortcut from VS Code
](https://stackoverflow.com/questions/43184034/remove-a-keyboard-shortcut-from-vs-code/43192261)
FlutterでFirebaseエミュレーターへの接続調査、バージョン問題が解決できないよ


最初の記事、メモ書きです。 あまりキレイに書くつもりが無いので、あしからず
できねーよっていう記録なので読まないほうがいいかもです。（じゃー書くな、は無しで）

## 何を開発してるか （読み飛ばし推奨）

## 楽器練習アプリ
何気なく、楽器練習アプリを開発したいとツイートしたら欲しいという要望がたくさんたくさん（4件）寄せられたので、Flutterを調べつつ開発に挑戦中です。
楽だけど覚えることも多いですね。 言わなきゃよかったｗ
なので、仕事じゃなくて趣味開発です。

エンジニアって、大体こんなの欲しいと思って着手しても挫折するよね （あるあるー）
でも応援してくれる人がいるので頑張ってます。
というか、それが分かってたのでいろんな人を巻き込んで、やらざるを得ないに追い込んでます。
これに関しては、気が向いたら記事を別に書くかも、書かないかも 

### 現状の学習ステータス
Flutterのレイアウトはなんとなく作れるようになったので、実装やデータ保存周りを調べてます。
学習の手順は、人それぞれだと思いますが、私の場合は、Android Projectを作りまくります。
壊れてもいいように練習プロジェクトを10個ほど作ったあと、プロトタイプを作りはじめました。

### データどこに保存する問題
楽器の練習結果は録音するのですが、端末内に保存しとけばいいかと思ってました。
しかし、壊れたり、端末変更したら消える問題を解決するためにはやっぱりFirebaseが必要なのかなと
録音データは、まぁ、iCloudとか、Googleドライブでいいにしても、設定とかがね結局、mBaaS が必要だねと。
サーバ周りまで開発してたらモチベーション続かないので


## ここから本題 ー やっぱFirebaseが必要そうだね、はぁ、やりたくないｗ

NEC Mobile Backendとか、AWS Amplify Flutter とかありますけど、仕事じゃないので技術選定は、まぁ、これでいいんじゃない程度で選択
サーバレスとかいいつつも考えないといけないこと増えるの分かってし、やってるうちにやりたいことが増えて結局できない沼に入りそうですが、やっぱりいるよね、しょうがないやるか、、、みたいな。

### まずは写経

Qiitaの以下の記事を参考にしつつ、現状と合わないところは、調整して、AndroidでもiPhoneでもなんとか動くようにしました。

[FlutterでFirebaseを使ってみる〜投票アプリ〜](https://qiita.com/121a/items/ee488298a5b9468c3b57)

どこを直したのかは気が向いたら追記します。
多分、エンジニアならそんなに難しくない、IDEのヒントに従えばいいし

### Firebaseは、ローカルエミュレータがあるらしい。

[Firebase Local Emulator Suite の概要](https://firebase.google.com/docs/emulator-suite/)

ここからいろいろ変更して、覚えていこうと思ったら、Firebaseには、エミュレータがあるらしいと
この方が楽そう。

しかし！ ここからがハマりポイント
(※ エミュレータのインストールと起動はすんなりいけました。)


検索してると既に記事を書いている方が、monoさん。

[FlutterアプリからFirebaseエミュレーターに接続](https://medium.com/flutter-jp/firebase-emulator-938e9a0cdfad)
記事検索すると、だいたいこの方の記事に大体あたりますね。日本では一番くわしいのでは？

うん、動かない、run.dart のサンプルになってる以下の部分、Firestore がバージョン上がって、FirebaseFirestone になったタイミングで、
.instance.settings が無くなってる？

```
  if (isEmulator) {
    final domain = (!kIsWeb && Platform.isAndroid) ? '10.0.2.2' : 'localhost';
    CloudFunctions.instance.useFunctionsEmulator(origin: 'http://$domain:5001');
    await Firestore.instance.settings(
      persistenceEnabled: false,
      host: '$domain:8080',
      sslEnabled: false,
    );
  }

```

で、この問題を検索したら、

[FlutterでFirebase Firestore設定を構成する方法](https://www.it-swarm.dev/ja/google-cloud-firestore/flutter%E3%81%A7firebase-firestore%E8%A8%AD%E5%AE%9A%E3%82%92%E6%A7%8B%E6%88%90%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/806329899/
)

という記事が、あり

```
cloud_firestore: ^0.8.2+1
```

にすると良い、、、、としたら、別のエラーが、最初の写経で作った main.dart がエラーです。


コメントは、自分で追記した部分


```
          // サンプルから修正 .updateData → .update
          onTap: () => record.reference.updateData({'votes': FieldValue.increment(1)}),
```


.incrementなんてねーよ！と言われます。どうもこのメソッド日本人の方の提案らしいのですが、なぜバージョンが新しくなって無くなるのか不明

[Cloud Firestoreに追加されたFieldValue.increment()は期待以上！！](https://qiita.com/1amageek/items/665df5a6d9921319e300)



さっきは、これで動いてたのにということで、pubspec.yaml のバージョンをゴニョゴニョしてみましたが、まだ解決出来ず。


```
dependencies:
  flutter:
    sdk: flutter
  firebase_core: "^0.2.5+1"
  cloud_functions: ^0.6.0
  firestore_ref: ^0.9.0-dev
  cloud_firestore: ^0.8.2+1

```

この依存関係の解決方法が、分からない。

今日（2020/08/28）時点で同じことやろうとしたら同じ道をたどると思うので残しておきます。解決できたら追記予定

というか、解決した人がいたらコメントで教えていただけると嬉しいです。
生き物であるサービスをJIT（Just in Time)で提供する。

**サービスとは生き物である。**と考える方はどれだけいるのであろうか？
ソフトウェア開発ではサービスの定義を仕様として表現している。
そのソフトウェア品質を高めるには、正しく仕様を捉えなければ駄目だ、正しい仕様を定義すれば良い品質が保たれると、いう輩がまだまだ多数派である。
我々を取り巻く世界は刻々と変化しています。それは、ビジネスもサービスも同じです。
昨日まで上手く言った方法だからと言っても、今日上手くいくとは限りません。
昨日、ユーザーが必要とすると言っていても、今日も同じように実用だとは断言できません。
また、サービスを手にしたとたんに、新しい要求が生まれてきます。
それは生き物の様に動いていて、固まって動かないものではありません。
もはや、**正しく仕様を捉えられるという事は不可能**なのです。
確りと要求を確定しても、時間の経過とともに陳腐化していきます。一年も経てば、
良くて25％程度、悪くみると50％まで、元の要求から変わってきます。
**目指す姿は、今必要であるといった時に、サービスを提供することです。**
この理想を目指して、様々なテクノロジーや仕事・作業のやり方を変え続けて行く（不断の改善）ことになります。
xibファイルを読み込んでNSWindowContrllerを表示する

# 概要

- xibファイルを読み込んで別ウィンドウを表示したい。

![-w809](https://i.imgur.com/PVMXFgL.jpg)

- `Storyboard`から、`NSWindowController`（with xibファイル）を表示する

![-w1156](https://i.imgur.com/CilaurD.jpg)

# 参考
- [Xcode で最低限の\(何もしない\)ウィンドウを表示するまでの手順 \- メモ書き](https://nsaito-nmiri.hateblo.jp/entry/2015/07/13/164802)
- [Swift4でのクラス名取得方法まとめ \- Qiita](https://qiita.com/yosshi4486/items/f7916352d22d0e4d03ee)

# 実装

- `NSWindowController`のクラスを定義する。（このときxibファイルも一緒に作成する）

```swift:SampleWindowController.swift
import Cocoa


class SampleWindowController: NSWindowController {

    // MARK: - Properties
    
    let windowTitle: String
    let message: String
    
    @IBOutlet weak var messageLabel: NSTextField!
    
    // MARK: - Lifecycle
    
    init(withTitle title: String, message: String, window: NSWindow?) {
        self.windowTitle = title
        self.message = message
        super.init(window: window)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func windowDidLoad() {
        super.windowDidLoad()
        configureUI()
    }
    
    override var windowNibName: NSNib.Name? {
        return String(describing: type(of: self))
    }
    
    // MARK: - Helpers
    
    private func configureUI() {
        window?.title = windowTitle
        messageLabel.stringValue = message
    }
}
```

- クラスと`xib`の結びつけは下記のコード。これが今回のポイント。

```swift:SampleWindowController.swift
override var windowNibName: NSNib.Name? {
        return String(describing: type(of: self))
}
```



- `ViewController`からの呼び出し方は以下の通り。

```swift:ViewController.swift
var sampleWindowController: SampleWindowController?

// （中略）

@IBAction func openingWindowButtonClicked(_ sender: Any) {
    let sampleWindowController = SampleWindowController(withTitle: "Title of SampleWindowController",
                                                        message: "passed message for SampleWindowController..",
                                                        window: nil)
    sampleWindowController.showWindow(self)
    self.sampleWindowController = sampleWindowController
}
```
IoTがもたらす効果を"監視"，"制御"，"最適化"，"自律化"の4段階に分類

応用情報技術者平成30年秋期 午前問71

IoTがもたらす効果を"監視"，"制御"，"最適化"，"自律化"の4段階に分類すると，IoTによって工場の機械の監視や制御などを行っているシステムにおいて，"自律化"の段階に達している例はどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/8f249d27-1d15-2870-7bdc-81a9a82b61a4.png)

アメリカの経営学者であるマイケル・E・ポーター氏らは、IoTがもたらす効果が4段階に進化すると述べています。

・監視
　　離れた場所にあるモノの状態を遠隔からモニタリングできる状態
・制御
　　通信を介した外部からの指示でモノを操作できる、または、一定の状態を観測したときに決められた動作を自動で行うようになっている状態
・最適化
　　蓄積されたデータと観測したデータをもとに、人間が与えた基準に基づく望ましい状態を自ら見つけ、モノの様態を最適に保つことのできる状態
・自律化
　　目標値などの最低限の指示のみ与えれば、人間による細かな条件や基準がなくても、自律的に（あたかも人間のように）最適な状態を判断し、モノ同士が協調して動作できる状態


参照：
https://www.nw-siken.com/kakomon/30_aki/am1_27.html
FuelPHPでAjax使ったときの値の見方

Ajax使って非同期でデータのやり取りを実装するとき、
「403エラー出てるけど具体的にどういうエラーなん？」
ってなったときとかに見る方法です。

```example.php
$value;//おそらく原因であろう変数
var_dump($value);
exit();
```

`var_dump()`は引数の情報（値、型など）を表示する関数です。`exit()`は現在のスクリプトを終了する`言語構造`というらしいです。関数とは違うんだとか。
参考→https://www.php.net/manual/ja/function.exit.php

非同期かどうかにかかわらずデバッグするときに使えそうですね。
新人研修でチームビルディングを頑張る

# ご挨拶
どうもお久しぶりです。初めまして。えすです。
この度、新人研修をさせてもらえることになりまして、その時の話を書き留めておこうかと思いました。

# 対象
研修ネタに困っている方。チームビルディングのトライネタに困っている方。
本記事から、現場でうまく使える案にしてもらえれば幸いです。

# 研修の目的
私自身は、ふりかえりの習慣を刷り込むことと、チームビルディングを目的に置いていました。
自分が持っているIT系の知識は大半別のところで手に入れられるため、わざわざ研修で行う必要もないだろう、と考えていました。

# で、実際に話したこと
システムアーキテクチャの話やら某ベストプラクティスやら、あとはプロジェクトの進め方やら、それと、本目的のふりかえりです。ぶっちゃけ、ふりかえりを通してメンバー間でのチームができるきっかけになればネタはなんでも良かったのですが、こちらのネタをいきなり相手やえらい人が認めてくれるかというと、それは難しそう、というのが印象だったので、他の喜びそうなネタを色々つけました。

私自身は、ふりかえりのきっかけ作りで「ふりかえりやろう」は難しいと感じていました。本当にプロジェクトに火がついてからでは価値のわからないことに手を出してはくれませんので。仮にふりかえりの場を持てたとしても、すでに前向きな気持ちでいられないことが多いです。それからでは、正直自分のファシリ性能では挽回できません。

そこで、新人研修でサブリミナルしよう、と思いついたわけです。

# ワークショップの準備と失敗しづらいプロダクト選び
ふりかえりをネタに入れるとなると、ワークショップ形式の準備をしたくなるわけですが、リモートでやる以上、よくやるスクラムワークショップのネタを成果物にはしづらいです。そもそも、時間が全然違いますしね。。。そこで、いっそのことアジャイルもどき体験と銘打って、チームビルディングを成果物にしよう、と決めました。そうすれば一石二鳥だっ。自分の目的は果たされる。

# チームビルディングとは言いつつも
まあまず自己開示がないとね。
とはいえ、それって普通なかなか難しいじゃん？実際「えすです。前職ではこれこれしてました。今はそれそれの勉強してます。血液型はマサカリ型です」とかそんな感じじゃないですか。というか、実際今の新人チームはそんな感じだったわけです。あ。自己開示。価値観の共有とかね。そういうのが・・・打ってつけのがありますね。便利なのが。[Moving Motivators](https://nuworks.jp/product-category/management-3-0/)。
なんとかパーソナルマップをプロダクトに設定できないかと思ったのですが、

# ワークショップの構成
他の講義の時間も含めると、せいぜい40分取れれば良い方かな、という見込みで構成を作りました。
1. 各参加者がMoving Motivators からカードを一つ選び、自己紹介文を考える（3分）
2. 発表（1分）
3. ふりかえり（+/Δ）
4. これを2回
これをする時に、気をつけていたのは「時間を意識させること」と「解釈は自由に」でした。そして、さりげに発表が終わったら拍手音をわざとマイク近くでやること。これで、達成感を多めに出せたら良いかな、と。

# 結果とか感想とか
1回目の時から時間意識をさせていたおかげか、1回目ふりかえりの時に「時間をもっとうまく使って発表する」ようなΔが出てきました。そのためか、2回目は全員他の参加者の発表のうまい仕方を取り入れつつ時間通りに終われる、良いアウトプットになっていたと思います。
2回目の発表の後のふりかえりは、1回目に比べてかなり品質（時間や内容そのもの）に触れた+/Δに目に見えて変わっていました。これが可視化できてメンバー間で共有できたので、プロダクト向上に繋がる手応えも感じてもらえたかと思います。

この後、講義全体の締めを「理由付き感謝」で駄目押ししたので、メンバー全員気分良く終われたようです。「どう言う理由で、何に『ありがとう』かを言って終わりにしましょう」と言うことで、何が良かったことだったか、何が学びになったか、を再認識もできました。しっかり理由が言えていたところからして、言いっ放しになっていないことが確認できたのは、私にとっても大変ありがたいことでした。

終わった今の私自身の感想ですが、ほぼほぼ失敗が無いプロダクトを設定できたので大変気が楽でした。ふりかえりを導入したいみなさま、お試しあれ。
【UnityEditor拡張】ドラッグ操作を反映されないようにする

# 概要

ドラッグ操作の値は取得するが、そのまま移動量を反映させたくなかったり、移動量に変更を加えたりする時に使う。

# やり方

```C#
public void HogeFunc()
{
    var ev = Event.current;
    if(ev.type == EventType.MouseDrag)
    {
        ev.delta = Vector3.zero;
    }
}
```

`event.delta`は`set`も可能なので、ここで設定すればドラッグ量が伝わります。
MPEG4などに存在するパテントプール


応用情報技術者平成30年秋期 午前問70

MPEG4などに存在するパテントプールの説明として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/395ea770-7e71-c62f-e1ec-98b84e5b4a73.png)


１、パテントプール(Patent Pool)とは、
標準規格等に関して、複数の特許権者が保有する特許を持ち寄り、一括で効率よくライセンスする仕組みです。

※Patent 特許

メリット：
①複数の特許についてまとめてライセンス交渉できる、
②パテントプールで一定の条件が定められるため市場価格の参考になり、パテントプールで定められた条件は市場価格に影響する、など

パテントプールの例としては、MPEG2、MPEG4、CODEX、WCDMAなどの規格があります。


２、デファクトスタンダードの説明　de facto standard　（ラテン語で「事実上、実際には」を意味する）
国際機関及び標準化団体による公的な標準ではなく，市場の実勢によって事実上の標準とみなされるようになった規格及び製品


３、オープンソースソフトウェアの説明
著作権表示を保持することによって，ソフトウェアの使用，複製，改変，及び再頒布が認められる仕組み


４、オープンライセンスの説明
特許料が無償でライセンスされている技術

参照：
https://www.ap-siken.com/kakomon/30_aki/q70.html
Tableau DesktopにてShift-jisのファイル（Excelからエクスポートしたファイル）の文字化け対策

## 概要
Tableau DesktopにてExcelからCSVとして出力したファイルを取り込んだ際に、文字化けしてしまうたため、文字コードを変更する手順を紹介します。

## 問題
Tableau Desktopにて、Shift-jisのファイルを取り込んだ際に、デフォルトの文字コードがUTF-8となっていることから、文字化けしてしまいます。

**Excelでの表示**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/baf23c13-c338-9221-72e0-68dfacf8b2b3.png)


**Tableauでの表示**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/034bb917-0986-8e55-45d0-406140673448.png)


## 対策
### 1. 物理レイヤーにて、データソースの右に表示される”▼”を選択後、”テキストファイルプロパティ...”を選択します。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/71aa1cc3-881a-e58c-fed3-28b360fe79ef.png)

### 2. "文字セット"にて、”Japanese Shift JIS”を検索し選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/2001b81b-065e-87f2-ece6-6eaaeb3754cb.png)


### 3. 文字化けが解消されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/994bc4d4-ec4f-1d17-2632-a89b70660942.png)
jsで「今日は  2020年8月28日（金）です。祝日です。」とのMsg作成の簡易Methodをメモ

<script src="js/japanese-holidays.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        function sampleDate(date, format) {
            format = format.replace(/YYYY/, date.getFullYear());
            format = format.replace(/MM/, date.getMonth() + 1);
            format = format.replace(/DD/, date.getDate());
            return format;
        }
        function getNowYMDX(dt) {
            var result = sampleDate(dt, 'YYYY年MM月DD日');
            switch (dt.getDay()) {
                case 1:
                    result = result + "（月）";
                    break;
                case 2:
                    result = result + "（火）";
                    break;
                case 3:
                    result = result + "（水）";
                    break;
                case 4:
                    result = result + "（木）";
                    break;
                case 5:
                    result = result + "（金）";
                    break;
                case 6:
                    result = result + "（土）";
                    break;
                case 0:
                    result = result + "（日）";
                    break;
                default:
                    break;
            }
            return result;
        }
        function getHoliday(dt) {
            var holiday = JapaneseHolidays.isHoliday(dt);
            if (holiday) {
                return holiday;
            }
            return "";
        }
        function getToday() {
            var dt = new Date();
            //dt = dt.addDays(25);
            var ho = getHoliday(dt);
            return "<small>今日は</small><u>&nbsp;&nbsp;" + getNowYMDX(dt) + "</u><small>です。" + ((ho == "") ? "" : "" + ho + "です。</small>");
        }
        $(function () {
            $("#todayMsg").html(getToday());
        });
    </script>
Railsでlink_toを使ってボタン遷移を実装する

##概要
今回実装したいのは、以下の画像のようなボタンにlink_toメソッドでリンクを与える実装です。

![syuppinn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696517/82ac4946-1df3-e606-e9e0-22176c4bf6b1.png)

この'出品する'ボタンをクリックすると、与えた商品投稿ページのリンクへ遷移することができます。

##二通りのやり方がある
この機能の実装には二通りのやり方があります。
なぜlink_toの方が良いのかはわかりません...

・a href要素での記述

```ruby:xxx.html.erb
<a href="パス">
出品の画像やテキストの記述
</a>
```

・link_toでの記述

```ruby:xxx.html.erb
<%= link_to("URL") do %>
　ここにHTMLのコードを記述する
<% end %>
```

##例
今回の実装で記述したコードを参考例として貼っておきます。

```ruby:xxx.html.erb
<div class='purchase-btn'>
  <span class='purchase-btn-text'>出品する</span>
  <%= link_to ("/products/new") do %>
    <%= image_tag 'camera.png' , size: '185x50' ,class: "purchase-btn-icon" %>
  <% end %>

</div>
```
【Nuxt.js】Nuxt文法編：head

🎈 この記事はWP専用です
https://wp.me/pc9NHC-BC

# 前置き
metaタグを設定するhead属性について解説していきます🎀
SEOに直接的な影響はないと言われていますが、
検索結果のタイトル下に表示されるmeta descriptionは
クリック率に影響するため理解しておいた方がGood🌟

それではやっていきましょう〜！

# head
## head属性とは

前置きにも書きましたが、
metaタグを設定する場所です🎀🧸

公式：
https://ja.nuxtjs.org/guide/views/#%E3%83%9A%E3%83%BC%E3%82%B8

基本的にはnuxt.config.jsで
グローバルに設定しますが
pageごとのローカル設定を
優先させることもできます🌟

pageで個別の設定しなければ
nuxt.config.jsの設定が引き継がれます。

## headに使えるオプションと使い方

head で利用できるオプションは数種類あります。
メタ情報プロパティの認識

主に使うのがtitleやmeta descriptionですね。
descriptionは検索結果の下に出る文章のことです。
https://wacul-ai.com/blog/seo/internal-seo/meta-description-for-seo/

【コード（htmlの場合）】

```index.html
<head>
 <title>ここにタイトル</title>
 <meta name="description" content="Webサイトの概要">
</head>
```

【コード（Nuxtの場合）】

🎈 続きはWPでご覧ください👀
https://wp.me/pc9NHC-BC
ディープラーニングのモデルとパラメータの意味

# 概要
　本記事ではディープラーニングを初めて使う人向けモデルとパラメータについて説明します。

　モデルとは何なのか、パラメータとは何なのか、どうしてこの二つでAIが作れるのかを読者に理解してもらうことを目的としています。

# 前提知識
- 数学における関数の知識
    - $y = ax + b$ は直線を表す
    - $y = ax^2 + bx + c$ は放物線を表す

# どのようにAIはできるのか
　ディープラーニングなどのAI開発において、AIは必ず**入力と出力を必要とします**。例えば画像認識AIであれば、入力は認識する対象の画像、出力は認識した動物の名前となります。

　入力をx、出力をyとしたときyとxの関係式、つまり$y = f(x)$となるような$f(x)$を見つけることでAIを作成することができます。

# 実際の例
　実際にAIを作る手順を簡単なデータで見せていきます。表を見てください

| 握力[kg] | ボールの飛距離[m] |
|-----:|----:|
| 35   | 71  | 
| 45   | 92  | 
| 38   | 76  | 
| 15   | 31  | 
| 10   | 19  | 
| 20   | 39  | 

　この表は握力x[kg]の人が、ボールを投げた時にボールが飛ぶ飛距離y[m]を表した表です。これをx軸を握力、y軸をボールの飛距離としてグラフで表します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230673/a7622e4d-f93d-7e83-7813-ec5b7369c836.png)

　この点の並びを見ると「握力とボールの飛距離の関係は直線で表せるのではないか」と考えると思います。直線を数式で表すと$y = ax + b$です。

　今回x軸は握力[kg]、y軸はボールの飛距離[m]なので、xを握力[kg]、yをボールの飛距離[m]とすると$y = ax + b$という関係が成り立つことがこの図から予測できます。

　このあとaとbを求めます。本来、最小二乗法などの方法で求めますが難しいのでここでは話しません。

　今回はa = 2、b = 0とすると、下の図のようにすべての点とほとんど重なるような直線になります。（下図の点線が$y = 2x + 0$です。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230673/714f1876-30f5-fb52-df3d-c38aa1bbbfce.png)

　この直線**y = 2x + 0**を用いると様々な握力の人の、ボールを投げられる距離を予測できます。例えば握力が50[kg]の人であれば$y = 2 × 50 = 100$よりおよそ100[m]ほどボールを投げられるでしょう。

# モデルとパラメータとは
　上で示した例においてxとyの関係を$y = ax + b$と予想しました。このとき、この$y = ax + b$という形そのものをモデルといい、a、bのようなx、y以外の文字をパラメータといいます。

# モデルを決める重要性
　例えば上の例でモデルを$y = ax^5 + bx^4 + cx^3 + dx^2 + ex + f$とすると下の図のようになります。（パラメータa～fはエクセルで求めました。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230673/3db7acf0-143e-9e03-b0d4-2ddef9308d5c.png)


 すべての点の上をちゃんと通っていますが、このモデルでは握力とボールの飛距離の関係を適切に表しているように見えません。このように適切なモデルを設計できていない場合、AIの精度は大きく下がってしまいます。

# 結論
　実際のデータはグラフ化するのは難しくモデルも複雑で理解しがたいものばかりです。ただ、先駆者のコードを眺める中でも、実際にはこういう感じのことをやっていることを理解しながら読むと頭に入りやすいと思います。

# 補足
　実際には握力とボールの飛距離にはそれほど相関関係はないと思います。
進数

# 進数の表記

16進数の表記
16進数をリテラルで表記する場合、Python3では以下のような形式になります。
・先頭に「0」を付ける
・その後に「x」を記述する
・続けて0から9まで、及びaからfまでの英字を書く
「x」を含め、英字は大文字・小文字どちらでも構いません。

16進数の数値リテラルをキーボードから打ち込むと、10進数に変換した数値を表示します。
Pythonでは、16進数リテラルを数値型として扱います。
16進数のリテラルを10進数に自動的に変換します。
【16進数のリテラルを入力した例】　0x1ff　→　511

数値から16進数相当の文字列を得るには、hex()という組み込み関数を使います。
引数に数値を与えると、16進数相当の文字列を返します。
「hex」とは、英語で16新数表示を意味する「hexadecimal」を略したものです。
【10進数の数値を16進数相当の文字列に変換した例】　hex(1023)　→　’ox3ff’

16m進数の数値リテラルではなく、16進数相当の文字列を数値に変換するためには、組み込み関数のint()を使います。
ただし、第2引数に基数として「16」を渡します。
【16進数相当の文字列を数値に変換した例】int(“ox100”, 16)　→　256


2進数の表記
2進数をリテラルで表記する場合、Python3では以下の様な形式を使います。
・先頭に「0」を付ける
・その後に「b」を記述する
・0または1の数値を続ける
16進数のリテラル表記と同様に、2進数のリテラルも10進数に変換します。
【2進数のリテラルを入力した例】　0b1000　→　8

10進数の数値を2進数相当の文字列に変換するためには、組み込み関数のbin()を使います。
関数名の「bin」とは、英語で2進数表記を意味する「binary」を略したものです。
【10進数の数値を2進数相当の文字列に変換した例】　bin(1023)　→　‘0b1111111111’

2進数相当の文字列を整数に変換するためには、組み込み関数int()の第2引数に「2」という基数を渡して呼び出します。
※16進数の時と同じ
【2進数相当の文字列を数値に変換した例】　int(“0b1111111111”, 2)　→　1023


8進数の表記
8進数をリテラルで表記する場合、Python3では以下のような形式を使います。
・先頭に「0」を付ける
・その後に「o」を記述する
・0から7までの数値を続ける
Python2までは、「0123」のように0から始まる数値を使って8進数のリテラル表記としていました。
それだと「0123」は8進数、「123」は10進数となって紛らわしく、また、16進数や2進数と表記の仕方が異なっていたのですが
Python3になって、表記が統一されました。
【8進数のリテラルを入力した例】　0o1777　→　1023

数値を8進数相当の文字列に変換するためには、組み込み関数のoct()を使います。
関数名の「oct」とは、英語で8進数表記を意味する「octal」を略したものです。
【10進数の数値を8進数の文字列相当の文字列に変換した例】　oct(1023)　→　’0o1777’

8進数相当の文字列を整数に変換するためには、組み込み関数のint()の第2引数に「8」という基数を渡して呼び出します。
※16進数、2進数の時と同じ
【8進数相当の文字列を数値に変換した例】　int(“0o1777”, 8)　→　1023


ビット演算子
ビット演算子とは、2進数を個々の「ビット列」（1と0で構成された列）と見立てて実行する論理演算のことです。
演算というと、足し算や掛け算を思い浮かべまずが、ビット演算は、「+」や「*」といった算術演算よりも、論理演算に似た操作です。
論理演算とは、「==」などを使った比較演算を「and」や「or」で組み合わせる演算のことです。

ビット演算はGUIライブラリのようなものを使ってプログラミングを作るときなど、C言語で書かれたライブラリを利用するのに
用いることがあります。Pythonの標準ライブラリの中には、正規表現のモジュール（re）のように、引数として渡すフラグを
組む立てるときに、ビット演算子を利用するものがあります。
Pythonでは、特別な演算子を使って、整数を対象にビット演算を行うことができます。
0と1で構成される文字列を使ってビット演算をしたい場合は、組み込み関数のint()を使って文字列を整数に変換してから行えばいいでしょう。

【Pythonで利用できるビット演算子】

| ビット演算子 | 説明 |
|:-:|:-:|
|x ｌ y	|xとyの論理和（OR）をとる|
|x & y	|xとyの倫理積（AND）をとる|
|x ^ y	|xとyの排他的論理和（XOR）をとる|
|x << y , x >> y	|シフト演算子。「<<」はxをyビット左にシフト、「>>」はxをyビット右にシフト|
ファイルデータとは、ディレクトリとは、ファイルの場所を示す方法

#ファイルデータとは
　アプリケーションソフトで作った文書(データ)は、
　ファイルとして補助記憶装置に記憶される。

#データの種類と代表的なファイル形式
　**テキスト形式**
　文字コードと、改行やタブなど一部の制御文字のみで作られるファイル形式
　文字を扱うアプリケーションソフトであれば、読み書きすることができる

　**CSV形式**
　基本的にはテキスト形式だが、個々のデータである文字や数字をカンマ(,)で区切り
　行と行を改行で区切ることど、表形式のデータを保存することに特化したファイル形式
　
　**PDF**
　画像が埋め込まれた書類をコンピュータの機種やOSの種類に依らず元の通りに再現して
　表示することができる電子文書のファイル形式
　文書配布時における標準的なフォーマットとなっている
　
　**画像用のファイル形式**
　・BMP
　　画像を圧縮せずにそのまま保存するファイル形式
　　画像は一切劣化しないが、ファイルサイズは大きくなる

　・JPEG
　　写真を保存するのに向いている画像圧縮形式です。圧縮率が高く
　　フルカラーの画像を扱えるためディジタルカメラで写真を記憶する
　　用途などでも使われている不可逆圧縮を行うため、圧縮のレベルに応じて
　　画像が劣化してしまう。

　・GIF
　　イラストやアイコンなどの保存に適した画像圧縮形式です。可逆圧縮であるため画質の劣化は
　　ないが、扱える色数が256色までという制限を持つ

　・PNG
　　当初はGIFの代替として登場しましたが、フルカラーを扱える上に可逆圧縮であるため
　　画像の劣化もないとう、ある意味万能な画像圧縮形式です。ただし単純な圧縮率では
　　JPEGのほうが勝る。

　**音声用のファイル形式**
　・MP3
　　音声を圧縮して保存するファイル形式です。人に聞こえない範囲の信号を削り落とすことで
　　データ量を削減することで不可逆の圧縮を行う。音楽CDレベルの温室を表現できるとされていることから
　　インターネット上の音楽配信や携帯音楽プレーヤーなどで用いられている。

　・MIDI
　　音声そのものではなく、ディジタル楽器の演奏データを保存することのできるファイル形式
　　MIDIデータを使うことで、ディジタル楽器を演奏させることができる。

　**動画用のファイル形式**
　・MPEG
　　動画を圧縮して保存するファイル形式で不可逆圧縮を行う。ビデオCDに使われるMPEG-1
　　DVDに使われるMPEG-2、インターネット配信や携帯電話で使われるMPEG-4などがある。

#ディレクトリとは
　ディレクトリは、ファイルをグループ化して整理するもの
　補助記憶装置の中は、**ディレクトリ(フォルダとも呼ぶ)**で管理されている。

　**・ルートディレクトリとサブディレクトリとカレントディレクトリ**
　　ディレクトリには、ファイルだけじゃなくて他のディレクトリも入れることができる
　　そうすることで、補助記憶装置全体に階層構造(ツリー構造）を持たせて管理することができる
　　階層の構造の一番上位に位置する**ディレクトリはルートディレクトリ**と呼び
　　他のディレクトリに含まれるディレクトリのことを**サブディレクトリ**と呼ぶ
　　また、自分がいま開いて作業しているディレクトリのことを**カレントディレクトリ**と言います。
　　※カレントディレクトリを含む１階層上のディレクトリのことは、**親ディレクトリ**と呼ぶ。
　![図87.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/fcb3e6e7-a38f-713e-da6f-e4fc4cad7eb2.png)



#ファイルの場所を示す方法
　ファイルは、ファイルへのパスを用いてその場所を指し示します。
　
　**絶対パスの表記方法**
　　パスを表記するにあたっては、次の約束事に従います。
　　①ルートディレクトリは「/」または「￥」であらわす。
　　②ディレクトリと次の階層との間は「/」または「￥」で区切る。
　　③カレントディレクトリは「.」であらわす
　　④親ディレクトリは「..」であらわす
　<font color="#cc0000">※③と④は絶対パス表記の場合この２つは関係ない</font>
　![図89.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/3ee6a8ff-d705-35f7-5c64-b3f3b08f8929.png)


　**相対パスの表記方法**
　相対パスにもパス表記するにあたって約束事に従う
　①ルートディレクトリは「/」または「￥」であらわす。
　②ディレクトリと次の階層との間は「/」または「￥」で区切る
　③カレントディレクトリは「.」であらわす
　④親ディレクトリは「..」であらわす。
　　<font color="#cc0000">※①は相対パスの場合関係ない</font>
　![図90.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/686519/7f25d16e-4eb6-4c97-b4e3-9c430c537fd9.png)



#以上
Rails で外部キー制約をつける際に別名をつける

```ruby
class Test < ActiveRecord::Migration[5.2]
  def change
    add_reference :tags, :owner, foreign_key: { to_table: :users }, default: nil, null: true
  end
end
```

```ruby
class Test < ActiveRecord::Migration[5.2]
  def up
    add_reference :tags, :owner, foreign_key: { to_table: :users }, default: nil, null: true
  end

  def down
    remove_reference :tags, :owner, foreign_key: { to_table: :users }, default: nil, null: true
  end
end
```

`add_reference :tags, :owner` と指定した場合、カラム名は `owner_id` となる。
Linuxの管理用設定ファイル、コマンド周りのまとめ

<h2>ユーザーとグループの管理</h2>

>ユーザーアカウントと/etc/passwd

　書式　①root : ②x : ③0 : ④0 : ⑤root : ⑥/root : ⑦/bin/bash
　　　　①ユーザー名…システム内で一意のアカウント名.
　　　　②パスワード…暗号化されたパスワード.現在はシャドウパスワードとして「x」が入ります.
　　　　　シャドウパスワードはetc/shadowに格納されていて、rootユーザーしか読み出しできません.
　　　　③UID…ユーザーを識別するための一意なID.rootは0、1~99はシステム管理用、そのほかは1000以降が割り当てられる.
　　　　④GID…グループを識別するための一意なID.
　　　　⑤GECOS…コメント.
　　　　⑥ホームディレクトリ…ユーザーのホームディレクトリの絶対パス.
　　　　⑦デフォルトシェル…ユーザーがログインしたり、新たにシェルを開いた際に起動されるシェルの絶対パス.

>グループアカウントとetc/group

　書式　①root : ②x : ③0 : ④
　　　　①グループ名
　　　　②グループパスワード…グループメンバー用のパスワード.現在はシャドウパスワードとして「x」が入ります.
　　　　③GID…グループを識別するための一意なID.
　　　　④グループメンバー…本グループをサブグループとするユーザーのユーザー名を入れます.

>コマンドを用いたユーザーとグループの管理

　・ユーザーアカウントの作成
　　構文：***useradd [オプション] {ユーザー名}***

　・既存のユーザーアカウントを変更
　　構文：***usermod [オプション] {ユーザー名}***

　・ユーザーアカウントの削除
　　構文：***userdel [オプション] {ユーザー名}***

　・パスワードの変更
　　構文：***passwd [オプション] {ユーザー名}***

 ・グループの作成
　　構文：***groupadd {グループ名}***

　・既存のグループ情報の変更
　　構文：***groupmod [オプション] {ユーザー名}***

　・グループの削除
　　構文：***groupdel {グループ名}***

　・所属しているグループの確認
　　構文:***id {ユーザー名}***
　　

<h2>ジョブスケジューリング</h2>
>cron

　cronは、crondとcrontabから構成されています.デーモンは1分おきにcrontabファイルを調べ、実行すべきスケジュールがあればジョブを実行します.crontabの編集はエディタではなく、***crontab -e***コマンドを用います.

　書式　# m h dom mon dow command
 
　例）
　  00 00 * * 1 /usr/local/bin/backup　 ⇒　毎週月曜日の0時00分にbackupファイルを実行
　*/10  * * * * /usr/local/bin/syscheck　⇒　10分おきにsyscheckを実行

>atコマンド

　1回限りの実行を予約します.
　構文　***at [オプション]***

>cronとatのアクセス制御

　cronのアクセスを許可するユーザーを/etc/cron.allowに、拒否するユーザーを/etc/cron.denyに記載します.同様に、atのアクセスを許可するユーザーを/etc/at.allowに、拒否するユーザーを/etc/at.denyに記載します.

>systemdによるスケジューリング

　タイマーUnitを使うことで何らかのイベントから一定時間後から定期的に実行するといったモノトニックタイマーとカレンダー指定で定期的に実行するといったリアルタイムタイマーが挙げられます.

<h2>ローカライゼーションと国際化</h2>
　ローカライゼーションとは、言語や通貨を地域や国に合わせることをいいます.国際化（i18n;internationalization）.
>ロケール

　構文　***locale [オプション]***
　現在のロケール設定を確認します.
【備忘録】docker-composeで立てたWindowsコンテナを再起動する方法


# はじめに
Dockerを使えばWindowsかLinuxかは関係ないと思っていた時期が僕にもありました。
OSによる挙動の違いはともかくとして、コンテナ化の方法によって差異が生じるみたいです。
Windowsでコンテナを作成するアプローチは大きく2種類あります。Hyper-Vを使う方法とWindowsのプロセス分離を使う方法です。詳細は割愛しますが、両者ではDocker（composeだけかもしれないけど）の挙動が微妙に違うらしく、再起動設定周りでハマりました。

# やりたいこと
Windows Serverコンテナでdocker-composeの再起動設定を有効にする。

# 環境
OS：Windows Server 2019 Datacenter

# 問題
マシン起動時にコンテナ立ち上げの有無を設定できるrestartオプションがDockerにはありますが、Linux環境で動作したdocker-compose.ymlをそのままWindows Serverコンテナに移植してもうまく再起動できませんでした。

# 原因
起動時と再起動時で、Docker周辺の動作状況を確認していたところ、docker-compose起動時に有効になるデフォルトネットワークが、再起動時に消失していることが判明しました。

# 対策
networksの設定をnatのexternalで作成すれば解決しました。

```yml
version: '3.5'

networks:
  default:
    external:
      name: "nat"

services:
  hoge:
    build:
      context: .
      dockerfile: ./hoge/Dockerfile
    container_name: hoge
    restart: always
    command: powershell
    stdin_open: true
    volumes:
      - .\hoge:C:\hogehoge
```

# 最後に
困ったら[マイクロソフトの公式ドキュメント](https://docs.microsoft.com/en-us/virtualization/windowscontainers/)を見るのが一番確実ですね。

# 注意および免責事項
本記事の内容はあくまで私個人の見解であり、所属する組織の公式見解ではありません。
本記事の内容を実施し、利用者および第三者にトラブルが発生しても、筆者および所属組織は一切の責任を負いかねます。
ラムダ式とは(Java)

ラムダ式というのがどうしようもなく理解できなかったので、自分なりに簡略化して理解した結果を記載しています。

#無名関数
まず無名関数についてWikipediaから抜粋。

>プログラミング言語における無名関数（英語: anonymous functionあるいはnameless function）[1]とは、名前付けされずに定義された関数のことである。

>無名関数を表現するための方法には様々なものがあるが、近年[2]主流となっているのはラムダ式による記法である。

(Wikipedia(https://ja.wikipedia.org/wiki/無名関数))

#ラムダ式
つまり、ラムダ式とは無名関数を表現するための方法。(「->」こんなやつ)
→ラムダ式とは名前付けされずに定義された関数のこと。

ちなみにJavaで書く場合はこんな感じ。(Wikipediaの無名関数から抜粋。)

```sample.java
import java.util.function.*;
...
BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
System.out.println(add.apply(2, 3));
```

↑この例で説明すると
・「(x,y)」が無名の関数の引数を表現している。

・「x + y」が関数の処理を表している。（この例では省略されているが「{return x + y}」のように表現しても良い。この方がメソッド感があってわかりやすいと思う。）

#関数型インタフェース
そもそもなんのために無名関数を使うの？ということで出てくるのが関数型インタフェース。
これざっくりいうと関数(ラムダ式やメソッド参照)を代入できるインターフェイスである。

例えばBiFunction<T,U,R>というインターフェイスは、

型パラメータ:
T - 関数の第1引数の型
U - 関数の第2引数の型
R - 関数の結果の型
→引数2つで戻り値を返す関数を代入できるインタフェース。

つまり、さっきの例の無名関数をこのインタフェースに代入して、このインタフェースに定義されているメソッド（apply）を呼び出すと無名関数の処理が呼び出される。
↓これの結果は、applyに引数として2,3を渡しているので2+3の結果が標準出力される。

```sample2.java
BiFunction<Integer, Integer, Integer> add = (x, y) -> {return x + y;};
System.out.println(add.apply(2, 3));
```


---
今までJavaで関数を変数に代入するという考え方をしてこなかったので理解するのが難しいのではないかと思います。
JavaScriptの本を読んでいると結構あたりまえに出てくる概念のようですし。
Jupyter(IPython)でNoteBookをモジュールとしてインポートする方法

Jupyter notebook で別のnotebookの関数を使う方法は公式サイトやQiita でも紹介されていますが、それをちょっとだけ便利にする方法を紹介します。

基本的には公式サイトの通りです。
https://jupyter-notebook.readthedocs.io/en/latest/examples/Notebook/Importing%20Notebooks.html

Qiitaにも良い紹介記事があります。
https://qiita.com/tdual/items/32d3918b4c8dd1f703e7

ただ、使いにくいのは import 時に notebook の内容がすべて実行されてしまうことです。全部のセルではなく一部のセルに定義した変数や関数だけ他の notebook でも使いたい！　fastai の [nbdev](https://github.com/fastai/nbdev) では、そのような場合はセルの先頭に"#export" という印をつけます。でも、nbdev のように大げさにしたくない。

なので、公式サイトにあるプログラムの NotebookLoader クラスに修正を加え、先頭に"#export" と印をつけたセルだけインポートされるように修正します。

```python
import io, os, sys, types
from IPython import get_ipython
from nbformat import read
from IPython.core.interactiveshell import InteractiveShell

def find_notebook(fullname, path=None):
    name = fullname.rsplit('.', 1)[-1]
    if not path:
        path = ['']
    for d in path:
        nb_path = os.path.join(d, name + ".ipynb")
        if os.path.isfile(nb_path):
            return nb_path
        nb_path = nb_path.replace("_", " ")
        if os.path.isfile(nb_path):
            return nb_path

class NotebookLoader(object):
    def __init__(self, path=None):
        self.shell = InteractiveShell.instance()
        self.path = path

    def load_module(self, fullname):
        path = find_notebook(fullname, self.path)
        with io.open(path, 'r', encoding='utf-8') as f:
            nb = read(f, 4)
        mod = types.ModuleType(fullname)
        mod.__file__ = path
        mod.__loader__ = self
        mod.__dict__['get_ipython'] = get_ipython
        sys.modules[fullname] = mod
        save_user_ns = self.shell.user_ns
        self.shell.user_ns = mod.__dict__
        try:
          for cell in nb.cells:
            if cell.cell_type == 'code':
                code = self.shell.input_transformer_manager.transform_cell(cell.source)
                # セルの先頭に "#export" と記述されているセルだけ実行する 
                if code.startswith("#export"):
                    exec(code, mod.__dict__)
        except Exception as ex:
            # セルに"#export" を付け忘れる場合が多いので、どこでエラーになったかわかるようにする
            print(code)
            raise ex
        finally:
            self.shell.user_ns = save_user_ns
        return mod

class NotebookFinder(object):
    def __init__(self):
        self.loaders = {}

    def find_module(self, fullname, path=None):
        nb_path = find_notebook(fullname, path)
        if not nb_path:
            return
        key = path
        if path:
            # lists aren't hashable
            key = os.path.sep.join(path)
        if key not in self.loaders:
            self.loaders[key] = NotebookLoader(path)
        return self.loaders[key]
```
これを nb_finder.py などのファイル名で保存します。使うときは

```python
import sys
import nb_finder as nbf
sys.meta_path.append(nbf.NotebookFinder())
```

とすれば、以降は他の notebookをimportすることができます。

```python
from mynotebook import *
```

インポート元の notebook では、他の notebook でも使いたい変数や関数を記述しているセルの先頭に "#export" を追加してください。そのセルを実行するのに必要な import文のあるセルにも #export を付けることを忘れないでください。
また、#export ではなく、不要なセルに #hide と指定するとそのセルはインポートされないようにするようにしても良いかもしれません。
(Windows)　ディレクトリ以下をまとめて削除するコマンドとオプション

～ メモ書き ～
```rd target_directory```とやると```ディレクトリが空ではありません```と出てきてしまう場合に、

## ディレクトリの下もまとめて削除する
```
rd /S /Q target_directory
```
オプションの意味は
- ```/S```　ディレクトリ内部をファイルも含めて再帰的に削除
- ```/Q```　「削除しますか？[Y/N]」をいちいち聞かない
【Flutter】【LayoutBuilder】画面を横にしたときに、レイアウトエラーが起きないようにする

## まえがき
Flutterでアプリ開発をしてると、画面が横になったときにレイアウトのエラーが起きてしまいますよね。

これは困るな〜

![layout_error.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311390/b6844b3b-ff32-11fd-a7f4-a3a71ca2d71e.gif)

`LayoutBuilder`を使うと、横になったときに横になったとき用の、レイアウトが組めるようになります。


## LayoutBuilder
これは、Widgetが建てたれる範囲を測ってくれます。

そこでサイズに合わせて建てるWidgetを条件分けしたりできます。

## サンプル

![layout_builder.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311390/098878ff-5a3a-58f4-05ef-5849f17b0e14.gif)

今回はSimulatorのiPhone SEでビルドしています。

まぁちょっと一瞬ぐちゃっと見えますが、一旦レイアウトエラーが起きないことに注目しましょう。

```dart
import 'package:flutter/material.dart';

class SampleLayputBuilder extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SampleLayputBuilder();
}

class _SampleLayputBuilder extends State<SampleLayputBuilder> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('LayputBuilder使ってない'),
      ),
      body: LayoutBuilder(
        builder: (context, constraints) {
          print(constraints);
          if (constraints.maxWidth < 600) {
            return Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                imageExplanation(),
                image(),
              ],
            );
          } else {
            return Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                imageExplanation(),
                image(),
              ],
            );
          }
        },
      ),
    );
  }

  Widget imageExplanation() {
    return Text(
      'この写真は、こないだ海で撮影したものです。\n彼女とデートしたときに追いかけっこをしました。\nワハハと笑って楽しかったです。',
      style: TextStyle(fontWeight: FontWeight.bold),
    );
  }

  Widget image() {
    return Image.asset('images/sample1.png');
  }
}
```

## 説明
```dart
LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth < 600) {
      return verticalWidget() //縦向きのWidget
    } else {
      return horizontalWidget() //横向きのWidget
    }
  },
),
```
Widgetが建てられるサイズを`constraints`に入れています。
`constraints.maxWidth < 600`は横の最大の長さが600以下かそうでないかで条件分けしています。

サンプルのコードでは

```
print(constraints)
```
することで、横幅と縦幅が表示されるようにしてるので参考にしてみてください。