OmniAICreator/Qiita-1.07M huggingface dataset:
OpenFOAMの解析結果における最小値・最大値の抽出方法

# はじめに

OpenFOAMの解析結果処理で、計算領域中の各変数の最大値と最初値を出力できなかと、調べてみました。


# やり方
`controlDict`の`functions`のところに以下の記述を追記すれば良いです。

```c++:controlDict
functions
{
    minMax
    {
        type        fieldMinMax;
        functionObjectLibs ("libfieldFunctionObjects.so");
        fields
        (
            T.steam
            T.water
            p
        );
        location        no;
        writeControl    timeStep;
        writeInterval   1;
    }
}
```

各項目の意味は以下の通りになります。

| Property | Description | Required | Default value |
|---|---|---|---|
| type | type name: fieldMinMax | yes |	 |
|log |	write min/max data to standard output |	no |	no |
| location |	write location of the min/max value |	no |	yes |
| mode | calculation mode: magnitude or component | no | magnitude |

最小設定は、`type`とほしい変数名のみ、となります。ロケーションやログ出力をする場合は、各項目のトグルを`yes`にすれば良いです。

結果は`postProcessing/minMax/fieldMinMax.dat`に保存されます。


詳細は[本家のページ](https://cpp.openfoam.org/v8/classFoam_1_1functionObjects_1_1fieldMinMax.html#details)も参考にすると良いと思います。

# さいごに
設定自体は簡単ですので、まとめることもないかとは思いましたが、何かの参考になればと思い作成してみました。
2回の妊娠＆育休から会社復帰したエンジニア妻の経験談

## 初めに
具体的な年数などは伏せますが、
2人の男の子の育休を経て現場復帰した
エンジニアである妻の体験談を残します。
※育休は子供1人に付き 1年半～2年 で取得
※開発経験は10年以上

特に、私の様に共働きの妻を持つ方、
育休明けの方の現場上長や、同僚の方に知って頂ければと思います。

## ストレス要素
#### えー知らないの？的な発言
後輩の上から目線な発言（準パワハラ）。
"そんなこと分からないの？"
"なんでこの仕様を忘れているの？"
といった言葉。

この辺りは非常にストレスになる。

#### 復帰したら帰る場所が無かった
元の現場（常駐先）に戻れるチャンスはあったのだが、
時短勤務だと会社間の合意が取れず、結局戻れなかった。

#### 雑用が多かった
復帰後、しばらくは雑用係（テストだけ）だった。
これもストレスになったが、耐えるしかない。
その後、ちゃんと話を聞いてもらえて、
まともな開発の現場に入ることができた。


## 助かった事
#### 仕事のメンバーが助けてくれた
特に上長。
1人目の時のリーダーと2人目の時のリーダーが同じ人だった。
リーダーにも子供がいたので理解があった。

仮に全く話を聞かない上司だった場合、
もしかしたらやめていたかもしれない。

+ 妻は私よりストレス耐性が高い。  
それでも前述のような嫌味はキツかったそうです

また、現場で愚痴を聞いてくれる同僚がいたのも救い。

#### 会社の体制に助けられた
会社が、コロナ禍でのリモートワークを率先して導入してくれた。
よく聞く "出社何割 must" という指標も無く、自由選択だった。
このため、今は安心して勤務ができている。

また、家にいるので、家事や通園・育児のストレスも軽減される。

+ 早帰りして迎え＆料理作る、は超きつい（≒残業）

## 開発の勘を取り戻すまで
一度身につけたプログラミング言語は忘れていなかったが、
勘を取り戻すのにしばらくかかった。

復帰前と同じ現場でも、慣れるのに1か月くらいはかかる。

現場が違う（扱う言語もシステムも完全に違う）場合、
完全に慣れるのに半年くらいかかった。

## 最後に：横で見ていた感想
妻は本当にすごい人です。
私なんて、仕事＞家事＆育児の連続作業でヘタっていますから；

しかし、表面上大丈夫そうに見えても、
疲れているな、という姿を日々見かけます。
同じエンジニアとして、分からない技術はサポートしたり、
夫として、家事と育児のサポートをする。

自分にできることをして、妻を支えていきたいと思います。
ウマ娘の誕生日をカレンダー表示できるようにした

ウマ娘のゲーム、面白いですね。

ホームに設定しているウマ娘の誕生日当日にログインすると誕生日ボイスが聴けるというので、聞き逃さないようにカレンダー化しました。

以下はGoogleCalendarで購読した例。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104653/10a9c7bc-ea05-8c17-8c35-b39103605b16.png)

## ソースコード

以下に公開しています。
https://github.com/ushibutatory/umamusume-birthdays

## 処理概要

Dockerfile内でNode.jsアプリケーションを実行し、`text/calendar`形式でデータを配信しています。

実行環境はHerokuを選択しました。いつもお世話になっております。

iCalendar形式データは人間が直接メンテナンスするのが難しいので、YAMLで元データを作成し、iCalendar形式に変換する処理を挟んでいます。

![overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104653/a57a325f-289d-8455-4691-c5bb94d8f97f.png)

### データ構造

人間がメンテナンスするためのデータ構造は以下のように定義しました。

（2021/04/29追記: 今はちょっと構造変わってます。最新は上記GitHubにあります）

```yaml:birthdays.yaml
birthdays:
  - date: "03/05"
    names: ["ライスシャワー"]
  - date: "03/06"
    names: ["ゴールドシップ"]
  - date: "03/13"
    names: ["テイエムオペラオー", "シンボリルドルフ"]
...
```

変換すると以下のようになります。

```icalendar:birthdays.ics
BEGIN:VCALENDAR
PRODID:...
VERSION:2.0
METHOD:PUBLISH
BEGIN:VTIMEZONE
TZID:Asia/Tokyo
BEGIN:STANDARD
DTSTART:19390101T000000
TZOFFSETFROM:+0900
TZOFFSETTO:+0900
TZNAME:JST
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CLASS:PUBLIC
UID:20210305-ライスシャワー
DTSTAMP:20210318T155519+00:00
SUMMARY:ライスシャワーの誕生日
DESCRIPTION:ライスシャワーの誕生日です。
DTSTART;VALUE=DATE:20210305
DTEND;VALUE=DATE:20210305
END:VEVENT
BEGIN:VEVENT
CLASS:PUBLIC
UID:20210306-ゴールドシップ
DTSTAMP:20210318T155519+00:00
SUMMARY:ゴールドシップの誕生日
DESCRIPTION:ゴールドシップの誕生日です。
DTSTART;VALUE=DATE:20210306
DTEND;VALUE=DATE:20210306
END:VEVENT
BEGIN:VEVENT
CLASS:PUBLIC
UID:20210313-テイエムオペラオー
DTSTAMP:20210318T155519+00:00
SUMMARY:テイエムオペラオーの誕生日
DESCRIPTION:テイエムオペラオーの誕生日です。
DTSTART;VALUE=DATE:20210313
DTEND;VALUE=DATE:20210313
END:VEVENT
BEGIN:VEVENT
...
```

上記ファイルを、Node.js * Express で簡単なAPIを作成して配信しています。

不備やおかしなところ、権利関係、その他問題などあればご指摘ください。

## 余談

iCalendar形式データをgistで管理してそのURLを購読すればいいのではと思いましたが、gistはContent-Typeが `text/plain` で固定されているため、カレンダー側の仕様によっては正常に購読できない可能性があり、今回のようにHeroku上でDockerコンテナを動かす方式にしました。
非同期通信(Ajax)ができない場合の対処法

#はじめに
rails + jQueryでフォロー機能の非同期をする際、
フォローボタンをクリックしても画面が切り替わらず、試行錯誤したため、その対処法の一部を紹介します。

##完成図

<img width="200" alt="スクリーンショット 2021-02-27 11.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/cafe8d53-5c21-a561-343e-5414f60d1ded.png">
↑↓フォローボタンを押すと非同期で反映されます
<img width="200" alt="スクリーンショット 2021-02-27 11.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/40d223ed-06d0-b4ab-c6ab-4ed5fcbc7f06.png">




#到達点
以下の1点を達成する
・対処法を学ぶ

##流れ
① rails s でログを確認する
② デベロッパーツールを活用する


#① rails s でログを確認する
rails sすると、以下のようなログが表示されます。
<img width="400" alt="スクリーンショット 2021-02-27 11.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8b219abf-1816-5f2e-208d-d7ea5d795580.png">
最後の行が`500 Internal Server Error`などの表示であれば、エラーの原因が表示されますので、ログをしっかり確認しましょう。

今回は問題ありませんでした。

#② デベロッパーツールを活用する
デベロッパーツールのコンソールで原因がわかる場合があります。
###デベロッパーツールのコンソールの開き方
1) Chromeを立ち上げます
2) ブラウザの右上にある三つの点アイコンをクリックします
3) 「その他のツール」＞「デベロッパーツール」を選択します
4) コンソールタブをクリックします
<img width="400" alt="スクリーンショット 2021-02-27 11.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/43896adb-2278-63ed-610d-acbbe6e60130.png">

### コンソールで確認する
<img width="400" alt="スクリーンショット 2021-02-27 11.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/fbc2bd46-73f7-c1cd-4448-9944b98382b7.png">

何やら`Uncaught ReferenceError: $ is not defined`というエラー表示があります。
ググってみると、application.html.erbに以下の記述がなくjQueryが使えなかったことが原因のようでした。

```
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
```

エラー対処は、ログやコンソールからエラー文が出ていることがあるので、確認すると、対処の糸口が見つかるかもしれません。
Mac PC へのPython3 導入手順

# 1. はじめに

Mac PC には あらかじめPython2.7が導入されています。
今回は 新しいバージョンの**Python3** をMac PCに導入します。

※ Windows PCへの Python3 導入手順は、以下リンク先をご参照ください。

・Qiita：Windows PC へのPython3 導入手順
https://qiita.com/Haruka-Ogawa/items/b37d0a2b48d14e29e802

# 2. Python3 導入

## 2-1. pyenv 導入

### ① インストール

今回は **Python3** の導入に、**pyenv** コマンドを使用します。
**brew**コマンドで、**pyenv** を導入します。

コマンドは以下の通りです。

```
brew install pyenv
```

### ② 確認

**pyenv** の導入が完了したら、
バージョンを表示して、無事導入されていることを確認します。

コマンドは以下の通りです。

```
pyenv -v
```

実行例は以下の通りです。

```
$ pyenv -v
pyenv 1.2.23
```

## 2-2. Python3 導入

**pyenv** コマンドを使用して、**Python3** を導入します。

### ① インストール可能 バージョン 表示

**pyenv**コマンドで インストール可能な Pythonのバージョンを確認します。

コマンドは以下の通りです。

```
pyenv install --list
```

今回は、Python **3.9.1** を導入することとします。

### ② インストール

**pyenv** コマンドで Python **3.9.1** をインストールします。

コマンドは以下の通りです。

```
pyenv install 3.9.1
```

### ③ 確認

Python **3.9.1** の導入が完了したら、
使用可能なバージョンを表示して、無事導入されていることを確認します。

コマンドは以下の通りです。

```
pyenv versions
```

実行例は以下の通りです。

```
$ pyenv versions
* system (set by /Users/ogawa/.python-version)
  3.9.1
```

# 3. Python3 使用設定

Python3.9.1 を導入しても、使用されているバージョンは Python2.7のままです。

```
$ python -V
Python 2.7.16
```

Python 使用バージョンの変更方法には、
グローバル（環境全体）で バージョンを変更する方法と、
ローカル（特定のディレクトリ）で バージョン変更する方法 があります。

それぞれでのバージョン変更方法について 記載します。

## 3-1. グローバルの使用バージョン変更

グローバル（環境全体）における Pythonの使用バージョンを変更します。

### ① 現行 バージョン確認

変更前の Pythonの使用バージョンを確認します。

コマンドは以下の通りです。

```
python -V
```

実行例は以下の通りです。

```
$ python -V
Python 2.7.16
```

### ② バージョン 変更

**pyenvコマンド**で グローバルでの 使用バージョンを *3.9.1* に 変更します。

コマンドは以下の通りです。

```
pyenv global 3.9.1
```

### ③ 変更後 バージョン確認

Pythonの使用バージョンを 変更した後、
無事 バージョンが *3.9.1* に変更されていることを確認します。

実行例は以下の通りです。

```
$ python -V
Python 3.9.1
```

### ・補足

グローバルのバージョン変更 が反映されない場合、
**pyenv** にパスが通っていない可能性があります。

$HOME に配置されている **.bash_profile** に以下を記述します。

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

その後、**.bash_profile**を実行します。
コマンドは以下の通りです。

```
source ~/.bash_profile
```


## 3-2. ローカルの使用バージョン変更

ローカル（特定のディレクトリ）における Pythonの使用バージョンを変更します。

### ① ディレクトリ作成・移動

使用バージョンを変更する 特定ディレクトリ*/Users/ogawa/python* を準備・移動します。

実行例は以下の通りです。

```
$ mkdir python
$ cd python/

$ pwd
/Users/ogawa/python
```

### ② 現行 バージョン確認

変更前の Pythonの使用バージョンを確認します。

コマンドは以下の通りです。

```
python -V
```

実行例は以下の通りです。

```
$ python -V
Python 2.7.16
```

### ③ バージョン 変更

**pyenvコマンド**で ローカルでの 使用バージョンを *3.9.1* に 変更します。

コマンドは以下の通りです。

```
pyenv local 3.9.1
```


### ④ 変更後 バージョン確認

Pythonの使用バージョンを 変更した後、
無事 バージョンが *3.9.1* に変更されていることを確認します。

実行例は以下の通りです。

```
$ python -V
Python 3.9.1
```

### ・補足

ローカルのバージョン変更を行うと、
カレント・ディレクトリーに **.python-version** ファイルが作成され、
変更時に指定した バージョンが記載されます。

```
$ cat .python-version 
3.9.1
```
Pythonの使用バージョンを決める際に
カレント・ディレクトリーに**.python-version** ファイル が存在すると、
そのファイル内で 記載された バージョンが指定されます。

# 4. おわりに

今回は、Mac PC へのPython3 導入と 使用バージョンの変更を行いました。
Python2 はサポートが終了しているので、Pythonを始める際には Python3 を使用する方が良いです。

# 参考情報

・GitHub：pyenv/pyenv
https://github.com/pyenv/pyenv
gqlgenでresolver・model・schemaファイルを分割しコードの見通しを良くする

gqlgenで開発していると、`gqlgen generate`で生成されるresolversとmodelsが長くなってしまい、分割したくなることがあると思いますので、その方法を書きます。

■方針
今回は、GraphQL形式でクライアントがDBのデータをリクエストすることを可能にするGraphQLサーバをGoで構築することが目的だったことから、schema、resolvers、modelsをテーブル単位で分割することにしました。


## model分割
ここはドキュメント読めば分かると思うのですが一応書きます。
↓分割する際には`models_gen.go`にある構造体をテーブル毎にファイル分割して、あとは↓のように`gqlgen.yml`に書いておけば`go generate ./...`で新しく生成されなくなります。

```yml

models:
  Users:
    model: git-xxx/repository-name/graph/model.Users
```

## resolvers・schemaファイル分割
一番分割したかったのがresolversファイル。ドキュメントを読んでも分割する方法が書いてなかったのですが、issueを読んだらやり方が書いてあったので試してみたらできました。自動生成されるやつは中身ブラックボックスになりがちで、良く分からないけど言われた通りにやってみたらできたみたいな腑に落ちなさが残る。
↓resolves.goが長くなって困っている人がissueを上げていました。

https://github.com/99designs/gqlgen/issues/1427

### 手順
1. schemaを定義する*.graphqlsをテーブル毎に分割する
2. type, input, Query, Mutationなど全てテーブル単位で分割したファイルに移動する
3. Query, Mutationにextendをつける↓

```graphql:graph/schema/user.graphql

extend type Query {
	UserByID(id: ID!): User
}

extend type Mutation {
    CreateUser(input: CreateUser!): User!
}
```

gqlgen.ymlで関係する部分はこのようになっています。

```yml:gqlgen.yml
# Where should the resolver implementations go?
resolver:
  layout: follow-schema
  dir: graph/resolver
  package: resolver
  filename_template: "{name}.resolvers.go"
```

これで`go generate ./...`してあげるとテーブル毎のresolverが生成されるはずです。

あとは元々存在していたresolvers.goは削除してあげれば完了です。ドキュメントにextendなんて書いてあったかな・・・？


分からないのは、↓達がある特定のファイルに決まって生成されるのだけど、それがどのように決まるのかが謎。一番上にあるから？
気持ち的にはテーブルに対応していない別のファイルに移したいのだが、`gqlgen generate`する度に同じファイルに生成されるため、良く分からないけど気持ち悪さがあるだけで特に支障はないので一旦放置。

```go:table1.go
...//table1関連の実装

// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} }

// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }

type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
```

## 追記
mutationResolver, queryResolverが自動的にgqlgenによってその時のschema定義によって決まったファイルに生成されてしまい、自分で好きなところに置いた後に自動生成されるのを防ぐ方法が分かっていなかったがissueを読んでいたら方法を発見したので追記。
やり方は簡単で、yamlファイルのresolverセクションを削除すればOK。自動生成されなくなるというデメリットはあるけれど、自分でやるのも簡単なのでコードの見通しが良くなるという利点の方が大きいので消してしまって問題ないと思う。

↓はissueで丁寧に回答に答えてくれていた聖人のコメント。

```yaml
# Where should the resolver implementations go?
resolver:
  layout: follow-schema
  dir: graph/resolver
  package: resolver
```
>
@bofia thank you, unfortunately there is zero documentation on the yaml file, and I've been using gqlgen for much longer than most of these features existed.
You will want to remove the resolver section of the yaml file. This autogenerates the resolver in an opinionated way which, as you've noticed, doesn't scale well. Great for a new small project, but not good for what you are trying to do.
You can then create the resolvers yourself (which is really simple and easy), as well as customize them and avoid the auto-generate making a mess of your code


https://github.com/99designs/gqlgen/issues/1253

##所感
これで他のソースコード部分と同様に、きれいにテーブル単位でファイルを分割できたので良かった。
思ったのはドキュメントの情報量が少なくて、ちゃんとissueの方も読まないといけないんだなということ。それがOSSというものなんでしょうか。


おしまい
PUN2の3 *** Tips ***


# 名前の混同を避ける

```
    private void Start()
    {
        var nameLabel = GetComponent<TextMesh>();
        if (nameLabel == null) return;
        nameLabel.text = "HOGE";
        //if (photonView == null) return;
        // プレイヤー名とプレイヤーIDを表示する
        nameLabel.text = $"{photonView.Owner.NickName}({photonView.OwnerActorNr})";
    }
```

# PhotonViewの取得

```
        PhotonView photonView = PunExtensions.GetPhotonView(obj);
        photonView.Owner.NickName = "tiger";
```

# VPAD
```
public class VPAD : MonoBehaviour
{
    public FixedJoystick joystick;
    public ButtonState buttonA;
    public ButtonState buttonB;
    GameObject m_self;
    void Update()
    {
        Vector3 t_pos = Vector3.zero;
        var sc = this.GetComponent<ExitGames.Demos.DemoPunVoice.CharacterInstantiation>();
        if (sc) m_self = sc.m_self;

        if (m_self == null) return;
        float val = 0.02f;
        if (joystick.Horizontal > 0.5f)
        {
            t_pos.x = val;
        }
        if (joystick.Horizontal < -0.5f)
        {
            t_pos.x = -val;
        }
        if (joystick.Vertical > 0.5f)
        {
            t_pos.z = val;
        }
        if (joystick.Vertical < -0.5f)
        {
            t_pos.z = -val;
        }

        m_self.transform.position += t_pos;
    }
}
```

# ハウリング

PUN生成するOBJにSpeakerつけるとハウリングノイズがなくなる（ような気がする）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/b6bd92ef-7c0c-1c3d-27f6-0d682383d55f.png)

# Recorderマイクタイプ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/e1ac361b-e08f-ff7b-975a-45e2d2967480.png)

Recorder.MicrophoneType　Unity or Photon デフォルトは[Unity]　
Phothonの場合は次のコードでリストアップできる。

‘‘‘
var enumerator = Recorder.PhotonMicrophoneEnumerator;
if (enumerator.IsSupported)
{
    for (int i = 0; i < enumerator.Count; i++)
    {
        Debug.LogFormat("PhotonMicrophone Index={0} ID={1} Name={2}", i, enumerator.IDAtIndex(i),
            enumerator.NameAtIndex(i));
    }
}
‘‘‘

# Recorder.VoiceDetectionThreshold

VoiceDetectionThresholdのデフォルト値は0,01です。 これは、ボイス検出キャリブレーションとノイズレベル測定を使った実験の結果として、一般的な環境に推奨される値です。

# AudioSource

3D Sound Settings
MinDistance 
MaxDistance

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/943f846e-ee6d-c719-3411-0e1fe4d83002.png)

# インタレストグループ Recorder.InterestGroup
TortoiseGitでOpenSSHパスフレーズを要求されるようになった

ある日、TortoiseGitでPullしようとしたら、下記のようなウィンドウが表示された。
"Enter your OpenSSH passphrase"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/5288f640-38ff-deba-c0e0-799a06af4b25.png)

当然ながら、パスフレーズなどは設定した覚えはない。
色々試行錯誤した結果、どうやらSSHの認証がOpenSSHに倒れてしまっていることが原因のようだった。

対策としては、TortoiseGitのGlobal settingを開いて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/b4108e16-2f26-c5e7-8aa1-1bcfee1b1710.png)

下記の行を消してファイルを上書き保存する。（いつの間に足されたのかは不明）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267148/2bd65a92-0cea-3005-59f2-9841d62a3047.png)

こうすることで、PuttyKey側に設定が変更される。
Windows10 かな入力 「を」が入力できない問題

日頃からかな入力を使っているが、
先日から急に「を」入力できなくなった。

# 結論: 解決方法

Windows IMEの設定で「以前のバージョンのMicrosoft IME を使う」をオンにする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/e643b7a1-41db-952e-efbb-fa90a14ffb83.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/2e108a50-754c-14b9-3177-7e54da617809.png)

※ [@akikawa134](https://twitter.com/akikawa134)さんのおかげで助かりました。

# 現象

* かな入力で、入力最初の文字が「を」の場合Shift + 0を押してもなにも入力されない。
* Shiftなしで「わ」は入力できる。
* 半角に切り替えて0も入力できる。
* 他の文字を入力してからだとShift + 0で「を」入力できる。
* しばらくなにも入力しないで、入力最初に「を」入力すると再現
* どのキーボードでも同じ現象になる(ハードウェアがおかしいわけではない)
  * ノートパソコン自体のキーボードも外付けキーボードも同じ現象

# 思い当たること

直近、Windows Update で Windows 10 Version 20H2 にした。
[Linter] Error running PHPMD Error: dyld: Library ~ not loaded: ~の解消方法

# 概要
テキストエディタのAtomで、ファイルを開いたところ、以下のようなエラーが発生しました。
今回は、このエラーの解消方法を投稿します。
![Linter Error running PHPMD](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/650098ad-1483-34d3-4125-ac9c54a80185.png "ポップアップ表示の内容")
![Atom Console画面で、エラーの内容確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/bdea97bb-8aaa-c962-c171-67fa59ce33cc.png "Atom Consoleの内容")

# 解消方法
まず、Homebrewを用いてPHPを再インストールするコマンドを実行します。

```console:terminal
% brew reinstall php
```

次に、以前Composerを用いてPHPMDをインストールした際に、
作成した「composer.json」fileが配置されているディレクトリで、以下のコマンドを実行します。
このコマンドは、「composer.json」に記述されているパッケージのアップデートを行うものです。

```console:terminal
[composer.jsonが配置されているディレクトリ]% composer update
```

こうすることで、無事にエラーを解消することができました。

# エラーの原因
Atomを起動する前に以下のコマンドを実行しました。

```console:terminal
% brew update && upgrade
```

そのためか、ローカル上にあるPHPと繋がらなくなっていました。
これが、原因の1つであると思われます。
また、Composerでインストールしていたパッケージのバージョンが、
古くなっていたことも原因のようです。

# 参考文献

https://stackoverflow.com/questions/22631026/dyld-library-not-loaded-usr-local-lib-libpng16-16-dylib-with-anything-php-rel


https://qiita.com/KEINOS/items/86a16b06af6e936a1841
特定の領域だけBasic認証を掛けない

特定の領域だけBasic認証を掛ける記事は山ほど出てくるのだが…

開発中のページは非公開にしておきたいけどapiだけはrestfulなので叩けるようにしておきたい
ディレクトリであればapi置いてるところにもう1個.htaccess置けばいいのだが
URLがエイリアスである場合は特定の文字列を許可領域として設定する必要がある


```apache
AuthType Basic
AuthName "Please enter your ID and password"
AuthUserFile /var/www/.htpasswd

SetEnvIf Request_URI "/*api*" auth_dir
SetEnvIf Request_URI "^/index.php$" auth_dir
# assets類は必要に応じて追加
SetEnvIf Request_URI ".(svg|js|ico)$" auth_dir

<RequireAny>
    Require valid-user
    Require env auth_dir
</RequireAny>
```

上記はWordpressのwp-jsonを使うシーンでの設定だが
汎用的に使えるので大きなナレッジになった。
色々試しまくって分からなかったのでやってもらった...けど今後も必要なので残しておく
Cypressをdocker-composeで起動（Mac）

# 概要
CypressのTestRunnerとGUIをdockerでローカルに構築したときのメモ
公式サイトと他の方の記事に全て書いてあるが、自分の構築時の備忘録として残しておきます。

# 手順
- MacOS:10.15.7
- docker-compose
    - app -> テスト対象のwebサービス
- webアプリケーションはあらかじめたてておく


```
(approot)
 ├ cypress
 │  └ integration
 │    └ sample_spec.js
 ├ cypress.json -> 空でも置く
 ├ yml:docker-compose-cypress-open.yml -> GUI open用
 ├ yml:docker-compose-cypress.yml -> cypress起動
 └ docker-compose.yml -> app用
```

## Test実行(CLI)

アプリケーションがRailsだったので以下をconfigに追加
```rb
config.hosts << 'app'
```

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

services:
  e2e:
    container_name: e2e
    image: cypress/included:6.6.0
    depends_on:
      - app
    environment:
      - CYPRESS_baseUrl=http://app:3000
    working_dir: /e2e
    volumes:
      - ./:/e2e
```

```sh
docker-compose -f docker-compose.yml -f docker-compose-cypress.yml run --rm e2e
```

## GUI open
### XQuartzインストール
以下にしたがって、インストール・設定・起動
https://sourabhbajaj.com/blog/2017/02/07/gui-applications-docker-mac/

### envをセット

```sh:fish
set IP (ipconfig getifaddr en0)
set DIDPLAY :0
xhost + $IP
set DISPLAY $IP:0
```
(参考) https://www.cypress.io/blog/2019/05/02/run-cypress-with-a-single-docker-command/#Docker-compose

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

services:
  e2e:
    entrypoint: cypress open --project .
    environment:
      - DISPLAY
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
```

### 起動
```sh
docker-compose -f docker-compose.yml -f docker-compose-cypress.yml -f docker-compose-cypress-open.yml run --rm e2e
```

# 課題
cypressのバージョンによってうまく動作しないところがそれぞれある
テスト実行時の挙動
(画面にログインをして、ログアウトリンクをクリックするサンプルテスト)

- 3.2.0
    - CLI:「Uncaught TypeError: Illegal invocation」のエラーが出る
    - GUI:「Uncaught TypeError: Illegal invocation」のエラーが出る
    - GUI: 別途日本語化対応が必要
- 3.4.0
    - CLI:「Uncaught TypeError: Illegal invocation」のエラーが出る
    - GUI:途中で「he automation client disconnected. Cannot continue running tests.」となって切れる
- 3.8.1
    - CLI: 正常に実行してパスした
    - GUI: 実行はされていそう（リクエストはしている）が画面が白い
- 4.12.1
    - CLI: 正常
    - GUI: 画面にRESULT_CODE_BAD_PROCESS_TYPEがでて止まる
- 5.6.0
    - CLI: 正常
    - GUI: Error code:6とでて止まる
- 6.6.0
    - CLI: 無限ループのようになるので強制終了させた
    - GUI: 正常に実行された。日本語化されてる
- 6.8.0
    - CLI: 6.6.0と同様
    - GUI: 最初のvisitをくりかえす無限ループのような現象

入っているデフォルトのブラウザのバージョンの違いとかかな・・


# 参考
- https://www.cypress.io/blog/2019/05/02/run-cypress-with-a-single-docker-command/#Docker-compose
- https://sourabhbajaj.com/blog/2017/02/07/gui-applications-docker-mac/
- https://qiita.com/kodai_0122/items/67c6d390f18698950440
DXを進めるための5Gの基礎知識

###"５Ｇ"は「一強独占のインターネット型のビジネスモデル」を変える###
　**1. ”５Ｇ”で「何ができるか？」**
　**2. ”５Ｇ”に「いつ着手するか？」**
　**3. ”５Ｇ”の「ビジネスモデル」**

https://www.slideshare.net/MMurakamiMurakami/dxg-244710199

##1. ”５Ｇ”で「何ができるか？」##
**▶ インターネット”で出来なかったことが“５Ｇ”で出来る**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/1e1e392b-6b32-5b0b-a1f7-064e035eef00.png)
##2. “５G”に「いつ着手するか？」##

####“５G環境”は前倒し ⇒ ５Gビジネスでの先行者利益が得られる時期
**▶ 今年(2021年)、「５Gのインフラ」が整い**
**▶ 来年(2022年)、「５Gビジネス・モデル」が色々な分野でスタート**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/b773fa6a-d3fa-c1e6-5c5c-861350492ea9.png)

##3. ”５Ｇ”の「ビジネスモデル」##
**▶ 米国、中国のICTビジネスモデルが参考にならない“５G”**
**▶ 日本のビジネス・モデルを、欧米が参考にする！？**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585213/62d1523e-7fe3-e8aa-3f34-2a84b2e0f3ed.png)


https://www.slideshare.net/MMurakamiMurakami/dxg-244710199
PythonやRuby等のスクリプトをUbuntuデスクトップのメニューに追加する -   GNOME メニュー編集用ツール alacarte -

## はじめに

Ubuntu Desktopを使っている人も最近はわりと多いのではないかと思います。そして、PythonやRubyで自分用のスクリプト（GUIを含むもの）を書いて利用している人も少なくないと思います。ここでは[alacarte](https://gitlab.gnome.org/GNOME/alacarte)というメニュー編集ツールを利用してUbuntuのメニューに、自作のスクリプトを登録する方法を記述します。

## alacarte

インストール

```sh
sudo apt install alacarte
```

alacarteを起動したところ　↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/18e8edc5-03a1-3152-87d4-d49a7781ae1f.png)

ここでは、例として、サウンドとビデオの項目に[LibUI](https://github.com/kojix2/LibUI)で作成した[tiny_midi_palyer.rb](https://github.com/kojix2/LibUI/blob/main/examples/midi_player.rb) を追加することにします。

左のリストから、サウンドトビデオを選び、新しいアイテムをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/ef42f40e-e4de-bb8a-38ec-92fa6e1ae136.png)

Nameを入力します。
Browseをクリックして、Rubyスクリプトを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/9ea29aee-2fdf-63db-e4a1-c8838ba9d9fe.png)

しかし、実はこれだけではうまくいかなかったりします。Ruby ユーザーの多くは `rbenv` を利用して Ruby をインストールしていると思いますが、こうやってしまうと、rbenv で global にした Ruby ではなく、`/usr/bin/ruby` が呼ばれてしまいます。`~/.bashrc` を経由していないのが原因かもしれません。Pythonスクリプトでも似たような問題が発生するかも知れないので気をつけてください。

ここでは原因を突き止めるのは面倒なので、安易な解決策、つまり、rubyのパスをベタ書きすることで対処します。
(shebangを書き換えても動作するかも知れませんが、確かめていません）

```
/home/kojix2/.rbenv/shims/ruby your_script_name.rb
```

です。これで無事にアプリが登録されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/dfe1d7a2-c9fa-8a0e-cea9-a01d27c63e27.png)

↑ここから、アイコンを登録することができますが、スキップしても大丈夫です。
きちんと起動できるか確認します。きちんと登録されていれば、アプリが検索できるようになっているはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/d773ce4b-df48-f2e6-dcf2-e651a2046301.png)

うまく起動しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/fd82a77f-285d-9327-6e45-9347a1cbe8c9.png)

## 注意点

この記事はここで終了でも良いかもしれませんが、いくつか注意点がありますので書いておきます。

* 一度登録したメニューはプロパディから編集できないかも知れません。これは、私の環境が悪いのか、ソフトのバグなのかわかりませんが、アイテムを一度作ってしまうと、プロパディからアイテムを編集しても変更が反映されないということがありました。これで1時間ぐらいハマりました。これも原因を詳しく調査していませんがそういうことがあり得るので気をつけてください。

* 上と関連するのですが、うまくスクリプトのメニューへの登録ができなくて、デバッグのようなことをする場合は、Launch in Terminalに✅を入れて調べることになると思います。これも、一回作成したものをすべて削除して、あたらしくアイテムの追加からやりなおさなければ反映されないケースがあります。気をつけてください。

　この記事ではalacarteを使う方法を紹介しましたが、それ以前には他にも方法があったようですがなくなってしまったようです。理由はわかりませんが、Ubuntuデスクトップのクオリティの高さとは裏腹に、RubyやPythonのようなスクリプトをメニューに登録する方法はあまり整備されていないような印象を受けました。セキュリティの関係でしょうか？また上記に書いたような不具合のようなものも存在します。RubyやPython、Perlといったスクリプト言語でGUIアプリを作成する人が少ないため、整備が遅れているのでしょうか？　少し不思議です。

この記事は以上です。
Firestoreのサブコレクションに複合インデックスを作成する

例えば `users/{uid}/messages` というサブコレクションに複合インデックスを作成したいとします。

コレクションIDに `users/{uid}/messages` を指定したいですが、入力エラーとなってしまいます。

Firestoreのインデックスはコレクション名に対して指定するもので、コレクションのフルパスに対して指定するのではないようです。
https://stackoverflow.com/questions/47151798/cloud-firestore-wildcard-for-indexing/47165007#47165007

今回のケースではコレクションID `messages` に対して複合インデックスを作成すれば良いみたいです。

同じ名前のサブコレクションを意図して使うかどうかは検討が必要そうだな。。

# 2021/3/21追記
同じ名前のコレクション全てにインデックスが作成されるから、別のドキュメント下の同じ名前のサブコレクション全体(コレクショングループ)に対してクエリが実行できるメリットがあるのか。
https://firebase.google.com/docs/firestore/query-data/index-overview?authuser=0#single_field_index_collection_group_scope
EKSのバージョンを上げたらFalcoが「error opening device /host/dev/falco0」で動かなくなった

EKS Version 18で動いていたFalcoと同様の定義を、EKS Version 19で動かしたら `CrashLoopBackOff` のエラーになりました。

以前も同じエラーで詰まったのですが、情報残しておかなかったら、原因忘れてまた調べることになったので書いておきます。

EKS Version 18で動いていたFalcoのPodが、Version 19では何故かエラーになります。

```sh
$ kubectl get po 
NAME                          READY   STATUS             RESTARTS   AGE
falco-bmn9d                   0/1     CrashLoopBackOff   6          7m7s
```

ログを見ると以下のようなログが出力されていました。

```sh
/build/make.log (with GCC /usr/bin/gcc-6)
* Trying to dkms install falco module with GCC /usr/bin/gcc-5
DIRECTIVE: MAKE="'/tmp/falco-dkms-make'"
* Running dkms build failed, couldn't find /var/lib/dkms/falco/5c0b863ddade7a45568c0ac97d037422c9efb750/build/make.log (with GCC /usr/bin/gcc-5)
* Trying to load a system falco driver, if present
* Trying to find locally a prebuilt falco module for kernel 5.4.95-42.163.amzn2.x86_64, if present
* Trying to download prebuilt module from https://download.falco.org/driver/5c0b863ddade7a45568c0ac97d037422c9efb750/falco_amazonlinux2_5.4.95-42.163.amzn2.x86_64_1.ko
curl: (22) The requested URL returned error: 404
Download failed, consider compiling your own falco module and loading it or getting in touch with the Falco community
Fri Mar 19 05:15:57 2021: Falco version 0.27.0 (driver version 5c0b863ddade7a45568c0ac97d037422c9efb750)
Fri Mar 19 05:15:57 2021: Falco initialized with configuration file /etc/falco/falco.yaml
Fri Mar 19 05:15:57 2021: Loading rules from file /etc/falco/falco_rules.yaml:
Fri Mar 19 05:15:59 2021: Loading rules from file /etc/falco/falco_rules.local.yaml:
Fri Mar 19 05:16:00 2021: Unable to load the driver.
Fri Mar 19 05:16:00 2021: Runtime error: error opening device /host/dev/falco0. Make sure you have root credentials and that the falco module is loaded.. Exiting.
```

ログをしっかり見ればすぐわかるのですが、原因はここです。

```sh
https://download.falco.org/driver/5c0b863ddade7a45568c0ac97d037422c9efb750/falco_amazonlinux2_5.4.95-42.163.amzn2.x86_64_1.ko
curl: (22) The requested URL returned error: 404
```

EKSのバージョンを上げたことで、マネージドEC2ノードのAmazon Linuxのバージョンが上がっていました。

```sh
$ uname -a
Linux ip-10-53-147-85.agc.jp 5.4.95-42.163.amzn2.x86_64 #1 SMP Thu Feb 4 12:50:05 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```

このカーネル情報を合ったDriverを、[こちらのサイト](https://download.falco.org/)からダウンロードする動きなのですが、最新のバージョンに対応したDriverがまだ無いことが原因でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116068/7460e3a4-dd96-351e-586d-56da40bfbfd8.png)


次のバージョンのDriverが出るまで待つしかなさそうです。
ハイパーパラメータ探索

## グリッドサーチ

- 最適なパラメータが見つかりやすい
- 計算量が多い（パラメータの数に応じて指数関数的に増大）
- 時間がかかる

## ランダムサーチ

- 運任せ
- 見つかりにくい
- 時間かからずそこそこの成果


## ベイズ最適化

- ガウス過程の回帰
- 良さげなパラメータまわりを探す
- よいパラメータ近くを探索する
- 良いとこどり
- 実務向け
php公式dockerイメージで使えるphp拡張を調べる

## はじめに

https://hub.docker.com/_/php

- phpの公式dockerイメージでは`docker-php-ext-configure`, `docker-php-ext-enable`, `docker-php-ext-install`でphp拡張を管理できる
- dockerイメージの/usr/src/php.tar.xzにphp拡張のソースコードが予め含まれており、`docker-php-ext-*`でphp拡張を追加で有効にしたり、コンパイルオプションを調整して再ビルドしたりできる仕組みになっている
- 扱えるのは事前にソースコードが用意されている分のみ

## `docker-php-ext-*`で扱えるphp拡張を調べる

`docker-php-ext-install`のhelpを見ればわかる。

```bash
$ docker run --rm -it php:7.3-cli-alpine docker-php-ext-install
usage: /usr/local/bin/docker-php-ext-install [-jN] [--ini-name file.ini] ext-name [ext-name ...]
   ie: /usr/local/bin/docker-php-ext-install gd mysqli
       /usr/local/bin/docker-php-ext-install pdo pdo_mysql
       /usr/local/bin/docker-php-ext-install -j5 gd mbstring mysqli pdo pdo_mysql shmop

if custom ./configure arguments are necessary, see docker-php-ext-configure

Possible values for ext-name:
bcmath bz2 calendar ctype curl dba dom enchant exif fileinfo filter ftp gd gettext gmp hash iconv imap interbase intl json ldap mbstring mysqli oci8 odbc opcache pcntl pdo pdo_dblib pdo_firebird pdo_mysql pdo_oci pdo_odbc pdo_pgsql pdo_sqlite pgsql phar posix pspell readline recode reflection session shmop simplexml snmp soap sockets sodium spl standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl zend_test zip

Some of the above modules are already compiled into PHP; please check
the output of "php -i" to see which modules are already loaded.
```

> Possible values for ext-name:

以降に使えるphp拡張名が列挙されている。

php:7.3のイメージでは以下のようになっている。

```
bcmath
bz2
calendar
ctype
curl
dba
dom
enchant
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
imap
interbase
intl
json
ldap
mbstring
mysqli
oci8
odbc
opcache
pcntl
pdo
pdo_dblib
pdo_firebird
pdo_mysql
pdo_oci
pdo_odbc
pdo_pgsql
pdo_sqlite
pgsql
phar
posix
pspell
readline
recode
reflection
session
shmop
simplexml
snmp
soap
sockets
sodium
spl
standard
sysvmsg
sysvsem
sysvshm
tidy
tokenizer
wddx
xml
xmlreader
xmlrpc
xmlwriter
xsl
zend_test
zip
```

ここにないものはpickleで入れる。
https://github.com/FriendsOfPhp/pickle
Ubuntu 18.04 で機械学習環境 ( cuda 10.0 + cudnn7.4 + Pytorch 1.7.1 ) の構築

# 環境
OS : ubuntu 18.04
CPU : Intel® Xeon(R) W-2123 CPU @ 3.60GHz × 8 
GPU : RTX 2080 Ti 

# 古いバージョンを消す

```bash
sudo apt-get --purge remove nvidia-*
sudo apt-get --purge remove cuda-*
sudo apt-get --purge remove cudnn-*
sudo apt-get --purge remove libnvidia-*
sudo apt-get --purge remove libcuda-*
sudo apt-get --purge remove libcudnn-*
sudo apt-get autoremove
```

以下を実行して何も出なければ OK です。

```bash
dpkg -l | grep nvidia
dpkg -l | grep cuda
dpkg -l | grep cudnn
```

# CUDA 10.0 のインストール
CUDA 10.0を[ここから](https://developer.nvidia.com/cuda-10.0-download-archive)ダウンロードする。(今回はrunfile)

```
sudo ./cuda_10.0.130_410.48_linux.run
sudo reboot
```

`nvidia-smi` で GPU が認識されていることを確認します。

続けて PATH を通します。

```bash
echo -e "\n## CUDA and cuDNN paths"  >> ~/.bashrc
echo 'export PATH=/usr/local/cuda-10.0/bin:${PATH}' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-10.0/lib64:${LD_LIBRARY_PATH}' >> ~/.bashrc
```
`nvcc -V` で CUDA 10.0がインストールされていることを確認します。


# cuDNN 7.4 のインストール

https://developer.nvidia.com/rdp/cudnn-archive

下記のページでログイン後、以下のパッケージをダウンロードします。
- libcudnn7_7.5.1.10-1+cuda10.0_amd64.deb
- libcudnn7-dev_7.5.1.10-1+cuda10.0_amd64.deb
- libcudnn7-doc_7.5.1.10-1+cuda10.0_amd64.deb

```bash
sudo dpkg -i libcudnn7_7.5.1.10-1+cuda10.0_amd64.deb
sudo dpkg -i libcudnn7-dev_7.5.1.10-1+cuda10.0_amd64.deb
sudo dpkg -i libcudnn7-doc_7.5.1.10-1+cuda10.0_amd64.deb
```

以下で `Test passed!` が出ればOKです。

```bash
cp -r /usr/src/cudnn_samples_v7/ $HOME
cd $HOME/cudnn_samples_v7/mnistCUDNN
make clean && make
./mnistCUDNN 
```

# Pytorch 1.7.1 のインストール
```bash
pip install torch==1.7.1 torchvision==0.8.2 torchaudio==0.7.2
```

# トラブルシュート
途中でミスったりすると、`E: 未解決の依存関係です。'apt --fix-broken install' を実行してみてください` みたいなエラーが出る可能性があります。これが解消されると以下２つのコマンドの結果が空になります。

```bash
sudo dpkg --audit
sudo dpkg --configure -a
```

解消するには、上記２つのコマンドで出てくるpackageを

```bash
sudo dpkg --remove --force-remove-reinstreq package名
```
で消しまくります。以上です。

# 参考
- https://qiita.com/tsuchiyaTaro/items/10d399686ce778cb9ffa
- https://qiita.com/Yoshitaka_Youtuber/items/bd8edcb36396df878641
Chromeバージョンによるaudioの自動再生の挙動について

# はじめに

audioによる自動再生（Javascriptによる再生も含む）について調査しました。
videoタグについても同様かと思いますが、ここではaudioをターゲットにしています。

# 自動再生について

自動再生には、audioタグにautoplay属性を付与する方法と、Javascriptから再生する方法があります。

```html:autoplay属性付与
<audio src="/path/to/audio.mp3" autoplay id="audio">
```

```javascript:Javascriptによる再生
document.getElementById("audio").play()
```

# 自動再生の条件

Chromeのバージョンが70より前は、特に条件なく上記の書き方で問題なく再生されます。

ただ、70以降は別の対応が必要になります。これはメディアに関するChromeのセキュリティポリシーが変更になったためです。

まず、[Googleが公開しているページ](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#iframe)を参考に、自動再生するための条件についてみていきます。

- ミュートになっている
- ユーザがサイトに対して操作（クリック、タップ、キー押下）を行う
- MEI（メディアエンゲージメントインデックス）が閾値を超えている
- PWAアプリとしてインストールされている
- iframeタグで自動再生ポリシーを委任している

#### ミュートになっている

audioは音声のみのため、ミュートにすることはないと思うので、この対応は現実的ではありません。

#### ユーザがサイトに対して操作（クリック、タップ、キー押下）を行う

ページ表示後にユーザがページのいずれかをクリックまたは、タップなどを行った場合はユーザが意図的に閲覧していると解釈され自動再生が可能になります。

#### MEI（メディアエンゲージメントインデックス）が閾値を超えている

簡単に言うと、メディアコンテンツメインのページであることです。具体的に指標を見てみます。

- メディア（オーディオ/ビデオ）の再生時間は7秒より長くなければなりません。
- 音声が存在し、ミュートされていない必要があります。
- ビデオのあるタブがアクティブです。
- ビデオのサイズ（ピクセル単位）は200x140より大きくする必要があります。

上記を見る限り、音声のみだと閾値を超えるのは難しそうです。

#### PWAアプリとしてインストールされている

該当ページがPWA対応されており、かつユーザがPWAアプリをインストールした場合です。
非PWAから対応するにはコストがかかりますし、ユーザがインストールしてくれるとは限りません。

#### iframeタグで自動再生ポリシーを委任している

以下のような記述によって、自動再生ポリシーが適用できます。

```html:iframeの利用
<iframe src="/path/to/dummy.mp3" allow="autoplay" style="display:none"/>
```

ここまで自動再生の条件をみてきましたが、フロントのみで対応可能なのは、iframeを利用することだと思います。

# 挙動確認

|バージョン|iframeの有無|自動再生|
|--:|:--:|:--:|
|69以前|無|○|
|70〜76|有|○|
|78以降|有|×|

この結果が表すものは、<font color="red">78以降はiframeによる自動再生ポリシーも通用しない</font>ということです。

# 対策

ページ表示後にダイアログを表示させるなど、<font color="red">ユーザにアクションさせるように促す</font>しかないと思います。または、本当にここで音声を自動再生させるべきか検討し直した方がいいかもしれません。

他に対策があれば、コメント等で教えていただけると幸いです。

同一オリジン内の画面遷移で表示した場合は、自動再生されます。

# 参考サイト

- [メディアおよびウェブオーディオ API の自動再生ガイド](https://developer.mozilla.org/ja/docs/Web/Media/Autoplay_guide)
- [Autoplay Policy Changes](https://developers.google.com/web/updates/2017/09/autoplay-policy-changes#iframe)
- [How to make audio autoplay on chrome](https://stackoverflow.com/questions/50490304/how-to-make-audio-autoplay-on-chrome)
mysqlでデータベース毎にダンプをとる

## 何をするか？

データベース毎にダンプをとる。

## shの作成

ホスト名やユーザ名は共通する場所に置いておく。

```txt
# conf.txt
host="ホスト名"
user="ユーザ名"
password="パスワード"
dump_path="ダンプの保存場所"
db_name_list_file="データベース名を保存するファイル名"
```

データベース名を取得して保存するshを作成する。
ホスト名などは上で作成したファイルから取得する。

```sh
# db_name.sh
cd `dirname $0`

. ./conf.txt

show_command="show databases;"

db_name_list=$dump_path"/"$db_name_list_file

$(mysql -h $host -u $user -p$password -N -e "$show_command" > $db_name_list)
```

保存したデータベース名を読み取って、ダンプを取る。
gizpに圧縮してファイルの容量を減らす。

```sh
# db_dmup.sh
cd `dirname $0`

. ./conf.txt

read_file=$dump_path"/"$db_name_list_file

while read line
do
  $(mysqldump -u $user -h $host -p"$password" $line --no-tablespaces | gzip > ${dump_path}/${line}_dump.sql.gz)
done < $read_file
```

あとは、順番に動くようにcronで自動実行の設定をする。

## おわりに

さくらのレンタルサーバで複数のアプリが起動していて、役割が違うデータベースが存在するので、このようなスクリプトを作成してみました。
今後はデータベースが増えても自動でダンプが取れるはず。
sqlのアウトプット

# is と＝の違いについて
is は null でしか使用できない。それ以外の、例えば文字列には = を使う。
でも、is でも実行できちゃったんだけどダメなの？
#集計関数って sum avg count の他にどんなものがあるの？
max min があった。それ以外には特に見当たらなかった。
#クエリって？
データベースに問い合わせること

#雑感
一気に書こうとしちゃいけない。処理の順番を確認して、１個ずつちゃんとエラーなく動くかどうか辿っていくと良い。
【備忘録】AmazonLinux2でLaravelの環境構築をする時の手順

2020年1月頃（?）にやったときの手順

# EC2インスタンスに接続
```bash
ssh -i 公開鍵ファイル名 ec2-user@IPアドレス
```

# yumアップデート
```bash
sudo yum -y update
```

# 時刻設定
```
sudo vim /etc/sysconfig/clock
```
```vim:/etc/sysconfig/clock
ZONE="Asia/Tokyo"
UTC=false
```

:wq

```bash
sudo cp /usr/share/zoneinfo/Japan /etc/localtime
```

# 言語設定
```bash
sudo vim /etc/sysconfig/i18n
```

```vim:/etc/sysconfig/i18n
LANG=ja_JP.UTF-8
```
:wq

# amazon-linux-extrasを使わないとPHPのバージョンが古いまま
```bash
$ sudo amazon-linux-extras install php7.3
$ php -v
$ sudo yum install php-mbstring php-pecl-memcached php-gd php-apcu php-xml
$ sudo yum install httpd
$ sudo systemctl start httpd
$ sudo systemctl enable httpd
$ sudo vi /etc/php.ini
```

```ini:/etc/php.ini
# HTTPヘッダにPHPのバージョンを記載しない(一応セキュリティ上Offにしておいたほうが良い)
# expose_php = On
expose_php = Off
# メモリ上限を引き上げる(結構デフォルトのメモリは少なめなので増やしておくことが多い)
# memory_limit = 128M
memory_limit = 256M
# POST送信の許容サイズを引き上げる
# post_max_size = 8M
post_max_size = 16M
# アップロードファイルの許容サイズを引き上げる(2Mだと画像投稿に際して不足なので増やす）
# upload_max_filesize = 2M
upload_max_filesize = 5M
# timezoneの設定
# date.timezone =
date.timezone = Asia/Tokyo
```

```bash
$ sudo systemctl restart php-fpm
```

# composerインストール 〜 プロジェクト作成

```bash

$ curl -sS https://getcomposer.org/installer | php
$ sudo mv ./composer.phar /usr/local/bin/composer
$ cd /var
$ sudo chmod -R 777 www
$ cd www
$ composer create-project --prefer-dist laravel/laravel myapp
$ cd myapp
$ sudo chmod -R 777 storage/logs
# httpd設定
$ sudo vi /etc/httpd/conf/httpd.conf
```

```conf:/etc/httpd/conf/httpd.conf
DocumentRoot "/var/www/myapp/public" # /var/www/htmlから修正
    (中略)
<Directory "/var/www/myapp/public"> # /var/www/htmlから修正
    Options +FollowSymLinks
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
    Require all granted
    AllowOverride All
</Directory>
```

```bash
$ sudo systemctl restart httpd
# composer requireなどがメモリー不足と言われるので、その対応
$ free -m
$ sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
$ sudo /sbin/mkswap /var/swap.1
$ sudo /sbin/swapon /var/swap.1
# node.js npmのインストール
$ curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -
$ sudo yum install -y nodejs
$ node -v
$ npm -v
```


# s3の使用準備

```bash
$ composer require league/flysystem-aws-s3-v3
```

# マイグレーションファイルがカラム変更等にも対応できるよう設定
```bash
$ composer require doctrine/dbal
```
【Laravel】Collectionのfilter後に、APIのJSONレスポンスでオブジェクトとしてレスポンスされてしまった

# はじめに
Laravelで、Collectionのfilter後に、Collection内の配列にkeyが付与されてしまい、
「APIのJSONレスポンスで配列ではなくオブジェクトとしてレスポンスされてしまう」
というケースが発生したので、メモとして残しておきます。

- PHP 7.4.14
- Laravel 7.27.0

# 結論
Collectionクラスの  `values()` メソッドでキーをリセットする
[Laravel 7.x コレクション : values()](https://readouble.com/laravel/7.x/ja/collections.html#method-values)


# 問題になったケースのサンプル
商品テーブルから取ってきた内容に対して、filterした結果をmapでidだけにする。

```php
Product::query()
    ->get()
    ->filter(function (Product $product) {
        return $product->amount >= 100; // 金額が100円以上の商品のみ
    })->map(function (Product $product) {
        return [
            'id' => $product->id,
        ];
    });
```

##### tinker の結果
keyが設定されている

```php
=> Illuminate\Support\Collection {
     all: [
       2 => [
         "id" => 2,
       ],
     ],
   }
```

# values() を付けることで解消する

```php
Product::query()
    ->get()
    ->filter(function (Product $product) {
        return $product->amount >= 100; // 金額が100円以上の商品のみ
    })->values() // 追加
    ->map(function (Product $product) {
        return [
            'id' => $product->id,
        ];
    });
```

##### tinker の結果
keyが設定されていない

```php
=> Illuminate\Support\Collection {
     all: [
       [
         "id" => 2,
       ],
     ],
   }
```
CSS in JSライブラリのトレンド比較

# 概要

CSS in JSライブラリを選定するにあたり、NPMダウンロード数を比較しました。

# NPM ダウンロード数

![スクリーンショット 2021-03-19 12.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/802246/596252f3-9be2-984c-6bed-49de0f251a77.png)

https://www.npmtrends.com/styled-components-vs-emotion-vs-jss-vs-styled-jsx-vs-radium

# 参考

https://openbase.com/categories/js/best-react-frameworks-libraries?orderBy=RECOMMENDED&

https://www.telerik.com/blogs/what-you-need-to-know-css-in-js-2021
【Go言語】文字結合 (string concatenate) パフォーマンス strings.Builderを使おう


# TL;DR

go1.10からのstrings.Builderは実態はGoのBufferタイプと同じ。アロケーションが発生しないので多量な文字結合するならばstrings.Bufferを使っていこう。

# ベンチマークコード

```go:vs_test.go
package main

import (
	"strings"
	"testing"
)

func Benchmark_string(b *testing.B) {
	var s string
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		s += "a"
	}
	b.StopTimer()
}

func Benchmark_stringsBuilder(b *testing.B) {
	var sb strings.Builder
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		sb.WriteString("a")
	}
	_ = sb.String() // output string
	b.StopTimer()
}
```

# 結果

圧倒的にstrings.Builderが速い

```
$ go test -bench . -benchmem
goos: darwin
goarch: amd64
Benchmark_string-4                769185             52775 ns/op          388557 B/op          1 allocs/op
Benchmark_stringsBuilder-4      204743859                5.09 ns/op            5 B/op          0 allocs/op
PASS
```

# 参考
【Git】Githubで共同開発しているときに空白を消してはいけない！？なぜ消してはいけないのか？その理由

Githubで共同開発しているプロジェクトで、余計な空白があった場合に、消した方がキレイで見やすくなるじゃんと思って親切心で消したくなるが、**他の人が作った空白は消してはいけない**。

##不要な空白の例
空白は赤くハイライトされるから気持ち的には消したくなる、、

**▼（例１）Githubのコードチェック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/4a850f2e-c0f2-09a9-16db-de7c7cf376b9.png)


**▼（例２）VSCode （pluginでハイライト）**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563526/08af84e7-791e-1afc-3a48-055392a28470.png)


##消してはいけない理由
###1. コードの責任者が変わる
親切心で空白を消してしまうと、そのコードの最終作業者が自分になってしまう。

例えばある関数の空白を一つ消すと、Git Lenseなどで表示される作業者が自分になるので、その関数の**責任を自分が持っていることになってしまう**。

デバッグ時や問題があった時に、みんなが混乱する原因になる。


###2. 変更済みファイルが増える
プルリクを出した時に、空白を削除しただけのファイルやコードがあると、そこも差分として表示されてしまう。

コードを確認する人からしたら、どこを触ったのかわかりにくくなり確認の手間が増える。



<br>
##プルリク（プッシュ）してしまった時の対処法
もしプルリク（プッシュ）した後に修正する必要性が出たら、以下で対応可能（他にもたくさんあるので一例として）

プッシュ済みの変更を確認しながら作業する必要があるため、一時的に現状をコピーしたブランチを作成。

```
#ブランチのコピーを作る（参照用）
$ git checkout -b 一時的なブランチ名

#作業用ブランチに戻る
$ git checkout 作業用ブランチ名

#作業前のコミットに戻す（変更内容も削除）
# git reset --hard <コミット番号>
```

あとは、`git checkout <一時的なブランチ名>`で中身を確認しながら、空白以外の変更点を記述指定けばOK。


**▼注意点**
ブランチを切り替えるときは、git stashで変更内容を待避させること。

```
#作業中のブランチ
$ git stash 

$ git checkout <一時的なブランチ名>

#作業中のファイルとの差分を確認
$ git diff stash@{0}

#作業中のブランチに戻る
$ git checkout < 作業中のブランチ名>

#待避した内容を呼び戻す（※コレ忘れがち！）
$ git stash pop
```

`git stash`して、自分のブランチに戻ってきたら、`git stash pop`を忘れないこと。

`git stash pop`する前にファイルを変更してしまうと、コンフリクトが発生して、待避内容を呼び出せなくなる。


###git stash popできなくなってしまった時の対処法

```
#直前のコミットの状態に戻す（stashの内容は消えない）
$ git reset --hard @
$ git stash pop
```

<br>
以上。
【Git】git rebase エラー対処法｜First, rewinding head to replay your work on top of it... Fast-forwarded master to origin.

他のブランチの変更内容を自分のブランチの過去履歴に取り込む`git rebase`でFirst, rewinding head to replay your work on top of it...が出た時の理由と対処法。

>エラー内容
$ git rebase origin master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to origin.

>[要約]まず、あなたのブランチの最新のコミットにHEADを移動させてください（巻き戻す）
そこから、fast-forwardしてください。

<br>
##発生原因
取り込もうとしているブランチと自分の**ブランチが分岐していないため**。

`git rebase <ブランチ>`は分岐している指定したブランチの内容を自分の最新のコミットの直前にとってつける処理なので。

**分岐していない場合は、そもそもrebaseする必要がない**。

<br>
###分岐していないコミットの例


```:コミット履歴
    A---B---C---D---E master
   　　　↑  
　　自分のブランチ
```

または

```:
          C---D---E  master
         /
    A---B---F---G  他人のブランチ
   　　　↑
     自分のブランチ
```

この場合、masterブランチを取り込むには、自分のHEADをmasterの位置に移動すればいいだけ。

前に移動するので、`fast-forward`と呼ぶ。


##対処法
・`git merge <ブランチ名>`で自分のコミットを前に進めることができる。

```
git merge master

or

git merge origin master
```

<br>
###実例
まずは現状。masterのHEADは4つ前にある。分岐はしていない。

```:現状
$ git log --oneline
#masterの状況
57776bc (HEAD, origin/master, origin/HEAD, master) [add] article page: review
34db962 [add] article page: header
988381d [add] article page: cv btn
2a21e0a [add] article page: table

#今ここ
3e4e2b0 (origin/topic, topic) [F]json-ld route('index')
```

**▼fast-worwardを実行**
fast-worwardという名前がややこしいが、ただマージするだけ。

```
$ git merge origin master
Updating 3e4e2b0..57776bc
Fast-forward
#headが移動
57776bc (HEAD, topic, origin/master, origin/HEAD, master) [add] article page: review
34db962 [add] article page: header
988381d [add] article page: cv btn
2a21e0a [add] article page: table
3e4e2b0  (origin/topic) [F]json-ld route('index')
```

(origin/topic) を合わせるには、以下を実行すればOK。

```
$ git push origin topic
$ git fetch  
```


<br>
##（参考）rebaseの処理結果
rebaseの処理結果は以下のようになる。

```
          C---D---E  master
         /
    A---B---F---G  自分のブランチ
```

 ↓ `git rebase master`

```
                master
          C---D---E---F'---G'  自分のブランチ
         /
    A---B
``` 

以下と同じ

```
                  master
    A---B---C---D---E---F'---G'  自分のブランチ
``` 

これがrebase処理なので、分岐してなければrebaseは不要。(fast-forwardしてください言われる)
Warning: Each child in a list should have a unique "key" prop.

初学者あるあるらしい?

# 前提

React 17.0.1

# 起こったこと

こういうコンポーネントがあって

```jsx
const Blog = ({blog}) => {
	return (
		<li key={blog.id}>{blog.title} {blog.author}</li>
	)
}

export default Blog
```

こういうふうに使っていました。

```jsx

//(略)

const [blogs, setBlogs] = useState([])

//(中略)

const getAllBlogs = async () => {
	const blogs = await blogService.getAll()
	setBlogs(blogs)
}

const blogList = () => {
	getAllBlogs()
	return (
		<ul className="blog_ul">
			{blogs.map(blog =>
				<Blog blog={blog} />
			)}
		</ul>
	)
}

//(中略)


return (
	<div>
        {/*(略)*/}
		{user && blogList()}
	</div>
)
```

画面上は特に問題なさそうでしたが、コンソールには以下のエラーが出ていました。

```
index.js:formatted:1 Warning: Each child in a list should have a unique "key" prop.
```

# 修正

こちらのliタグではなく

```jsx

//liタグのkeyを消した
const Blog = ({blog}) => {
	return (
		<li>{blog.title} {blog.author}</li>
	)
}

export default Blog
```

こちらにkeyを持たせます。

```jsx
const blogList = () => {
	getAllBlogs()
	return (
		<ul className="blog_ul">
			{blogs.map(blog =>
				<Blog key={blog.id} blog={blog} />
			)}
		</ul>
	)
}
```

# なぜkeyがいるのか

これについてはReactのドキュメントでしっかり解説されていました。

https://reactjs.org/docs/reconciliation.html#recursing-on-children

要は、keyがあればリスト内のどの要素が変更されたのかkeyの値を使って一発で判定できるけれど、keyがなければわざわざ全部比較していかなければならないということらしいです。

# 配列のindexをkeyに使ってはいけない

Reactドキュメントの中で紹介されていた記事です。

https://robinpokorny.medium.com/index-as-a-key-is-an-anti-pattern-e0349aece318

例えば要素が3つの配列があったとしてindexがkeyだと以下のようなことが起きてしまいます。

```
1: 初期状態
<li key='0'>aaa</li>
<li key='1'>bbb</li>
<li key='2'>ccc</li>



2: keyが0のものに変更を加えて、さらに要素を先頭に追加すると...

2-1:先頭(=keyが0)のものに変更を加える
A <li key='0'>MODIFIED</li>
B <li key='1'>bbb</li>
C <li key='2'>ccc</li>

2-2: 要素をkeyの値で判定しているので、先頭に要素が追加された(=追加された要素のindexは0)ことにより間違ったデータが表示されてしまう
D <li key='0'>MODIFIED</li>
A <li key='1'>bbb</li>
B <li key='2'>ccc</li>
C <li key='3'></li>
```

配列のindexは要素の追加や削除によって変わってしまうので、こんなふうにズレてしまうということらしいです。
なのでkeyにはユニークな値を使うべきであり、例えばDBからユーザーのデータを取ってきて一覧表示などする場合は、ユーザーのidなどをkeyにするのがベストと言えます。
VSCODEで権限がないためにファイルの更新ができない場合の対処法


![vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135794/3323251e-bb53-55ca-82a7-fe405fe3dc2c.png)

VSCODEで権限がないためにファイルの更新ができない場合の対処法

こんにちは。

vscodeでReactで開発している時、ファイルの権限がないために変更できないという問題がありました。

この問題は、プロジェクトユーザーのパーミッションを自分に変更することで解決できます。

しかし、ファイルのパーミッションを変更してしまうと、チームで開発しているときに、ファイルのパーミッションまでgitにプッシュしてしまうことがあります。

そうなると、チームから警告を受けてしまうこともあります。

そこで、ローカルのプロジェクトフォルダのパーミッションを変更すると同時に、ファイルのパーミッション変更のgitへのプッシュを無視するようにするとよいでしょう。

[コマンドはこちら](https://off.tokyo/blog/vscode-permission/)
React入門（useState, useEffect）

#useStateの使い方


- [公式サイトを参考](https://ja.reactjs.org/docs/hooks-state.html)

変更前、変更後の状態の管理する機能です。
今回の場合は`checkbox`の状態を管理しています。


親クラス`App.js`
子クラス`Todos.js`

```react:Todos.jsx

import React, { useState } from 'react';


const Todos = () => {
  const [Task, setTask] = useState(false);　//初期値（false）
       //変更前　　変更後
  return (
    <div>
      <input 
         type="checkbox" 
         checked={Task} 
         id="check" 
         onClick={() => setTask(!Task)}/>
    </div>
  )
};

export default Todos;
```


```react:App.js
import React from 'react';
import Todos from './Todos';


return (
    <>
     <Todos />
    </>
  )
};

export default App;
```



#useEffectのライフサイクル
- [公式サイトの参考](https://ja.reactjs.org/docs/react-component.html)

https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

**Mounting**は初期値
**Unmounting**は初期値から変更された値

#useEffect

`import { useEffect } from 'react';`

```js:
useEffect(() => {
  // MountingとUnmountingに呼ばれる
})

useEffect(() => {
  // Mountingの時に呼ばれる
}, [])

useEffect(() => {
  // Mountingと引数の時に呼ばれる
}, [引数])

useEffect(() => {
    // Mountingの時に呼ばれる
  return () => {
    //Unmountingが呼び出される
   }
})
```
成功したGAN実験(DCGAN)(ソースコード付き)

成功例です。

![anima.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/2ae0b579-6208-ef20-b5d9-43d56fd0a350.gif)

2週間前にGANの初期バージョン（畳み込み層なし）を作成しましたが、その効果は次のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/2530940c-7d78-38a1-bb64-9b3ce51aa2ca.png)

数字を指定できる理由は、条件付きGANアーキテクチャを使用したためですが、バニラGANの効果が非常に悪く、ノイズが多いです。

DCGANは、GANの最初の進化であり、バニラGANアーキテクチャに畳み込み層を追加するだけと言えます。

コードをgithubに載せましたので、お気軽に参照してください。 後続のGAN実験は、この倉庫に配置されます。

https://github.com/zhuobinggang/fool-gan
一个成功的GAN实验

一两个星期以前我做了一个最初版本的GAN（没有卷积层），效果如下：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/5744683f-4452-f449-dd84-135257153289.png)

至于为什么可以指定数字输出是因为我用了conditional GAN的架构（如下图，左1），不过我想说的是vanilla GAN的效果很差，噪点很多。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/f7554b46-1c4d-b9f0-dab4-3ba84b8f5bab.png)

DCGAN可以说是GAN的第一次进化，只是简单地在vanilla GAN架构里加入了卷积层，效果如下图（epoch=60）：

![anima.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227568/56234682-5bc1-a95d-5a68-8e05f08d0b43.gif)

我把代码放在github，请随意参照。后续GAN的实验都会摆在这个仓库里：

[Fool GAN](https://github.com/zhuobinggang/fool-gan)