OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニアリング組織論を読んだ。(Ch.2-2)

エンジニアリング組織論を読んだので、まとめてここに書こうと思います。
1冊をここにすべて載せれればいいんですけど、そんなスキルはまだないので
6章構成でいきます。(Ch.2)
ここで心理的安全性の話

心理的安全性 = 対人リスクをとっても問題ないという信念がチームで共有されていること。
心理的安全性 = 快適で居心地のよい環境ではない。

心理的安全性のメリット

|影響|解説|
|:---|:---|
|率直に話すようになる|課題について他のひとがどう思うかをそれほど気にせず発言することができる|
|考えが明晰になる|不安が少ないため、認知のゆがみが少なく、考えを明晰に表現できる|
|意義ある対立が後押しされる|関係性の悪化に伴った対立ではなく、より本質的な対立を健全に議論できる|
|失敗が緩和される|失敗を報告しやすくなり、ミスについて話し合う機会が増え、学習を行える|
|イノベーションが促される|今までの前提を取り払って、思考することができるようになり、創造的な意見が出る|
|組織内の障害ではなく目標に集中できるようになる|目標に対して、ストレートに向き合えている。組織内の理不尽を取り除くことに力をかけないでもすむ状態にある|
|責任感が向上する|対人リスクをとっても、目標に対して自立的に行動できるようになる|

対人リスク = 個々人の関係性が損なわれる可能性のある行動のこと。

心理的安全性が機能している場合、「問題に対して向き合う状況」が生まれる。

問題に対して向き合う状況のことを責任という指標だとすると、

||責任が低い|責任が高い|
|---|---|---|
|心理的安全性が高い|コンフォートゾーン(問題解決や発展的な議論はできない)|ラーニングゾーン(問題解決ができる)|
|心理的安全性が低い|無関心ゾーン(生産性の高い議論はできない)|不安ゾーン(問題解決できない)|

というマトリクスを表示することができる。

問題解決が生まれるときというのは、対人リスクを取りあって問題と自分たちという構図が生まれているラーニングゾーンにあたる。

高い心理的安全性を構築するには、
- メンティの弱さ・メンティの弱さを開示してもらう
- 自分の弱さ・自分の失敗を開示する

ことで、「どんなにだめなところを見せても、関係性が破綻することはないだろう」という確信をメンティに抱いてもらう必要がある。

どうすれば、その確信をもってもらえるのか？

1. メンティに承認のサインをおくり続ける。
 承認の種類は3つあり、存在承認・行動承認・結果承認の3つである。

|承認段階|解説|
|---|---|
|存在承認|存在承認とは、相手が今ここにいてくれてありがたいというメッセージ。|
|行動承認|「結論から話すようになった」のようにポジティブな行動を褒めるのでもなく言葉にして伝える| 
|結果承認|できあがったものに対して、それに主観をこめて伝える|

難易度として高い場合は、「声をかける」だけでも承認を与える行為になる。

2. ストーリーテリングをこころがける

3. SMARTな行動をこころがける。
指摘やフィードバックで最も危険な前提が、「自分の言葉は自分の思ったように相手に伝わっている」という前提。
正しく伝わらないことを前提として、解釈のブレをできるだけ減らしていくことで起こりうる誤解を減らすように努める。

||意味|解説|
|---|---|---|
|S|Specific(具体的な)|抽象的でない行動で、何をするのか解釈にブレの少ない言葉である|
|M|Measurable(測定可能な)|その行動が行われたことを、どのようにして計測するのか|
|A|Achievable(到達可能な)|精神論的で、過剰な数の行動ではなく、達成可能な行動として合意する、メンティがコントロールできる|
|R|Related(関連した)|メンティの課題とどのように関連しているのかをメンティが十分に説明できる行動である|
|T|Time-Bound(時間制限のある)|いつまでに行われるのか、いつまで測定されるのかということが具体的に決まっている|

4. 行動起こさせるには？
メンターはメンティのこころを動かすことは難しいが、行動変化を起こさせることはできる。
メンティが行動変化を起こすことができないとき、行動を阻害する力が働いている。（行動を継続的にとれるかとれないかは、行動を促進する力と阻害する力のバランスによって決まる。）

促進する力 = 自己効力感や周りからの承認など
阻害する力 = 周りからのからかい・誘惑など

行動変化を起こさせるには、メンティの行動を促進する力を増やす or 阻害する力を減らすことが求められるので、
この両方を満たすように定期的なフィードバックを行うことが方法の一つとして考えられる。

もし、メンティが望ましい行動をとれなかった場合は、とれなかった要因に共感しどのようにすればその要因が取り除けるのかを
話し合うことで解決策を生み出せる。

メンタリングは、自立的な人材を育むために行う。

1. 自分の気づかなかった問題に気がつくようになる
2. 認知の歪みによる感情と問題の癒着を切り離せる
3. 答えではなく、次の一手を生み出す行動を取れるようになる

この３つの状態(言い換えると、自分で自分をメンタリングしていくことができる状態 )に導いていく必要がある。

---
https://qiita.com/hirokidaichi/items/195d42ee056ea85a3150
関連してつぎに読みたい本

失敗の本質―日本軍の組織論的研究 (中公文庫)   戸部 良一 https://www.amazon.co.jp/dp/4122018331/ref=cm_sw_r_tw_dp_U_x_JHPwDb6X68QRB

チームが機能するとはどういうことか ― 「学習力」と「実行力」を高める実践アプローチ   エイミー・Ｃ・エドモンドソン https://www.amazon.co.jp/dp/B00N8J1NPQ/ref=cm_sw_r_tw_dp_U_x_oIPwDbXM9R4NZ

THE TEAM 5つの法則 (NewsPicks Book)   麻野耕司 https://www.amazon.co.jp/dp/B07PZB9DTK/ref=cm_sw_r_tw_dp_U_x_7IPwDbJJ2CT07
UbuntuでRe:VIEW環境を構築する

## 概要
Ubuntu22.04で、Re:VIEW環境を構築する

## Re:VIEWのインストール

まず、最初にRubyをインストールします。
Re:VIEWはRubyGemsからインストールします。
Re:VIEWからPDFを生成するために、TeXのインストールも必要です。

```
$ sudo apt update
$ sudo apt install ruby
$ sudo gem install review
$ sudo apt install texlive-lang-japanese texlive-latex-extra texlive-latex-recommended

```

執筆時点(24/3/30)で5.8.0がインストールされます。

```
$ review version
5.8.0
```


## Re:VIEWを作成する

最初に雛形を生成します。「review_sample」という書籍にしてみましょう。

```
$ cd ~
$ review-init review_sample
```

以下のコマンドでPDF作成です。

```
$ rake pdf
```

以下のコマンドでPDFを開きます。

```
evince book.pdf 
```

## Re:VIEW Templateから、技術書を作成する

TechBoosterの「Re:VIEW Template」から書籍を作成してみましょう。

```
$ git clone https://github.com/TechBooster/ReVIEW-Template
$ ReVIEW-Template/article
$ rake pdf
```


## Re:VIEW Templateでエラーが出た場合の対処

執筆時点(24/3/30)でUbuntu22.04とreview:5.8.0の組み合わせでは、
「$ rake pdf」を実行すると、
articles/styの中にあるファイル「techbooster-doujin-base.sty」の中で、
エラーが発生しました。

```
./techbooster-doujin-base.sty:56: LaTeX Error: Command \captionwidth already de
fined.
 Or name \end... illegal, see p.192 of the manual.
```

```techbooster-doujin-base.sty
- \newlength{\captionwidth}
+ %\newlength{\captionwidth}
 \setlength{\captionwidth}{\textwidth}
 \addtolength{\captionwidth}{-\captionnumwidth}
```
articles/styの中にあるファイル「techbooster-doujin-base.sty」の中で、
「\newlength{\captionwidth}」の行を、"%"を文頭につけてコメントアウトすると、Reviewのビルドが通るようになりました。

```
s$ rake pdf
review-pdfmaker  config.yml
✔ SUCCESS built ReVIEW-Template.pdf
```

以下のページの情報を参考にしました。

https://www.crossroad-tech.com/entry/ReVIEW-GitHubActions-build-failed#4-202391-%E8%BF%BD%E8%A8%98-%E8%A7%A3%E6%B1%BA%E6%96%B9%E6%B3%95

https://github.com/TechBooster/ReVIEW-Template/pull/107
ISONORAFTER 関数ってのがありまして、その話

リファレンスを紐解くと、
>A boolean function that emulates the behavior of a ‘Start At’ clause and returns true for a row that meets all of the condition parameters.

って書いてあって、"Start At" ってなによってことでもあるのでしょう。

**そもそも Start At ってなによ**
[DAX Queries - DAX | Microsoft Docs](https://docs.microsoft.com/en-us/dax/dax-queries) を読めばわかることであるけれども、ORDER BY とともに使用すると DAX クエリ で得られる結果に対し **"先頭"** を指定し以降の行を取得できるということ。で、同様の動作を DAX 関数でも使えるようになっている。

```text
ISONORAFTER(<scalar_expression>, <scalar_expression>[, sort_order [, <scalar_expression>, <scalar_expression>[, sort_order]]…)
```

# 試しながら確認
```text:SourceTable
SourceTable = 
    CROSSJOIN(
        SELECTCOLUMNS({2018, 2019, 2020}, "Y", [Value]),
        SELECTCOLUMNS({1, 2, 3, 4}, "Q", [Value])
    )
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/c719e616-3b5b-ff56-2c6c-f128a17b701f.png)

クロス結合なのですべての組合せなテーブルがあるとして、これにフィルタをかけて試す。

SourceTable[Y] が 2019 **以上**の行

```text:DEMO_1
DEMO 1 = 
    FILTER(
        SourceTable,
        ISONORAFTER(
            SourceTable[Y], 2019, ASC
        )
    )
```

SourceTable[Y] が 2019 **以下**の行

```text:DEMO_2
DEMO 2 = 
    FILTER(
        SourceTable,
        ISONORAFTER(
            SourceTable[Y], 2019, DESC
        )
    )
```

で、これがどうなるか。

```text:DEMO_3
DEMO 3 = 
    FILTER(
        SourceTable,
        ISONORAFTER(
            SourceTable[Y], 2019, ASC,
            SourceTable[Q], 3, ASC
        )
    )
```
SourceTable[Y] が 2019 で SourceTable[Q] が 3 の行以降

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/eb0f0e24-a5b3-a146-3056-b0dae0018a8a.png)


別の記述をするとこうなる。

```text:DEMO_4
DEMO 4 = 
    FILTER(
        SourceTable,
        SourceTable[Y] > 2019
        || SourceTable[Y] = 2019
        && SourceTable[Q] >= 3        
    )
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/378a130a-7ceb-a76a-0976-a035ffe2936f.png)

# 思ったこと🙄
まぁ、馴れは大切。で、確認するのはもっと大切。
# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
gitメモ

###### tags: `git`

# gitメモ
## #構造、バージョン管理の流れ
以下の３状態で管理
+ 作業ディレクトリ
+ ステージングエリア(add)
+ リポジトリ(commit)

## #git config   
ヘルプ
`git config --help`

各値設定
`git config --global user.name "[user_name]"`   
`git config --global user.email "[e-mail_address]"`   
`git config --global color.ui true`

設定の確認
`git config -l`

## #編集、add、commit
はじめに行う
`git init`
ファイル編集
`git add .`
（特定のファイルのみであればgit add [ファイル名]）
`git commit` （こちらの場合は自分でvi上でコメント）
または
`git commit -m "変更内容をコメント"`

## #ログを見る
全体のログ
`git log`
具体的に変更された場所を見る
`git log -p`
どのファイルが何箇所変わったか見る
`git log --stat
`
## #状態を見る
add状態、commit状態を確認
`git log --stat`
(addだけしてcomittしてない状態で)前の状態に戻す
`git checkout -- index.html`
addされていない状態で、変更点を確認する   
`git diff   `
addされたあとに変更点を確認する
`git diff --cached
`
## #ファイルの移動、削除
移動
`git mv`
削除
`git rm`

## #git管理に含めないファイルの設定
.gitignoreを作成
`vim .gitignore`

管理から外すファイル名を記述。（正規表現も可）
ex)
```
error.log
*.log
```

## #コミットを増やさず細かな修正を行う
`git commit --amend`

## #過去のバージョンへ戻る
作業ディレクトリもステージングエリアも一気に戻す時（HEADは１つ前という意味で、コミットIDを指定しても良い）
`git reset --hard HEAD`
2つ前に戻る時
`git reset --hard HEAD^`
git resetしたあとに戻す
`git reset --hard ORIG_HEAD`
Git hub pagesで画像が表示されない時の対処法

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている山本拓磨です。

今回は、git hub pagesで画像が反映されない時の対処法を紹介します。

プログラミング初心者であるため、内容に誤りがあるかもしれません。

もし、誤りがあれば修正するのでどんどん指摘してください。


☐　手順

１．git hubを開いて、自分のレポジトリのページに移動します。

![スクリーンショット (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429658/85715109-5903-99fa-5148-35e154904771.png)

そして、画像のファイル（この場合はjpg）を開きます。



２．画像を右クリックして、画像のアドレスをコピーする

画像が表示されたら、カーソルを画像まで持って行き、右クリックで「画像アドレスをコピーする」
をクリックしてください。

注意点として、google chromeでないと右クリックしても、表示されないことがあります。



３．そのアドレスをコピーして、htmlのコードに貼る。

<img src=""　のコードに先ほどコピーした画像のアドレスを貼ってください。

これで、後は更新すれば、画像がページに反映されているはずです。

更新しても、すぐには反映されないことがあるため、数分経ってからもう一度更新してください。
ADFS のセカンダリ構築・プライマリとの切替方法

Active Directory Federation Service (ADFS) の構築方法は検索するとたくさんヒットしますが、セカンダリ構成についてはまとまった情報があまりないように見受けられたので、少しではありますがまとめてみました。


##セカンダリ サーバーの構築方法
基本的にはプライマリ サーバーの構築 (初回のフェデレーション サーバー ファームの作成) と変わりはありません。
異なるのは ADFS 構成ウィザードの設定で、[Add a federation server to a federation server farm] を選択するだけです。
それまでの過程はプライマリの構成と変わらず、ドメイン参加、Active Directory Federation Service の機能の追加をするだけでOKです。

[Add a federation server to a federation server farm] を選択
![pic34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475866/8edd0a01-caca-1b8c-5366-546af81a1186.png)


[Primary Federation Server] の指定
![pic35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475866/1639cfb5-0d59-9c19-f464-685182a5266c.png)


※証明書の設定などもありますが、プライマリ サーバーの設定方法と同じため省略します



##プライマリ-セカンダリの切替方法 
構成ウィザードに沿って進めていただければ、あっという間にセカンダリ サーバーのセットアップは完了しますが、ここではプライマリ-セカンダリの切替方法をみていきます。

<b>プライマリ・セカンダリ切替</b>
セカンダリをプライマリに変更する場合、以下のコマンドを実行します。 

```
Set-AdfsSyncProperties -Role PrimaryComputer
```

復旧したサーバーをセカンダリとして構成する場合、新規プライマリを参照するように構成します。

```
Set-AdfsSyncProperties -PrimaryComputerName [新規プライマリの FQDN]
```

プライマリをセカンダリに変更する場合は、以下のコマンドを実行します。

```
Set-AdfsSyncProperties -Role SecondaryComputer -PrimaryComputerName  [プライマリの FQDN]
```


##プライマリとセカンダリの切替に際して
プライマリとセカンダリの切替に際して、両サーバー間で情報に差異がある場合 (たとえば、クレームルールの追加などが行われた場合) は切替前に同期を実施する必要があります。ただし、そのような更新を実施しない限りは、定期的な同期によってプライマリとセカンダリは同一情報を保持しているため、特に作業前に同期を待つ必要はありません。

また、プライマリとセカンダリの切替時に、一時的に両台ともプライマリ (もしくはセカンダリ) になるタイミングが発生しますが、これによってユーザーの認証に影響が出ることもありません。

なぜなら、ADFS の冗長構成というのは、両サーバー間でデータの同期を行うだけだからです。
プライマリでもセカンダリでも、複数のサーバーがプライマリであったとしても認証処理には関係ありません。

そのため、複数のサーバーがプライマリ (もしくはセカンダリ) になる影響としては、プライマリからセカンダリへの同期が行われなくなることくらいです。

(ユーザーが Azure AD などにアクセスする際、フェデレーション サービスにリダイレクトされますが、クライアントはそのフェデレーション サービス名の名前解決を行うので、フェデレーション サービス名に紐づくホストに認証が行われることとなります。名前解決の結果がプライマリであればプライマリ、セカンダリであればセカンダリに認証通信が発生します)



同期状態の確認方法
セカンダリで以下のコマンドを実行すれば同期状態を確認することができます。

```
Get-AdfsSyncProperties

(同期が成功している場合)
LastSyncFromPrimaryComputerName : 6-VM-ADFS
LastSyncStatus                  : 0         //最後の同期のステータス：成功
LastSyncTime                    : 8/27/2019 11:10:47 AM
PollDuration                    : 300       //同期間隔
PrimaryComputerName             : 6-VM-ADFS
PrimaryComputerPort             : 80
Role                            : SecondaryComputer

(同期が失敗している場合)
LastSyncFromPrimaryComputerName : 6-VM-ADFS
LastSyncStatus                  : 1         //最後の同期のステータス：失敗
LastSyncTime                    : 8/27/2019 06:10:47 AM
PollDuration                    : 300       //同期間隔
PrimaryComputerName             : 6-VM-ADFS
PrimaryComputerPort             : 80
Role                            : SecondaryComputer
```

プライマリで同じコマンドを実行すると、下記のように自身がプライマリであることを示します。

```
Get-AdfsSyncProperties

Role
----
PrimaryComputer
```

また、イベント ログを確認することで、前回以前の同期結果も確認することができます。
>
Applications and Services Logs > AD FS > Admin
同期成功のログ : イベント ID 348
同期失敗のログ : イベント ID 344、345

セカンダリ側に同期されたイベント 348
![pic36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475866/3e3bbe66-a13b-4329-aa1f-34e3475a57ae.png)
Vue CLI スタートガイド

# はじめに
Vue.jsの利用方法にはhtmlのscriptタグでVue.jsを読み込むCDN版と、ローカルにVue.jsを落として開発するCLI版があります。前者は「とりあえずVue.jsを試してみよう」という方や「jQueryみたいな感じで部分的にVue.jsを取り入れてみよう」という方向けですが、Vue.jsで本格的なシングルページアプリケーション開発を行う場合はCLI版でスタートする方が良いそうです。
※参考[Vue.js公式-インストール](https://jp.vuejs.org/v2/guide/installation.html)
ということでVue CLIを使ってみたので、利用し始めるまでの手順をまとめてみました。

# node.jsのインストール
javascriptパッケージ管理システムのnpmを使用するために、node.jsをインストールします。
[node.js公式](https://nodejs.org/ja/)からインストール用ファイルをダウンロードして、実行しましょう。
インストール完了後にnpmのバージョンが確認できれば成功です。

```terminal
$ npm --version
6.9.0
```

# vue cliのインストール
以下のコマンドを入力してvue cliをインストールします。

```terminal
$ npm install -g @vue/cli
```

インストール完了後にvueのバージョンが確認できれば成功です。

```terminal
$ vue --version
3.11.0
```

# Vueプロジェクトの作成
Vueプロジェクトを作成したい場所にカレントディレクトリを設定し、以下のコマンドを入力します。`my-project`のところはお好きな名前を入力してください。

```terminal
$ vue create my-project
```

プロジェクト作成後にディレクトリの中身を確認すると、先ほど指定した名前でフォルダが作られています。

```terminal
$ ls
my-project
```

そのフォルダ内に移動して、`npm run serve`を入力すると、開発用サーバを起動することができます。

```terminal
$ cd my-project
$ npm run serve
```

この状態で`http://localhost:8080/ `にアクセスすると、Vue.jsのデフォルトページが表示されます。
![スクリーンショット 2019-08-26 8.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/8fa64d07-fd12-a7b5-e4d4-04ecee446a08.png)

# プロジェクト構成
`vue create my-project`で何が作られているのか確認してみます。
<img width="298" alt="スクリーンショット 2019-08-31 11.47.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/5a846026-6397-261a-3a36-9ad33b87de2e.png">

## node_modules
npmでインストールしたパッケージは全てここに格納されています。
デフォルトでgitignoreされています。

## public
### favicon.ico
お気に入りやブックマークとかに表示されるアイコンです。

### index.html
Vue.jsを表示させるための大元のhtmlファイルです。

## src
### assets
画像などの静的ファイルを格納する場所です。

### components
子コンポーネントのVueファイルを格納する場所です。

### App.vue
ルートコンポーネントのVueファイルです。
このファイルからcomponentsに格納した子コンポーネントを呼び出してWebページを組み立てていきます。

### main.js
ルートコンポーネント（App.vue）を呼び出してindex.html（のdiv要素）にマウントするためのjsファイルです。

## babel.config.js
ES6からES5への変換をしてくれる「babel」の設定ファイルです。
※参考[【５分でなんとなく理解！】Babel入門](https://qiita.com/Shagamii/items/a87181c22ea777ee2acc)

# ビルド

```terminal
$ npm run build
```
で、プロジェクトのビルドを行うことができます。

ビルドを行うと`dist`ディレクトリが作成されます。
<img width="298" alt="スクリーンショット 2019-08-31 12.12.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214279/245f7d18-abac-b8b2-d285-655dae144405.png">

大元のindex.htmlがあり、それに対してcss、js、imgを適用していく、というよく見るファイル構成になりました。
cssやjsはminファイル化されています。

ちなみにserveやbuildといったコマンドはpackage.jsonのscriptsに記載されています。

```json
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  }
```
ここを変更すればserveやbuild実行の内容を変更したり、deployコマンドを足してserveやbuildと同じノリでデプロイしたり、といったことが可能になります。
※参考[Vue.jsを最速でビルドして、無料で公開するぞ！[ハンズオン形式]](https://qiita.com/kurosame/items/1e8754fceeba9b9bfcd1)
Azure AD の機能でドメイン単位のアクセス制限を行うことはできる？

基本的には、Azure AD の機能でドメイン単位のアクセス制限を行うことはできません。
基本的にと書いたのは、対象のドメインを AD FS に Federation させて、AD FS のクレーム ルールで何とかするという方法も考えられますが、そこまでするメリットはないように見受けられます。

Azure AD の機能でアクセス制限を行いたい場合は、条件付きアクセスを使用して、ユーザー単位、グループ単位、アプリケーション単位、デバイス単位などなどでアクセス制限をかけるほうがはるかに簡単です。

では、ドメイン単位のアクセス制御が Azure AD の機能で全くできないかというと、そういうわけでもありません。

条件付きアクセス と 動的グループ の機能を併用することで、一定のアクセス制限は可能となります。

###具体的な設定方法は？

動的グループのメンバーシップ ルールで以下のような設定を行います。
>
プロパティ : userPrincipalName
演算子 : Contains
値 :  domainnameを指定


このような動的グループのメンバーシップ ルールを制御したいドメイン数分用意します。
このメンバーシップ ルールによって、UPN に特定の値 (ドメイン) が含まれるユーザーが存在する場合、指定したグループに自動的にユーザーを仕分けることができます。

そして、条件付きアクセスの適用対象となるグループに、上記で作成したグループを指定します。
指定したグループごとに、このアプリにはアクセスさせたくない、といった指定を設定すれば、実質的にドメイン単位での特定のアプリケーションへのアクセス制限を実現することができます。

###そのほかの機能は？
そのほかの機能としては、テナント制限がありますが、こちらは社内環境の Proxy に社内からアクセス可能なテナントを指定することで、他のテナントにアクセスさせなくするということが実現できますが、制限の仕組みは全然異なるものとなります。

テナント制限について
https://github.com/jpazureid/blog/blob/master/articles/azure-active-directory/tenant-restriction.md
libwebp を Windows (VC++) でビルドしたメモ


## ソースコード入手

[github ミラーのリリース](https://github.com/webmproject/libwebp/releases)から最新版をダウンロードして展開。

本記事執筆時点（2019/08/31）では v1.0.3 が最新だった。

## ビルド

基本的には、展開したソースツリーのルートディレクトリにおいて `nmake` 一発でビルドできる。

### スタティックライブラリ

`README` 記載の通りに

```
nmake /f Makefile.vc CFG=release-static RTLIBCFG=static OBJDIR=output
```

`RTLIBCFG` が `static` なので、この場合 VC++ ランタイムもスタティックリンクになる。

したがって、これをリンクする実行ファイルも VC++ ランタイムはスタティックリンクにすること。

VC++ ランタイム DLL を利用したければ、`RTLIBCFG` を `dynamic` にしておくとよいだろう（ビルドは未確認）。

### DLL

DLL をビルドするには以下のようにする：

```
nmake /f Makefile.vc CFG=release-dynamic RTLIBCFG=static OBJDIR=output
```

`RTLIBCFG` に関してはスタティックライブラリと同様で、`static` にすれば `KERNEL32.dll` にしか依存しない DLL がビルドされる。

`RTLIBCFG` は、最終的にリンクする実行ファイルのビルド設定に揃えて選ぶこと。
read, write, fetchの違い【Rails.cache.fetchを例に解説】

# 先に結論
read：データを読み込む
write：データに書き込む
fetch：データを1つ取り出す（取ってきた後に、読み込みか書き込みか決定する）

以上です。

fetchについては[フェッチ【DB】 - 「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11583.html)を読むと理解が深まるかと思います。

# 背景
Railsで`Rails.cache.fetch`メソッドを調べていて、「あれ、fetchってそもそもどういう意味だっけ...」となったので調べました。

# 具体例（Rails.cache.read, write, fetch）
Railsのキャッシュを操作する`Rails.cache`を例に挙げます。

・read、writeの使い方

```rb

# キャッシュからデータを読み込む（'city'をキーとするデータが存在しないのでnilが返ってくる）
Rails.cache.read('city') # => nil

# キャッシュにデータを書き込む（'city'がキー、'Tokyo'が値）
Rails.cache.write('city', 'Tokyo')

# キャッシュからデータを読み込む（'Tokyo'が返ってくる）
Rails.cache.read('city')  # => 'Tokyo'

```

・fetchの使い方

```rb

# キャッシュからデータを取ってくる（'city'をキーとするデータが存在しないのでnilが返ってくる）
Rails.cache.fetch('city') # => nil

# キャッシュからデータを取ってくる
# もしデータが存在しなければ、do~endに囲まれたブロック部分を書き込む
Rails.cache.fetch('city') do
  'Tokyo'
end

# キャッシュからデータを取ってくる（'Tokyo'が返ってくる）
Rails.cache.fetch('city') # => 'Tokyo'

```

以上です。 

参考文献：[Ruby on Rails API 公式サイト](https://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html)
wagtailについて

こんにちは！
今回は僕のインターン先で使用しているWagtailについて勉強がてら、書いていこうかなと思います。
興味のある方は読んでみてください！

##Wagtailとは
WagtailとはDjango上に構築されたコンテンツ管理システムのことを言うそうです。
このWagtailではユーザーエクスペリエンスに重点を置いており、使用者、開発者に正確な制御を提供しています。

##Wagtailの特徴
・著者と編集者のためのすばやく魅力的なインターフェース
・標準のDjangoテンプレートを使用してデザインを完全に制御
・標準のDjangoモデルを使用してコンテンツタイプを設定する
・箱からすぐに取り出してください。 必要に応じてキャッシュに優しい
・緊密に統合された検索
・強力なドキュメントとイメージ管理
・埋め込みコンテンツの幅広いサポート
・既存のDjangoアプリケーションとの直接的な統合
・シンプルで設定可能な権限
・ワークフローのサポート
・拡張可能なフォームビルダ
・マルチサイトおよびマルチ言語サポート
・優れたテストカバレッジ
上記引用です　[上記引用元](https://githubja.com/wagtail/wagtail)

##Wagtail利用
Wagtailを利用するためにはまず、インストールする必要があります。
[こちら](https://docs.wagtail.io/en/stable/)のドキュメントに従ってインストールしてみてください。
インストール完了後以下のコマンドを打ってください。

```
$ mkdir mysite
$ cd mysite
$ wagtail start config .
```
そして、以下のコマンドでアプリケーションを追加します。

```
$ python manage.py startapp cms
```
そして以下のコマンドで開発用サーバを立ち上げましょう。

```
$ python manage.py runserver
```
これでhttp://localhost:8000/に接続するとページが表示されます。

これらすべてともっと詳しい説明が参考文献に乗っているサイトに書いてあるので、もっと詳しく知りたい方はそちらを参考にしてみてください。
最後までお読みいただきありがとうございました。

##参考文献
[Wagtailのすすめ(1) DjangoベースのCMSを比較・検討してWagtailを選択した話](https://qiita.com/j54854/items/96396f24fe8ce9b60d05)
[wagtail – 柔軟性とユーザーエクスペリエンスを重視したDjangoのコンテンツ管理システム
投稿日：2018年4月4日](https://githubja.com/wagtail/wagtail)
TCPDFを使ってPHPでPDFに文字を出力したい

##やりたいこと
Web上で必要事項を入力させ、ボタンを押すと、テンプレートのPDFに入力した内容の文字を埋め込んだPDFファイルを作成させる。みたいな機能を作りたい。

##用意するもの
今回は以下のライブラリを使用してみた。
###TCPDF
https://tcpdf.org/
ソースはGitHubのリンクからCloneをダウンロード。
###FPDI
https://www.setasign.com/products/fpdi/about/
テンプレートPDFを読み込むのに必要


####composerで落とす場合
composer.phar require tecnickcom/tcpdf
composer.phar require setasign/fpdi
composer.phar require setasgin/fdpi-tcpdf

この3つを準備しておけば大丈夫。な、はず。

展開したものを今回は以下のように設置。
tcpdf
→tcpdf.php
→fpdi
　→autoload.php
　→その他fpdi
→その他tcpdf



##実際に使ってみる

まずはインスタンス化。

```php
require_once('tcpdf/tcpdf.php');
require_once('tcpdf/fpdi/autoload.php');

$pdf = new setasign\Fpdi\Tcpdf\Fpdi();
```

次に初期設定。

```php
 $pdf->SetMargins(0, 0, 0); //マージン無効
 $pdf->SetAutoPageBreak(false); //自動改ページ無効
 $pdf->setPrintHeader(false); //ヘッダー無効
 $pdf->setPrintFooter(false); //フッター無効
```
今回のようにテンプレートのPDFがそもそもカッチリ用意されている場合は不要な気もするけど一応。


次にテンプレートのPDFを読み込ませる。

```php
$pdf->setSourceFile(テンプレのpath);
$pdf->AddPage();
$tpl = $pdf->importPage(1);
$pdf->useTemplate($tpl);
```

まずsetSourceFileで、テンプレートとなるファイルを指定。
AddPageでページを追加。
tplにテンプレートファイルをインポート。引数はページなので、今回は1ページ目を指定。最後にuseTemplateでテンプレートPDFの1ページ目が埋め込まれたtplを指定して、テンプレートを埋め込む。


あとは入力された内容を埋め込んでいく。

```php
$pdf->SetFont('kozminproregular', スタイル, サイズ);
$pdf->Text(x座標, y座標, テキスト);
```

一応日本語フォントは用意されていたが、TCPDF自体がちょっと日本語に弱いみたいなので、フォントにこだわりたい場合はAddFontメソッドなどを使って色々設定する必要がありそう。


一通り文字の埋め込みが終わったら、最後に出力。

```php
$pdf->Output(出力時のファイル名, 出力モード);
```

出力のさせ方にはいくつかのパターンが用意されている。
- I：ブラウザで表示（デフォルト）
- D：強制ダウンロード
- F：指定されたパス上にファイルを保存
使うのはこのあたりだと思う。

#####Fモードで出力させる時の注意
ファイル名のところでパスもつけてあげれば、指定のパス上に作成されたPDFを保存することができるが、通常ではローカルファイルとしての保存しか出来ない仕様になっていた。
今回はサーバ上に作成したPDFを保存したかったので、以下のように修正した。

```php
//tcpdf/include/tcpdf_static.php
//return以外全てコメントアウト
public static function fopenLocal($filename, $mode) {
//		if (strpos($filename, '://') === false) {
//			$filename = 'file://'.$filename;
//		} elseif (stream_is_local($filename) !== true) {
//			return false;
//		}
		return fopen($filename, $mode);
	}
```

これでサーバ上にも問題なく保存できるようになった。


以上で、テンプレートのPDFにユーザが入力した内容を埋め込んだファイルを新たに作成することが出来るようになった。

今回は単純な文字の埋め込みだけだが、用意されているメソッドはけっこう多くて、色んな編集が出来そう。PDFに対して色々こねこねしたい時はお世話になりそう。


##参考
・TCPDFマニュアル（勝手訳）
http://tcpdf.penlabo.net/method.html
用意されているメソッドの情報がいっぱい載っていたので、引数がよくわかんない時や、こーいうこと出来ないかな？って思った時にお世話になりました。

・TCPDFの部屋
http://www.t-net.ne.jp/~cyfis/tcpdf/index.html
こちらは目的別にまとまっています。
TravisCIでRubyビルドが失敗する場合の対処法

#概要
Rubyビルド中に以下のようなエラーが出た場合の対処法になります。
(以下はTravisCIで発生したエラーをそのままコピペしたもの)

```terminal
$ bundle install --jobs=3 --retry=3 --deployment
Traceback (most recent call last):
	4: from /home/travis/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:15:in `<main>'
	3: from /home/travis/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:15:in `eval'
	2: from /home/travis/.rvm/gems/ruby-2.5.1/bin/bundle:23:in `<main>'
	1: from /home/travis/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/rubygems.rb:308:in `activate_bin_path'
/home/travis/.rvm/rubies/ruby-2.5.1/lib/ruby/2.5.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
```

#なぜエラーが起きたか
エラー内容をもとに調べて見たところ、下記を見つけました。
https://travis-ci.community/t/bundle-install-started-failing-on-ruby-build/4368

どうやら、TravisCIのベースがTrustyからXenialに変わったことが原因のようです。
https://kledgeb.blogspot.com/2013/08/ubuntu.html

#対処法
.travis.ymlに下記を追加することで、今まで通りTrustyをベースにできるようなので、
今回はそれで対応したところビルドが成功するようになりました。

```yml
dist: trusty
```
Githubのviewedを活用してレビューを効率化する

## 詳細
大規模なプルリクエストをレビューする必要がある場合、レビューだけで数時間かかることがあります。その様な場合、レビュー途中で別の作業を行わなくてはならない状態になることも多くあり、再度レビューを再開すると進行状況がわからなくなり、更に時間がかかります。

ファイルを確認済み（**Viewed**）としてマークすることにより、進行状況を追跡する簡単な方法がありますのでご紹介します。
## 使い方
プルリクエストの上部からレビューの進行状況をすばやく確認できます。ここには、表示したファイルの数と残っているファイルの数が表示されます。各ファイルを確認済み（**Viewed**）としてマークすると、自動的に折りたたまれ、コードのレビューが迅速になります。
![01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229633/484b6c2d-c0bf-03cd-e886-fc661de3e76f.gif)
ファイルが変更された場合、**Viewed**のチェックは外され、**Changed since last view**が表示されるため、新しい変更を見逃すことはありません。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229633/7550ae75-fe44-c42f-33ea-6dc3eec1d4a2.png)
この機能により、大規模なプルリクエストを簡単に確認し、進捗を追跡できるようになりました。
## 参考記事
https://help.github.com/en/articles/reviewing-proposed-changes-in-a-pull-request#marking-a-file-as-viewed
DataGridViewの編集コントロール(テキストボックス)に実装されたValidationは実行されない

DataGridViewの編集コントロール(テキストボックス)にValidationを実装しても、セルの編集時には実行されない。

# 解説
テキストボックスの編集終了時のイベント発生順序

1. Leave
1. Validating
1. Validated

フォーカスが外れてからValidationが行われる。

DataGridViewのセル編集終了時のイベント発生順序

1. CellValidating
1. CellValidated
1. 編集コントロールの開放が開放され、IsCurrentCellInEditModeがfalseになる
1. CellEndEdit
1. CellLeave

Validationが行われてから、フォーカスが外れることなく編集コントロールが開放される。このため、テキストボックスのLeave以降のイベントは発生しない。

編集コントロールでValidationを行いたいなら、DataGridViewのイベントで行う必要がある。
textCNNを可視化（後半）

[前回](https://qiita.com/niship2/items/815ad0804861ed09aa50)の続き。

# 4.可視化

## 各層をconv_layersに収納↓

    for lay in model.layers:
        print(lay.name)

    print("-"*25)
    conv_layers = [l.output for l in model.layers[:13]]
    from tensorflow.keras.models import Model, Sequential
    conv_model = Model(inputs=model.inputs, outputs=conv_layers)
    conv_outputs = conv_model.predict(x)
    for i in range(len(conv_outputs)):
        print(f'layer {i}:{conv_outputs[i].shape}')  

# 5.出力結果
１回csvに落としてエクセルで作業。

    temptable = []
    for gyo in conv_outputs[5][0]:
        temptable.append(gyo[0])
    df = pd.DataFrame(temptable)
    df.to_csv("lay5.csv")


    temptable2 = []
    for lis in model.layers[5].get_weights()[0][0]:
        tbl.append(lis[0])
    df = pd.DataFrame(tbl) #.to_csv("test.csv") #n毎目のフィルタの注目文字を特定。
    df.to_csv("weight_5.csv")

## conv2dのfilter(h=3)、filter(h=4)、filter(h=5)を通したもの。
※filterは拝借したコードをそのまま使ってるので、h=3,4,5の３つ。
１行＝filter後の出力（h=3なら497個、h=4なら496個、h=5なら495個）
列＝各フィルター(100個）
filter5だと特定のフィルタの数値が高くなっているような。

* fiter(h=3)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/226b1798-0f5f-ec87-4c2f-5ef19b564559.png)


* filter(h=4)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/70d36a96-2e19-1f5b-3c8a-ac17af01198f.png)


* filter(h=5)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/7dac01f0-14fc-e519-7122-dd44ede9fca3.png)


## 重み
縦＝embeddingしたワード（4547個）、横＝フィルター数（100個）

* filter(h=3)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/0b819c05-aeea-75f3-7f21-1b530797f688.png)

* filter(h=3) ズームアウト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/b65c5481-1494-5d8a-9300-4adb89084949.png)




あれ、255番目以降のワード（250~4000くらいまで）の数値の反応が薄い！


## 注目ワード
textCNNが注目したワード上位。参考で木系の分類器での注目語（情報利得）も。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/385220/2d81b306-bf8d-ec05-61a6-733c51d55b47.png)



# 6.検討
注目語で木係と着目しているもんがほとんど違うのは、CNNは共起語に注目してるから？。
というかワードの重みづけ、256番目以降が全く反応していないのが気になります。これは短いepoch数でearly stopしたせいなのかな？
他のデータでも試してみようと思いました。
【Office365】会議室・備品の予定を特定の部署・人のみ登録出来るようにする

##実現できること
Office365 予定表機能で、会議室・備品に予定登録出来る人や部署を限定する方法です。
例えば、会議室Ａを総務部のみ予定登録出来るようにします。総務部のＢさんが会議室Ａで打ち合わせをするために予定を取りました。もちろん、それはＯＫです。
ですが、情報システム部Ｃさんが会議室Ａでの予定を取ろうとすると、会議室Ａより自動的に辞退メールがくるそんな仕様のPowerShellを今回ご紹介します。
##PowerShellでの登録方法
```PowerShell:登録(構文).ps1
Set-CalendarProcessing -Identity "対象のリソースメールボックスのアドレス" -AutomateProcessing AutoAccept -AllBookInPolicy $False -BookInPolicy "予約を許可するセキュリティグループ/ユーザーのメールアドレス"
```
AllBookInPolicyをfalseにして、まず、予約権限をなくします。
BookInPolicyで対象者を会議室・備品の予約を可能とします。

会議室Aの予約可能な部署を総務部だけにしたい場合だと、具体的にはこんな感じ。

```PowerShell:登録.ps1
Set-CalendarProcessing -Identity "会議室A@qiita.com" -AutomateProcessing AutoAccept -AllBookInPolicy $False -BookInPolicy 総務部@qiita.com
```
部署や人を複数指定したい場合は、カンマ区切りでいけます。
この場合、予定表へのアクセス権限は、総務部はLimitedDetails(空き時間情報・件名・場所の参照可能)、他の人はAvailableOnly(予定ありとしか見えません)になります。
【権限については[しーるの忘備録](http://alt.st/301)を参考にしました】
##本当に設定できたのか確認する
設定したけど、じゃあ本当に設定できているのか確認します。

```PowerShell:確認(構文).ps1
Get-CalendarProcessing 対象のリソースメールボックス | select -ExpandProperty BookInPolicy | Get-Recipient | select DisplayName,PrimarySmtpAddress
```
先ほど確認した会議室Ａの設定を確認しましょう。

```PowerShell:確認.ps1
Get-CalendarProcessing 会議室A@qiita.com | select -ExpandProperty BookInPolicy | Get-Recipient | select DisplayName,PrimarySmtpAddress
```
実行すると以下の結果が返ってきます。
DisplayName         PrimarySmtpAddress
総務部               総務部@qiita.com

ちなみに、設定されてない状態だと結果は空白で何もかえってこないので、ご注意ください。

設定するのは良いですが、管理が面倒ですね。ユーザーと本当に予約できる人を絞るべきなのか？今一度、相談してから登録したほうがよさそうです。
【Rails】meta-tagsを使う

###アプリケーションルートへ
```
$ cd setsubi_app
```

###Gemfileに以下を記述します。

```Gemfile.
gem 'meta-tags'
```

###bundlerで導入。今回はプロジェクト直下に配置

```
$ bundle install --path vendor/bundle
```

###ja.ymlを作成する
```config/locales/meta_tags.ja.yml
en:
  meta_tags:
    defaults:
      site: 'xxxxxxxxのまとめ集'
      description: 'xxxxxxxxをまとめています'
      keywords: 'xxxxxxxx'
      title: 'xxxxxxxxのまとめ集'

```


###app/helpers/application_helper.rbに記述

```app/helpers/application_helper.rb
module ApplicationHelper
  def show_meta_tags
    if display_meta_tags.blank?
      assign_meta_tags
    end
    display_meta_tags
  end
 
  def assign_meta_tags(options = {})
    defaults = t('meta_tags.defaults')
    options.reverse_merge!(defaults)
 
    site = options[:site]
    title = options[:title]
    description = options[:description]
    keywords = options[:keywords]
    image = options[:image].presence || image_url('image.png')
 
    configs = {
      separator: '|',
      reverse: true,
      site: site,
      title: title,
      description: description,
      keywords: keywords,
      canonical: request.original_url,
      og: {
        type: 'article',
        title: title.presence || site,
        description: description,
        url: request.original_url,
        image: image,
        site_name: site
      },
      fb: {
        app_id: '*****'
      },
      twitter: {
        site: '@twitter_account',
        card: 'summary',
      }
    }
 
    set_meta_tags(configs)
  end
end

```

###application.html.erbに記述

```app/views/layout/application.html.erb
<head>
<%= show_meta_tags %>
</head>
```

###各ページで上書きする

```
<% assign_meta_tags title: @region.jp+'のxxxx会社',
                    description: @region.jp+'のxxxxをご紹介します',
                    keywords: @region.jp+' xxxx' %>
```


参考：https://easyramble.com/rails-meta-tags.html
手っ取り早く巨大サイズのファイルを作る

手っ取り早く巨大ファイルを作る方法（小ネタ）です。

小難しいコマンドは使いません。
Windows, Linux どちらも（ほぼ）同じ方法でいけます。
（数学ネタも少しあります。）

#Windows(DOS窓) の場合

まず適当なファイルを、メモ帳(notepad.exe)等で作ります。
（１バイトでも可です。）

そのファイルを、自分自身に上書き追加します。

`type bigfile.txt >> bigfile.txt`

これを繰り返すと、**２のべき乗** でファイルサイズが増加します。
`( 1, 2, 4, 8, 16, 32, ・・・ )`

```
2019/08/30  23:50             1,024 bigfile.txt
    ：
2019/08/30  23:50             2,048 bigfile.txt
    ：
2019/08/30  23:50             4,096 bigfile.txt
```

数百ＭＢ程度なら、わりとすぐ作れます。

IN と OUT が同じファイルだから気になる～ という場合は、
２個のファイルで交互に上書き追加します。

`type bigfile1.txt >> bigfile2.txt`
`type bigfile2.txt >> bigfile1.txt`

これは１行にまとめられます。

`type bigfile1.txt >> bigfile2.txt & type bigfile2.txt >> bigfile1.txt`

この場合は、**フィボナッチ数列** でファイルサイズが増加します。
`( 1, 1, 2, 3, 5, 8, 13, ・・・ )`

```
2019/08/30  23:58                 8 bigfile1.txt
2019/08/30  23:58                13 bigfile2.txt
    ：
2019/08/30  23:58                21 bigfile1.txt
2019/08/30  23:58                34 bigfile2.txt
    ：
2019/08/30  23:58                55 bigfile1.txt
2019/08/30  23:58                89 bigfile2.txt
```

さらに２ファイルのサイズの比は、**黄金比** に近づきます。

```
2019/08/30  23:59           121,393 bigfile1.txt
2019/08/30  23:59           196,418 bigfile2.txt
    ：
2019/08/30  23:59           317,811 bigfile1.txt
2019/08/30  23:59           514,229 bigfile2.txt
    ：
2019/08/30  23:59           832,040 bigfile1.txt
2019/08/30  23:59         1,346,269 bigfile2.txt
```

参考
[フィボナッチ数列と線形代数](https://qiita.com/taketo1024/items/4c4d3c01aa92b42dc1b2)

#Linux の場合

Linux (CentOS7) では、自分自身に上書き追加が できないようです。

```
[xxuser@xxhost ~]$ cat bigfile.txt >> bigfile.txt
cat: bigfile.txt: 入力ファイルと出力ファイルが同じです
```

詳しくは書きませんが、標準コマンドで自分自身に
無理に上書き追加しようとすると、暴走する可能性があります。
（てか暴走しました :sweat_smile: ）

なので Linux では、２ファイル交互方式です。

`cat bigfile1.txt >> bigfile2.txt`
`cat bigfile2.txt >> bigfile1.txt`

または１行にまとめます。

`cat bigfile1.txt >> bigfile2.txt;cat bigfile2.txt >> bigfile1.txt`


でも やっぱり Windows と同様、自分自身に上書き追加したい！
という方は、**この記事の最後** をご覧ください。

#注意点

上記コマンドを、調子に乗って連打しないでね :wink:

ＰＣ／サーバには、パーティションのサイズや、
メモリの上限があります。あと I/O wait とか。

マシンが重くならない程度に、気を付けて作ってください。

#Linux で自分自身に上書き追加

Linux の章で、ファイルは自分自身に上書き追加できない、
と書きましたが、以下の方法があります。

`tac bigfile.txt >> bigfile.txt`

（一般的でないと思うので、**ベータ版** として扱ってください。）

`cat` ではなく `tac` を使います。
CentOS7 で試したところ、暴走せずに１ＧＢのファイルを作れました。

皆さまも よければ検証してください。
JavaからElasticSearchのindex作成

#はじめに
JAVAからElasticSearchを連携する際には、ElasticSearch　Rest　High Level Clientライブラリを利用して簡単に操作できます。
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

#ライブラリ導入
MVNリポジトリからバージョンを探してGradleの記載をコピーしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/cc47ddbb-e4b3-d8df-bb5d-7a1fe2f36c47.png)

例：

```gradle
// https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client
compile group: 'org.elasticsearch.client', name: 'elasticsearch-rest-high-level-client', version: '7.3.1'

```

#index作成概要例
```java
// Indexのキー
String blogId = "xxxx";

// Indexデータ（MongoDBのDocumentで作成する例）
Document document = new Document();
document.put("title", "first blog");
document.put("body", "xxxxx");

// 新規INDEX
IndexRequest upsertRequest = new IndexRequest("blogs");
upsertRequest.source(document, XContentType.JSON);
upsertRequest.id(blogId);

// 更新INDEX
UpdateRequest updateRequest = new UpdateRequest("blogs", blogId);
updateRequest.upsert(upsertRequest);
updateRequest.doc(document, XContentType.JSON);

// クライアント生成
RestHighLevelClient esClient = new RestHighLevelClient(RestClient.builder(new HttpHost("localhost", 9200, "http")));

// ElasticSearchに投入
esClient.update(updateRequest, RequestOptions.DEFAULT);

// クライアントを閉じる
esClient.close();
```

#その他
上記は新規、更新のサンプルです。
GET：https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-get.html
Exists:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-exists.html
Delete：https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high-document-delete.html
Search：https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/_search_apis.html

以上
ASP.NET CoreでShift_JISでCSV出力しようとしたら他ページのHTMLの中身が空になった件

# .NET Coreは標準ではShift_JISに対応していない
顧客要件でShift_JISでのCSVファイル出力をする必要があったので単純にStreamWriterに
`System.Text.Encoding.GetEncoding("shift_jis")`
を指定すればOKかと思ったらエラーを吐いた。

```
System.ArgumentException: 'shift_jis' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
Parameter name: name
   at System.Text.EncodingTable.GetCodePageFromName(String name)
   at System.Text.Encoding.GetEncoding(String name)
```

shift_jisがサポートされていない……だと……

ちょろっと調べたら.NET CoreではASCIIとUnicodeしか標準ではサポートしていないらしい
Windows10でも標準文字コードをShift_JISからUTF-8に置き換えてるらしいからその一環だろう

# 他の文字コード使いたいならCodePagesEncodingProviderを使う

nugetで`System.Text.Encoding.CodePages`を追加すればOK
<img width="825" alt="スクリーンショット 2019-08-31 11.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442003/11d5b6d7-b5f6-c7a2-ac5b-771366b27810.png">

そしてShift_JIS使うコードの前で下記を呼び出せばOK

```
// エンコードプロバイダを登録
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
```

……のはずだったのだが

# HTMLレスポンスのBody部が空で返ってくる現象が発生

`System.Text.Encoding.CodePages`を追加した以外コードをひとつも弄っていない状態でも何故か空のHTMLページがレスポンスとして返ってくる

# 解決方法

`Program.cs`の`Main`メソッドでエンコードプロバイダを登録すればOK

```
public static void Main(string[] args)
{
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    CreateWebHostBuilder(args).Build().Run();
}
```
ここで登録しておけばShift_JIS使う直前に再度登録する必要も無いのでASP.NET Coreで標準文字コード以外使う時は`Main`メソッド内でエンコードプロバイダ登録と覚えておけばよい
googleappscriptでスプレッドシートのオリジナル関数を作る

# この記事の目的

スプレッドシートでオリジナルの関数をGASで作る

# GASとスプレッドシートの紐付け

* googleスプレッドシート作成
* ツール>スクリプトエディタ

# 関数の作成

```javascript
function GETRESULT(input) {
  if (input >= 80){
    return 'PASS';
  }else{
    return 'FAIL';
  }
}
```

# シートで使用

=GETRESULT()で利用可能に
SQL　JOIN系まとめ

#JOINの種類一覧
・INNER JOIN（省略形：JOIN）
・LEFT OUTER JOIN（省略形：LEFT JOIN）
・RIGHT OUTER JOIN（省略形：RIGHT JOIN）
・CROSS JOIN（直積）

※CROSS JOINについて
　SELECT * FROM table1 CROSS JOIN table2
　と
　SELECT * FROM table1, table2
　は等価

※RIGHT OUTER JOINについて
　仕事で使ったことがないか。

#私が普段使うのは

・INNER JOIN（省略形：JOIN）
・LEFT OUTER JOIN（省略形：LEFT JOIN）
※直積は、JOIN書かない方式のみ

くらいかな
初心者でも出来るHTML,JavaScript入門6

## 1.事前知識
- [初心者でも出来るHTML入門1](https://qiita.com/ryome/items/9ec3819e5e9ab5321553)
- [初心者でも出来るHTML入門2](https://qiita.com/ryome/items/4e19c19d3166a01bc0fc)
- [初心者でも出来るHTML入門3](https://qiita.com/ryome/items/72408fb260d1576fcb25)
- [初心者でも出来るHTML,JavaScript入門4](https://qiita.com/ryome/items/152ebca06eda9fe05b39)
- [初心者でも出来るHTML,JavaScript入門5](https://qiita.com/ryome/items/c5e7716ff58bbced5173)

事前知識として、上記リンクの内容が必要です。

## 2.変数
```html:変数
<script type="text/javascript">
    //Object型
    var str1 = '文字列';

    //String型
    var str2 = new String('文字列');
</script>
```

- `変数` とは、`数値` や `文字列` などの値を保存する箱のようなもので、いつでも値を取り出すことや違う値を上書き保存することができる。
- `JavaScript` では、 `変数` を宣言するキーワードとして、 `const` 、`let` 、`var` の3つがある。
- `const` で宣言した `変数` には、後から値を `再代入`することはできない。
- `let` で宣言した `変数` には、何度でも値の代入が可能。
- `var` も `let` と同様に宣言した `変数` に何度でも値の代入が可能だが、 `var` では同じ名前の変数を `再定義` できてしまう問題がある。
- `変数` に直接文字列を代入すると `Object型` になる。


## 3.記述例

```html:js1_2.html
<!DOCTYPE html>
<html>
    <head>
        <!-- 付加情報 -->

        <!-- タイトル -->
        <title>JavaScriptの説明</title>

        <!-- 文字コードの指定 -->
        <meta charset="utf-8" />
    </head>

    <body>
        <!-- コンテンツ -->

        <!-- インラインスクリプト -->
        <script type="text/javascript">
            //Object型
            var str1 = '文字列';

            //String型
            var str2 = new String('文字列');
            
            //変数
            const a1 = 10;
            let a2 = 20;
            var a3 = 30;
            
            //ドキュメントの出力を開始
            document.open();
            
            //ドキュメントに変数を書き出す
            document.write(str1);
            document.write('<br/>');
            document.write(str2);
            document.write('<br/>');
            document.write(a1+a2+a3);
            
            //ドキュメントの出力を終了
            document.close();
        </script>
    </body>
</html>
```

中身の文をコピーして、文字コードは `UTF-8` を指定し、ファイル名を `js1_1.html` でデスクトップに保存するとブラウザではこうなります↓↓

- js1_2.html
![js1_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/406781b0-f28b-bba6-9bc9-6fc2b20ba653.png)


画像のようになれば成功です。

## 4.GitHub
GitHubにソースコードを公開しています。

https://github.com/ryomeblog/qiita/tree/master/%E5%88%9D%E5%BF%83%E8%80%85%E3%81%A7%E3%82%82%E5%87%BA%E6%9D%A5%E3%82%8BHTML%2CJavaScript%E5%85%A5%E9%96%806


## 5.関連
- [初心者でも出来るHTML,JavaScript入門7](https://qiita.com/ryome/items/6d58c666a4b296e8cc02)
Rails アプリケーションで現在ページ URL のクエリパラメータを遷移先 URL に引き回す

## はじめに

最近の開発で、Rails アプリケーションにおいて、あるページから特定のクエリパラメータを引き回して連携先の外部サイトのページに遷移したい、というケースがありました。

そのときに調べたことを備忘として残しておきます。

## やりたかったこと

あるページを開いたときに、Google アナリティクスのパラメータを次のページにも渡したいというケースを考えます。例えば、以下の URL (`PostsController#show`)でパラメータを指定し、

`https://hogehoge.com/posts/1?utm_source=xxxx&utm_medium=yyyy`

以下の URLに遷移したときに、

`https://fugafuga.com/?utm_source=xxxx&utm_medium=yyyy`


上記のように `utm_source` と `utm_medium` というパラメータのみ、外部サイトの URL に渡したいと思っていました。


## やったこと

### Controller で引き回すパラメータを絞る

上記の例踏まえ説明しますと、まずコントローラーの処理 `PostsController#show` で、引き渡す対象のパラメータを `params.permit` で絞り、余計なパラメータを渡さないようにします。

また後ほど処理しやすいように、`to_h` で Hash クラスのオブジェクトにしておきます。

```ruby:posts_controller.rb
  def show
    @params_to_transit = params.permit(
      :utm_source, :utm_medium
    ).to_h
  end
```

### Helper でパラメータ付き URL を生成する

次に、 `PostsController#show` の view に指定する URL に helper の処理を噛ませます。

```ruby:application_helper.rb
  def url_with_params(url, params = {})
    uri = URI.parse(url)
    uri.query = URI.encode_www_form(params.to_a)
    uri.to_s
  end
```

`URI.encode_www_form` を使うことで、以下の Hash クラスのパラメータを、

```ruby
{
  'utm_source' => 'xxxx',
  'utm_medium' => 'yyyy'
}
```

以下のような形式に変換してくれます。

```
?utm_source=xxxx&utm_medium=yyyy
````

### View でパラメータ付き URL でリンクを作成する

view には以下のような指定をしてリンクを準備しておきます。

```haml:posts/show.html.haml
= link_to '外部サイトへ', url_with_params('https://fugafuga.com', @params_to_transit)
```

これによって、`PostsController#show` で渡されたパラメータを外部サイトの URL に引き渡すことができました。

## 終わりに

一つ一つパラメータを指定する方法でもできたのですが、複数パラメータがあるときは処理が煩雑になりそうだったので、`URI` クラスのメソッドを使って一括で処理できるようになりました。

一旦こちらの方法で実現できましたが、他にいいやり方あれば教えていただけるとありがたいです。

## 参考

* [module URI (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/latest/class/URI.html)
cp、mv コマンドのよく使うオプションまとめ

CentOS 7 で確認。cp と mv のバージョンは GNU coreutils 8.22。

### ファイル/ディレクトリを属性を保ってコピー/移動
```
cp -a
mv
```
`cp -r` は属性を保存せずディレクトリをコピー。

ディレクトリを既存のディレクトリにコピー/移動しようとすると、コピー/移動元ディレクトリがコピー/移動先ディレクトリの中にコピー/移動される。

### ディレクトリを既存のディレクトリにコピー/移動
```
-T
```
`cp` では `-a` か `-r` をつける。

移動先ディレクトリの中にファイルがある場合、`cp` ではファイルを追加または上書き、`mv` ではエラー。

### コピー/移動したファイルを表示
```
-v
```

### SELinux のコンテキストをコピー/移動先に合わせる
```
-Z
```

### コピー/移動先に同じ名前のファイルがあったら処理を尋ねる
```
-i
```

### コピー/移動先に同じ名前のファイルがあったらバックアップを作成
```
-b
```
デフォルトではファイルの末尾に `~` がつく。これを変更するには `-S <接尾辞>` をつける。

### コピー/移動先に同じ名前の新しいファイルがあったらコピー/移動しない
```
-u
```

### コピー/移動先に同じ名前のファイルがあったらコピー/移動しない
```
-n
```
Parallels Desktop 15 for Macで動かすlinuxで、変わったWindow Managerを使っている場合Parallels Toolsのコピペや画面解像度自動変更が効かない

## 環境とか経緯
* Parallels Desktop 15 for Macを使っている
* Linux (Ubuntu 18とか）をゲストOSとして動かしている
* Ubuntu標準のWindow Managerは使わずに、自分の好みの物を使用している
* Parallels Toolsはもうインストールした（注意：有料のParallels Toolboxとは別物です。わざわざ買わなくてもコピペや画面解像度自動変更は使えます）
* Mac<->linuxでコピペする設定はすでに済ませた

## 問題
Mac<->linuxでコピペできない。画面ウインドウのサイズを変更しても、800x600の様な古風なスクリーンサイズのままで自動変更されない。

ただし、___Ubuntu標準のWindow Managerでログインした時は、コピペも自動解像度変更もきちんと機能する。___

注意：一番最後の行が重要。

## 解決策

自分のホームディレクトリに `~/.xsessionrc` ファイルを無かったら作り、以下の内容を追加。

```bash:~/.xsessionrc
prlcc &
```

たったこれだけ。

最初は`.xinitrc`に書き込んで思った通りにうごかなかったけど、Ubuntu 18では `~/.xsessionrc` が正解みたいです。

## チラ裏

長年MacOSXにhomebrewで環境ぶっこんでウエブ開発していました。でも、これだとMacOSのバージョンが上がったり、システムの調子が悪くなったりする度に環境を一から作り直さないといけないので面倒。最近になってセキュリティが強化されはじめ、homebrewその他関連のセットアップが少しづつ面倒になってきています。

そこで、Docker使ってウエブ開発をしようと思っていた事もありました。つい今月はじめ頃の事です。もっと簡単に開発環境をまとめて管理したいので、残念ながらDockerは諦めました。

次にVirtualBoxでlinux環境を動かして開発しました。この時からMacOS側からウエブブラウザやVS CodeのRemote SSHで仮想マシン上で動いているlinuxのサーバに繋いで開発するみたいな事をやりはじめました。なかなか良い感じです。ところが、どうもクラッシュしまくって不安定。細かい事を気にせず黙々と再起動すれば良いだけなのですが。

というわけでもっとも早いと言われるVMWare Fusionを試してみました。選ばなかった理由は、些細な事ですけど、マウスカーソルを拡大表示しているばあい、カーソルの位置がずれてしまうというバグみたいなのがあります。これも神経質にならなければ解決・・・他にも微妙に使いにくい点があったような気がする。でも金払って使うソフトなんですよね。これ。

最後にたどり着いたのがParallels Desktop。最近バージョンが１５に上がったばかり。Parallelsは買い時が難しいと言われているソフトです。今回のバージョンで大きく違うのが、なんとかなり前のバージョンからのアップグレードができる様になったこと。なんと半額になるんです。いつの頃かさえ忘れたバージョン３のライセンスを持っていて、これどうしようかと眺めつつもアップグレードに使えず諦めていた矢先のことです。Parallels Desktopは、かなりキビキビ動きます。安定しています。仕事の効率も上がります。
Rubyのnilガードについて調べてみた

#はじめに
Rubyのnilガードについて調べてみたので、
備忘録的に残しておこうと思います。
間違いなどありましたらご指摘いただけると幸いです。。

#概要
そもそもnilガードとは何かというと、
名前の通りnilが入らないようにするものです。
具体的には下記のような挙動になります。

```pry
pry(main)> a = nil
=> nil
pry(main)> a ||= "OK"
=> "OK"

pry(main)> b = 1
=> 1
pry(main)> b ||= "OK"
=> 1
```

左辺がnilの場合は値が代入され、既に値が入っている場合は
値の代入は行われません。

#試してみる
ここで、ふと思いました。
nil以外にも値が代入されることはあるのだろうか。。

ということで早速試してみました。

```pry
pry(main)> a = ""
=> ""
pry(main)> a ||= "OK"
=> ""

pry(main)> b = 0
=> 0
pry(main)> b ||= "OK"
=> 0

pry(main)> c = []
=> []
pry(main)> c ||= "OK"
=> []

pry(main)> d = {}
=> {}
pry(main)> d ||= "OK"
=> {}

pry(main)> e = false
=> false
pry(main)> e ||= "OK"
=> "OK"
```

ふむふむ。
どうやらnil以外にfalseだった場合も値の代入が行われているようです。

これらを踏まえ、「条件式においてfalseになる場合のみ値の代入が行われる」という仮説を立てました。

Rubyではnilとfalse以外は全てtrueとみなされます。
値がtrueかfalseなのかを知りたい場合は、否定演算子「!」を確認したい値の前に2つ付ければ確認することができます。
実際に先ほど実行した値を確認してみましょう。

```pry
pry(main)> !!""
=> true
pry(main)> !!0
=> true
pry(main)> !![]
=> true
pry(main)> !!{}
=> true
pry(main)> !!false
=> false
pry(main)> !!nil
=> false
```
仮説通り、nilガードで値が代入されなかったものはすべてtrueになってますね。

#結論
nilガードを使用すると、左辺がfalseになる場合のみ値の代入が行われ、
左辺がtrueになる場合は値の代入が行われない。
分子模型の3Dプリントモデル

# 概要
公開されているデータベースから分子の3Dモデルをダウンロードして、家庭用の3Dプリンタで出力可能な形式のファイルを生成する方法を簡単に紹介します。

## モデルの入手

低分子やタンパク質の情報を集めたデータベースが公開されており、構造・物性・形状などの情報が登録されています。
下の例に紹介するように、ウェブでデータベースにアクセスして簡単に3Dモデルをダウンロードすることができます。

- 低分子

[PubChem](https://pubchem.ncbi.nlm.nih.gov)にアクセスし、分子名で検索。
個別ページにアクセスして、3D ConformerのところからSDFファイルをダウンロード

- タンパク質

[RCSB PDB](http://www.rcsb.org/pdb/results/static.do?p=results/session_timeout.html) にアクセスしてタンパク質を検索。
download filesからPDB formatを選択してpdbファイルをダウンロード。


上で挙げたのは一例で、データベースはほかにもいくつも存在します。

## ビューワ
PyMOL, Chimeraなどをはじめとして研究用にいくつか分子モデル処理用のツールがありますが、今回の目的には[CueMol](http://www.cuemol.org/en/)が直接.stlファイルを出力でき、インターフェースもシンプルで便利だと思います。

## モデル出力

ダウンロードしたファイルをCueMolで開くと分子モデルが表示されます。
![コメント 2019-08-31 094628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89956/df11918e-5f41-37d4-3efd-11043c764330.png)


Rendering -> Export Sceneで表示しているモデルの.stlファイルを保存できます。
下は保存した.stlモデルをCuraで開いてみた様子です。
![コメント 2019-08-31 094533.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89956/3c0fd5d6-e715-aa9c-eb8c-1be77e298d81.png)

## 引用・ライセンス
PubChemはパブリックドメイン、PDBは基本的に[CC BY 4.0](http://creativecommons.org/licenses/by/4.0/deed.ja)ライセンスなので常識的な使い方をしている限り問題はないはずですが、出典を乗せられるときは引用元がわかるようにしておくのがよいマナーかと思います。

### 参考にしたページ

- 構造生物学と3Dプリンタ http://www.protein.osaka-u.ac.jp/rcsfp/supracryst/suzuki/jpxtal/Katsutani/3dprinter_cube.php
- CueMol http://www.cuemol.org/ja/

### 使用したモデル
- 2'-Deoxyadenosine https://pubchem.ncbi.nlm.nih.gov/compound/13730
rails で新しくアプリを作る　rails newからgitまでの流れ

新しくアプリを作ってみる時のメモ

##rails newでアプリを作る
１、アプリを置きたいレポジトリに移動する
２、ターミナルで`rails new アプリ名`

##githubにあげる
１、ターミナルで`git init`
　→cloud9でgitリポジトリを作成
２、ターミナルで`git add .`
３、ターミナルで`git commit -m "first commit"`
 →アプリをcloud9上のgitリポジトリにコミットする
４、ターミナルで`git remote add origin https://github.com/githubのユーザー名/アプリ名`
５、ターミナルで`git remote -v`
６、ターミナルで`git push origin master`
 →githubにpush

次はデプロイ！頑張れ自分:clap_tone1:
webarenaでubuntu その38

#概要

webarenaでubuntu18.04やってみた。
perl5.26やってみた。
メール送信やってみた。

#サンプルコード

```
#!/usr/bin/perl
$sendmail = '/usr/sbin/sendmail';
if (!open(smtp, "| $sendmail -t"))
{
	print "error!";
	exit;
}
$mailtext = << "EOM";
From: honne<hone@hoge.com>
To: <pene@hoge.jp>
Subject: test14
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset="ISO-2022-JP"

testdesu

EOM
print smtp $mailtext;
close smtp;
print "ok";
exit;

```

以上。
docker-compose up -dの実行で、port is already allocatedとのエラーが出た時の対処法

dockerを起動させようと`$ docker-compose up -d`コマンドを入力すると、次のエラーが出ました。

```
Bind for 0.0.0.0:3306 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
```
これは、すでに`3306`のポートは既に割り当てられているので、利用できません、無理ですと言う意味。
利用状況を次のコマンドで確認すると、次のように確かに使用されていることがわかる。

```
$ sudo lsof -i:3306
Password:
COMMAND    PID   USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
com.docke 64339         14u  IPv6    0t0  TCP *:mysql (LISTEN)
```

##対処法１
不要なポートであれば削除して、新たに設定する。

```
$ sudo kill 64339           #PIDの数値を記入
Password:
$ docker-compose up -d      #再度dockerを起動
```

##対処法２
ポート番号を変更して起動する。

```docker-compose.yml
version: '3.2'

services:

  ＜中略＞

    ports:
      - 3300:3306     #自分のPCのポート:仮想環境の中のポート
   
　＜中略＞

volumes:
  
　＜中略＞
```

##接続確認
最後に、MySQLの接続の確認が取れればOK。`exit;`で抜ける。

```
$ mysql -u root -p -h 127.0.0.1

　＜中略＞

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql >
```
Progate上級編


未来電子テクノロジー（https://www.miraidenshi-tech.jp/intern-content/program/ ）
で、インターンをしているたくみです。
今回は前回の中級編からステップアップして、取り組んできたProgate HTML/CSSの上級編の一部をまとめてみました。
###メディアクエリの条件設定

```css 
h1{
color:black;
}
@media(max-width:1000px){
h1{
color:blue;
}
}
```
###スマートフォン向けのメディアクエリの書き方

```CSS
＠media(max-width:500px;){
.lesson{
width:100%;
}
}

```
###footerの位置設定

```CSS
＠media(max-width:500px;){
footer{
text-align: center;
}
}


```
###最後に
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし誤りがあれば、修正するので、どんどん指摘してください。
ShellScript Linuxマシン の 空き容量 を 取得する

# 目的

- Linuxマシンの空き容量を取得する方法を知る

# 書き方の例

- dfコマンドの結果を使用して空き容量を取得する。
- 下記にShellScriptの処理を記載する。
※もっと合理的な書き方があると思います。知ってる方はよければ教えて欲しいです。

``` shell
$ df -BG . | awk 'NR==2{print $4}'
```
カメラ無しのラズパイとmomoでテスト映像をWebRTCで配信する

momoを使ったアプリのテストをするときに、常に動きのある映像が流れている状態にしたい。
映像が止まったらハングアップしているとすぐにわかるので。

そのために実際のカメラの映像でなくて決まったテストパターンを繰り返し配信できると嬉しい。
momoのソースコードを修正せずにそれが実現できた。

## v4l2 loopback

[この記事](https://qiita.com/tetsu_koba/items/b887c1a0be9f26b795f2)でテスト音声を流したときにはALSAのloopbackデバイスを使用した。
ALSAのloopbackがあるなら、v4l2にも同様なものがないか探したらドンピシャのものが見つかった。

https://github.com/umlaeute/v4l2loopback

具体的な使い方
https://github.com/umlaeute/v4l2loopback/wiki

### インストール

```
sudo apt install v4l2loopback-dkms
```
これで現在のカーネルのバージョンに合わせたv4l2loopback.ko をビルドしてインストールしてくれる。


### テスト
webcamや専用カメラモジュールをつけない状態でラズパイを起動する。

```
sudo modprobe v4l2loopback
```
これで /dev/video0 ができる。

## テストパターンを流す。

```
ffmpeg -re -f lavfi -i testsrc=size=640x480:rate=10 -pix_fmt yuv420p -f v4l2 /dev/video0
```

これでmomoを実行するとテストパターンを/dev/video0 から読み取って配信することができる。
しかしこれは負荷が高くてラズパイ2ではVGAの解像度でフレームレートを10fpsまで下げる必要があった。

## あらかじめデコードした動画ファイルを作っておいてそれを流す

10秒間のテストデータを作る。

```
ffmpeg -f lavfi -i testsrc=duration=10:size=640x480:rate=30 -pix_fmt yuv420p -f rawvideo testsrc.yuv420p
```

これを /dev/video0 に流し込む。

```
ffmpeg -stream_loop -1 -re -f rawvideo -pix_fmt yuv420p -s 640x480 -r 30 -i testsrc.yuv420p -c copy -f v4l2 /dev/video0
```

`-stream_loop -1`　をつけると無限に繰り返す。
これでmomoを起動するとラズパイ2でもVGAの解像度で30fpsで配信することができた。


## momoでのビデオデバイスの選択

タイミングよくリリースされた momo 19.08.1 で `--video-device` オプションが追加された。
これでビデオデバイスが複数あるときでも明示的にビデオデバイスを指定できるようになった。
なのでv4l2loopback を使用するときにわざわざカメラを外さなくてもよくなった。

## 関連

[ラズパイ+momoでWebRTCで送信するときにマイクの代わりに音声ファイルを使用する](https://qiita.com/tetsu_koba/items/b887c1a0be9f26b795f2)