OmniAICreator/Qiita-1.07M huggingface dataset:
PRML　演習問題  8.13（基本）　解答

## はじめに
本記事は, 機械学習の教科書の決定版ともいえる, **Christopher Bishop先生**による[**『Pattern Recognition and Machine Learning （パターン認識と機械学習）』**]  (https://www.microsoft.com/en-us/research/people/cmbishop/prml-book/) , 通称**PRML**の演習問題のうち, 私が解いた問題の解答を記したものです. これは, 私の所属する[生物測定学研究室] (https://www.ut-biomet.org/) の輪読会で**PRML**を取り扱っており, その勉強の一環として演習問題を解いたときのものです. なお, 他の演習問題の解答例に関する記事については, [PRML　演習問題　解答集　まとめ]  (https://qiita.com/Lab_of_Biomet/items/15e38ca34fafa8176d89) をご覧ください.
 

## 問題
反復条件付きモード (ICM) を使って

``` math
\begin{align*}
E \left ( \mathbf{x}, \mathbf{y} \right )  = h \sum_i x_i - \beta \sum_{\{i, j\}} x_i x_j - \eta \sum_i x_i y_i
\tag{8.42}
\end{align*}
```

で与えられるエネルギー関数を最小化することを考える. すべての他の変数を固定して, ある1つの変数 $x_j$ に関する2状態のエネルギー値の差を書き下せ.
またその表現が, グラフにおける $x_j$ の近傍の局所的な量だけに依存することを示せ. 

## 解答
ICMでは $x_i$ を, 例えば $x_i = y_i$ のように初期化する.
次に, ノード$x_j$を1つ選び, その他のノード変数の値を固定したまま $x_j$ の2つの可能な状態 ( $x_j = +1$ 及び $x_j = -1$ ) における全エネルギーを評価する. この問題では、まずこの2状態のエネルギーの値の差を書き下せばよい.
さてここで, $\{x_i, x_j\}$ が隣接する変数の対であることに注意すると, $x_j$ を1つ選ぶと, 全エネルギー関数に影響を及ぼす $x_i$ は, 2次元画像の場合$x_j$の上下左右に位置するノードであることがわかる. したがって, この場合 $\left ( 8.42 \right )$ 式の第2項における和は4つの項に分解される.

``` math
\begin{align*}
E \left ( \mathbf{x}, \mathbf{y} \right )  = h \sum_i x_i - \beta  \left ( x_{j1} x_j + x_{j2} x_j + x_{j3} x_j + x_{j4} x_j \right )  - \eta \sum_i x_i y_i
\tag{8.13.1}
\end{align*}
```
ここで, $x_{j1}$, $x_{j2}$, $x_{j3}$, $x_{j4}$ はそれぞれ $x_j$ の上下左右に位置するノードを指すこととする. 
では $x_j = + 1$ 及び $x_j = - 1$ の時の全エネルギー関数を書き下してみよう. これは $\left ( 8.13.1 \right )$ 式に $x_j$ の値を代入すれば良いだけで, それぞれ


``` math
\begin{align*}
E \left ( \mathbf{x}, \mathbf{y} \right )  = h \sum_i x_i - \beta  \left ( x_{j1} + x_{j2} + x_{j3} + x_{j4} \right )  - \eta \sum_i x_i y_i
\tag{8.13.2}
\end{align*}
```


``` math
\begin{align*}
E \left ( \mathbf{x}, \mathbf{y} \right )  = h \sum_i x_i + \beta  \left ( x_{j1} + x_{j2} + x_{j3} + x_{j4} \right )  - \eta \sum_i x_i y_i
\tag{8.13.3}
\end{align*}
```

したがって, エネルギー値の差は, 

``` math
\begin{align*}
2\beta  \left ( x_{j1} + x_{j2} + x_{j3} + x_{j4} \right ) 
\tag{8.13.4}
\end{align*}
```
となる.
この表現は, グラフにおける $x_j$ と隣接するノードの値のみに依存するので, $x_j$ の近傍の局所的な量だけに依存することが示された.  (証明終)  

※ なお, この解答では2次元画像の場合について考えているが, これがより高次元のデータに対するノイズ除去の問題になったとしても, $x_j$ に隣接するノードについてのみ考えれば良い, ということは変わらない.
【React】 マウントされていない状態でsetState()を実行した際に発生するエラーを解消する

# はじめに

reactでコンポーネントがマウントされたときに、setStateを呼び出しstateを定義する実装をしているときに、

```
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the ComponentA component.
```

というエラーで詰まったので、解決したときのメモ。

# 内容

## 結論

エラー文に書いてある通りで、マウントされていないコンポーネントでsetState()を呼んでいることがダメです。

以下のように、refを使って要素がしっかり更新されたときにsetState()を実行するようにします。


```react
class ComponentA extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: {}
        };
    }
    componentDidMount() {
        this.hogeHoge();
    }
    hogeHoge() {
        
        // 以前の処理（あれば）
        
        // ここでdivに付与された「ref="myRef"」が存在するかどうかを確認
        if (this.refs.myRef) {
            this.setState({
                data: hogehoge // hogehogeは、以前の処理で処理された変数とか
            });
        }
        
        // 以降の処理（あれば）
    }
    render() {
        return (
            
            <div className="hoge" ref="myRef">
            </div>
        );
    }
}
```

追加したのは、

```
- setStateを実行する前の条件分（if(this.refs.myRef)）
- divのref（ref="myRef"）
```

です。

## 詳細

はじめは、componentDidMount()時に実行しているのに、なぜ

```
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the ComponentA component.
```

とエラーが出て、コンポーネントマウントされる前に実行していると出るんだろうと思っていましたが、、、
omponentDidMount()のせいで、stateが変更されてもう一度render()が実行されるからなのか・・・？
よくわからんという状態でした。。。

**詳しい理由をご存じの方、ご教示いただければ幸いです。**

ひとまず、refsを使ってしっかりマウントされた後をチェックすればエラーを吐かなくなるからいいかと・・・

# 参考
https://stackoverflow.com/questions/34544314/setstate-can-only-update-a-mounted-or-mounting-component-this-usually-mea
falconでイメージのアップロードとダウンロード

# falconでイメージのアップロードとダウンロード

falconでイメージファイルをダウロードする必要があったのですが、Qiitaに記事がなかったのでアップします。

##APIのソースコード
```python:server.py
import os
import json
import uuid
import falcon
from falcon_multipart.middleware import MultipartMiddleware

IMAGE_DIR = './images'
if not os.path.exists(IMAGE_DIR):
    os.mkdir(IMAGE_DIR)

class PostResource:
    def on_post(self, req, resp):
        image = req.get_param('file')
        raw = image.file.read()
        image_id = str(uuid.uuid4())
        filepath = os.path.join(IMAGE_DIR, f'{image_id}.png')
        with open(filepath, 'wb') as fp:
            fp.write(raw)
        resp.status = falcon.HTTP_200
        resp.content_type = 'application/json'
        resp.body = json.dumps({'image_id': image_id})


class GetResource:
    def on_get(self, req, resp, image_id):
        filepath = os.path.join(IMAGE_DIR, f'{image_id}.png')
        if not os.path.exists(filepath):
            resp.status = falcon.HTTP_404
            return

        resp.downloadable_as = filepath
        resp.content_type = 'image/png'

        resp.stream = open(filepath, 'rb')
        resp.status = falcon.HTTP_200


app = falcon.API(middleware=[MultipartMiddleware()])
app.add_route('/images', PostResource())
app.add_route('/images/{image_id}', GetResource())

if __name__ == "__main__":
    from wsgiref import simple_server
    httpd = simple_server.make_server("0.0.0.0", 8000, app)
    httpd.serve_forever()
```


## 起動方法
```shell
python3 server.py
```


## 呼び出し方
### イメージの登録
イメージをPOSTするとイメージID(以下の例では""44fea721-ef84-41c1-8845-3f2d5ad8b990")がJSONで返却されます。

```shell
curl -X POST -F file=@image.png http://localhost:8000/images
{"image_id": "44fea721-ef84-41c1-8845-3f2d5ad8b990"}
```

### イメージの参照
さきほどのイメージ登録時に返却されたイメージIDを利用してGETします。

```shell
curl -X GET -o out.png http://localhost:8000/images/44fea721-ef84-41c1-8845-3f2d5ad8b990
```


## 参考
* [Falconで画像アップロードを爆速開発]
(https://qiita.com/komakomako/items/5ba6a1b2a582464a7748)
【C#】画像を簡単に分類できるソフト「Beach flag」作ってみた

##はじめに
あったらいいなってものをせっかく作ったので公開しようと思います
ソフト名は「**Beach flag**」です
※自動分類ではなく、**手動分類の支援ソフト**です
##GitHubに公開しています

ソースコードは[ここから](https://github.com/Yu-Tomo/Beach_flag)
.exeファイルは[ここから](https://github.com/Yu-Tomo/Beach_flag/tree/main/Beach_flag_ver2_3_1/imageClassification/bin/Release)
##どうして作ったの？
エクスプローラーで画像の分類作業をやってたけどこれがめんどくさいし大量にやると苦痛！
楽したいので**支援ソフト**を作ることにしました

##用途
物体検知とかで、大量の画像を一枚一枚確認しながらチェックして分類する時とかに使えると思います(というかそれが目的)
あとは、写真分けたりとか
授業のプロジェクターの写真分けたりとか

##使い方

これがUIになります
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/0e77b6a6-dd7c-38ba-33dd-54e425450958.png)

開くボタンを押すか画像フォルダをドラッグ＆ドロップで画像が表示されます

画像は、ホイールを回すと画像が次へ前へと移動します。

画像Viewerと使い勝手は同じだと思います
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/a685a29f-595c-05e1-7cd0-6a5d4c34e991.png)

画像を確認しながら、右上のフラグ(ラジオボタン)を自由につけていってください(フラグ名は可変です＆そのままフォルダー名になります)
![画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/468293a4-4914-7f66-7617-264eda6e5c72.png)

![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485495/29d28d3e-8490-ba7a-1e2a-8ba4004663fa.png)
実行画面です

1/27追記：ショートカットキーに対応しました。
画像のフラグ付けは0キー~9キーに対応しています。
画像の次へ、前へはKキーとLキーでも行えます。

**連続分類モード**と**個別分類モード**が存在します

###連続分類モード###
連続分類モードでは、スクロールすると現在のフラグが次の画像にも適応されます。(画像を戻すときには適応されません)
###個別分類モード###
個別分類モードでは、スクロールしても今のフラグは次に適応されません

**ぜひ使ってみて確かめてください**

最後に分類結果を保存するを押すと、新しくwindowが出てきて、保存先のフォルダーを選択します(ドラッグ＆ドロップも可)

結果、そのフォルダーの下に使用したフラグ名のフォルダーができ、そこに画像が入っているのが確認できると思います。

##最後に##
オープンソースなので、改変はご自由に！
再帰関数入門 : 再帰関数とは

## 再帰関数をつくってみる
再帰関数とは、関数の中で自分自身を呼び出す関数のことです。
例えば、以下のコードは再帰関数と言えます。

```rb
def hello
  puts 'hello!'
  hello
end
hello
```
helloという関数の中で、`hello!`という文字列を出力した後に、またhello関数が呼び出されています。
ちなみに上のコードを実行してみると、ただひたすら`hello!`という文字列がずっと出力されます。（rubyだと「SystemStackError」で強制終了されます）

再帰関数を作るというだけだと上記のコードで目的達成ですが、ただ文字列を出力する再帰関数は面白くないので、再帰関数実装の初歩問題として「階乗の計算」を取り上げてみます。
nの階乗を計算するコードを書いてみました。
まずは再帰関数を使わず実装してみます。

```rb
res = 1
while n > 0
  res *= n
  n -= 1
end
puts res
```
こんな感じでしょうか。
またrubyには`times`メソッドという便利なメソッドがあるので、そちらを使うと以下のようになります。

```.rb
res = 1
n.times do |i|
  res *= (i + 1)
end
puts res
```
どちらも`n`に自然数を渡してあげることで階乗を計算することができます。
ではこれを再帰関数で実装してみます。以下のようなコードになります。

```rb
def factorial(n)
  if n == 0
    1
  else
    n * factorial(n - 1)
  end
end
```
`factorial`関数に自然数を渡してあげれば、その階乗の結果を返してくれるプログラムになっています。
慣れていないとどういう処理の流れかが一見わかりづらいので、`n = 3`の場合を例に処理を追ってみます。

`n = 3`を引数として`factional`に渡すと、`if-else`ブロックで`n`が評価されて分岐します。`n = 3`なので`else`の処理が走って、`3 * factional(2)`が返されます。
しかし返り値に`factional`関数を呼び出しているため、ここでも処理が走り、結果が返されます。`factional(2)`は`2 * factional(1)`を返します。
同様にして、`factional(1)`は`1 * factional(0)`を返します。
ここで`factional(0)`は`if-else`ブロックの条件によって`1`を返すことになります。
結果として`factional(3)`は`3 * 2 * 1 * 1`を返すことになり、求めたい答え`3! = 6`を得ることができます。


## 再帰関数のポイント
再帰関数を作る際には、**必ず処理を終わらせる条件**が必要になります。このような条件は**ベースケース**と呼ばれます。
もしベースケースが設定してないと再帰関数は無限ループになってしまいます。無限ループを避けるためにもベースケースは必須です。今回の階乗計算コードでは、「n = 0」の場合がベースケースとなっています。
また**ベースケースにたどり着けるような処理を構築することも重要です。**ベースケースを用意しても、そのベースケースにたどり着かなければ、結局処理が終わりません。
例えば以下のコードだと無限ループになってしまいます。

```rb
def factorial(n)
  if n == 0.5
    1
  else
    n * factorial(n - 1)
  end
end
```
`if`の条件が小数点になっています。nは自然数なので、nが小数になるケースは起こりません。このような例ではベースケースにたどり着けません。

## なぜ再帰関数を学ぶのか
ループ処理を再帰関数で書けるようになると、プログラミングの幅が広がります。また深さ優先探索のようなアルゴリズムを実装する際にも再帰関数の考え方が重要（らしいです。まだ勉強中）です。
今回の階乗計算のような簡単な例だと、むしろ普通のループで実装したほうがわかりやすいように感じてしまいますが、深さ優先探索のようなアルゴリズムを実装するときには再帰関数を使うことでシンプルなコードで実装できるのだと思います。

## 参考
[qiita : 再帰関数を学ぶと、どんな世界が広がるか](https://qiita.com/drken/items/23a4f604fa3f505dd5ad)
【Nuxt.js】iOSでブラウザバックした時、元のスクロール位置に戻らない

（もっといい方法があれば教えて下さい！！🙇）
## 概要
Nuxt.jsプロジェクトで、外部ページに遷移してブラウザバックをしたところ、
画面最上部に戻されてしまったので対策。

## 結論
ホームディレクトリに`app/router.scrollBehavior.js`を追加し、下記のコードを実装

```app/router.scrollBehavior.js
if (process.client) {
  if ('scrollRestoration' in window.history) {
    window.addEventListener('load', () => {
      window.history.scrollRestoration = 'auto'
    })
  }
}
```

## 理由
スクロール位置の復元設定が既存の`router.scrollBehavior.js`で実装されているが、
iosだとbeforeunloadが発火しない。
なので、window.history.scrollRestorationがautoに設定されず、
window.history.scrollRestorationがmanualに設定されているので、ブラウザバック時に画面最上部に戻される。

対策として、常にwindow.history.scrollRestoration = autoになるように実装

```node_modules/@nuxt/vue-app/template/router.scrollBehavior.js
// 7行目〜23行目
if (process.client) {
  if ('scrollRestoration' in window.history) {
    window.history.scrollRestoration = 'manual'

    // reset scrollRestoration to auto when leaving page, allowing page reload
    // and back-navigation from other pages to use the browser to restore the
    // scrolling position.
    window.addEventListener('beforeunload', () => {
      window.history.scrollRestoration = 'auto'
    })

    // Setting scrollRestoration to manual again when returning to this page.
    window.addEventListener('load', () => {
      window.history.scrollRestoration = 'manual'
    })
  }
}
```

## 参考
・[クロール位置の復元](https://lab.syncer.jp/Web/API_Interface/Reference/IDL/History/scrollRestoration/)
・[beforeunloadはiOSで効かない](https://zapanet.info/blog/item/3361)
・[scrollBehavior](https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-router/#scrollbehavior)
rails s を実行しると"A server is already running."のエラーの対処法

rails sを起動しようとすると、このようなエラーが、、、

```
$ rails s -b 0.0.0.0
=> Booting Puma
=> Rails 5.2.4.2 application starting in development 
=> Run `rails server -h` for more startup options
A server is already running. Check /ディレクトリパス/tmp/pids/server.pid.
Exiting
```

これはサーバーがすでに実行中のために起こってしまうエラーです。

##server.pidのPIDをkillする
以下のコマンドを実行しする。

```
$ lsof -i:3000
COMMAND  PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ruby2.5 3033 vagrant   16u  IPv4  27499      0t0  TCP *:3000 (LISTEN)
```

上記のPIDの値を以下の値で削除します。

```
$ kill -9 3033
```
これで解決できます。
Android: kotlinx.serialization 1.0.1

- kotlin: 1.4.10
- kotlinx.serialization: 1.0.1

Jsonのパースをkotlinx.serializationの0.2.0で行っていましたが、Kotlinが1.4になったことにより、いろいろ変わったみたいなのでやり直し。

https://kotlinlang.org/docs/reference/serialization.html

## 導入

build.gradle(app)の記述だけでよくなったようです。

```gradle:build.gradle(app)
plugins {
    id 'org.jetbrains.kotlin.plugin.serialization' version '1.4.10'
}

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1"
}
```

## 実装

テストコードで実行。ドキュメントのサンプルそのままです。

```kotlin
package jp.co.sankosc.jsonsample

import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.junit.Test

@Serializable
data class Data(val a: Int, val b: String)

class ExampleUnitTest {

	@Test
	fun jsonTest() {
		val string = Json.encodeToString(Data(42, "str"))
		println(string)
		val obj = Json.decodeFromString<Data>(string)
		println(obj)

		val dataList = listOf(Data(42, "test1"), Data(12, "test2"))
		val jsonList = Json.encodeToString(dataList)
		println(jsonList)
		val objList = Json.decodeFromString<List<Data>>(jsonList)
		println(objList)
	}
}
```

```bash:実行結果
{"a":42,"b":"str"}
Data(a=42, b=str)
[{"a":42,"b":"test1"},{"a":12,"b":"test2"}]
[Data(a=42, b=test1), Data(a=12, b=test2)]
```
【失敗】Laravelでのテスト時にデータが消えてしまった件について

# はじめに
Laravelで開発中のアプリで、PHPUnitによるテストを実行した際悲劇が起きました。

沢山のエラーとともに、データが全て飛んでしましました。

なんで！？特に設定をいじっていないのに！とかなり焦りました。

# 解決
原因は、テスト実行前に`php artisan config:clear`を行っていなかったからでした。

というのも、Laravelでは設定ファイルをキャッシュして高速化をしている。
そのため、テスト用ではない設定のキャッシュが残っていたことでテスト時にデータが飛んでしまったのかと思います。

確かに公式ドキュメントに、このように記載されていました。
> テスト実行前には、config:clear Artisanコマンドを実行し、設定キャッシュをクリアするのを忘れないでください。
[Laravel 7.x テスト: テストの準備](https://readouble.com/laravel/7.x/ja/testing.html)

# まとめ
今回は、Laravelでのテスト時にデータが消えてしまった際についてまとめました。

幸い、開発環境のデータでかつ個人開発のため問題はなかったです。しかし、仕事中にやってしまった場合かなり焦るかと思いますので勉強になりました。

同じような状況になってしまった方の参考になれば幸いです。
Miracastで使わないノートPCをサブモニターにする方法

社員から、「モニターの余りが無いし使わないノートPCをモニターにできません？」と聞かれたので、今回は『ノートPCは2つ以上あるのに、モニターが少ない時に使える技』を記録します。

##概要
タイトルにもありますが、Windows10の標準搭載のMiracastでノートPCをモニター替わりにします。
Miracastは、Wi-Fiに接続してしている端末に対して画面の転送などができるアプリなのでMiracastを対応しているテレビ等でも同様に可能です。


## 環境条件
この方法は、下記の条件をクリアしないと使えません。
・両方のPCが同じネットワークのWi-Fiに接続されている。
・両方のPCがWindows10 である。


##使用方法
**▼モニター側のノートPC**
　1.スタートメニュー ＞ 接続　をクリック
　　※接続が無い場合は「ワイヤレスディスプレイのインストール方法」を参照
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/97c3f03f-1f9e-f3ed-c979-4cd5fd152c31.png)

　2.「PC名にワイヤレス接続する準備ができました。」と表示されましたら、"モニター側のノートPCの設定"は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/ba52ce41-d7a7-ef42-012e-2d6b4f2ff705.png)


**▼操作するノートPC**
　1.画面右下のアクションセンターをクリックし、接続をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/b64982d7-e073-08fa-77ac-33fa41973593.png)

　2.リストに、"モニター側にするノートPC"の名が表示されているので、接続をする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/718459/7c8feb90-5233-9bba-a13f-c2c865cd8818.png)

##ワイヤレスディスプレイのインストール方法
Windwosのメニューに「接続」が無い場合以下の方法でインストールができます。
※既にインストールされているPCしかない為、文字だけの説明になります。画像付きは、参照URLをご確認ください。。
　1.スタートメニューから「設定」をクリック

　2.『Windwosの設定』画面が表示されたら、アプリと機能　＞　「オプション機能」をクリック

　3.「機能の追加」＞「ワイヤレスディスプレイ」を選択し「インストール」をクリック


##おまけ
Miracastで”モニターになったPC”は、リモートデスクトップのようにウィンドウ上に画面が表示されるので、2人で作業中の情報共有として使用することもできるのかな～

▼参照URL
　役立つ情報の備忘録
　https://bibouroku.net/juc700#toc4
【PHP】Carbon で 「YYYY-MM-DDTHH:MM:SSZ」の形式で強制的にUTC時刻にされてしまう罠"

# 概要
PHPのCarbonを使用した際に日付形式「YYYY-MM-DDTHH:MM:SSZ」（ISO 8601）の場合にある罠。

[Carbon](https://carbon.nesbot.com/)
[ISO 8601](https://ja.wikipedia.org/wiki/ISO_8601)

# サンプル
使用するCarbonのコンストラクタです。

>Carbon::__construct
>$time = null, $tz = null
>Create a new Carbon instance.

## サンプルコード（失敗編）
```php
<?php
echo (new Carbon('2020-11-05T12:34:56Z'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56Z', 'UTC'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56Z', 'Asia/Tokyo'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56Z', 'America/Vancouver'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
```

結果は何故か全て同じ…

## サンプルコード（成功編）
```php
<?php
echo (new Carbon('2020-11-05T12:34:56Z'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56Z'))->timezone('UTC')->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56Z'))->timezone('Asia/Tokyo')->toString();
// Thu Nov 05 2020 21:34:56 GMT+0900
echo (new Carbon('2020-11-05T12:34:56Z'))->timezone('America/Vancouver')->toString();
// Thu Nov 05 2020 04:34:56 GMT-0800

```

タイムゾーンを設定することで正確な時間の取得が可能になりました。

## 原因
末尾の「Z」を削除すると普通にタイムゾーンごとの結果が受け取れます。

```php
<?php
echo (new Carbon('2020-11-05T12:34:56'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56', 'UTC'))->toString();
// Thu Nov 05 2020 12:34:56 GMT+0000
echo (new Carbon('2020-11-05T12:34:56', 'Asia/Tokyo'))->toString();
// Thu Nov 05 2020 21:34:56 GMT+0900
echo (new Carbon('2020-11-05T12:34:56', 'America/Vancouver'))->toString();
// Thu Nov 05 2020 04:34:56 GMT-0800
```

可能性ですがおそらく、内部処理的にはタイムゾーン設定後に日時の設定を行っているようです。
そのため、末尾にZが着いていると以下の処理を行っているものと考えられます。

1.タイムゾーンを設定
2.日時の末尾にZが付いてる
3.タイムゾーンはUTCの時間

最後にCarbonはPHPの [DateTime class](https://www.php.net/manual/en/class.datetime.php) を拡張しているので DateTimeクラスを使用していれば、おそらく同様の現象が発生すると思います。
（未確認）
【Docker】Docker run時の基本的なオプション(共有、ユーザ、ポート、CPU/メモリ)の紹介

Docker run時に指定できる基本的なオプションの紹介をします。

#ファイルシステムの共有
コンテナをあまり大きくしないようにするためになるべくコンテナ側にファイルをおかないようにすることが重要です。そういった時にホストのファイルをコンテナにマウントすることができる-vオプションを使います。書き方は下記の通りです。

###-v オプションの指定の仕方
`-v <host>:<container>`
#####ex.ホストの~/Desktop/to_containerフォルダをコンテナ側の/host_folderフォルダへマウントする場合
`docker run -it -v ~/Desktop/to_container:/host_folder <image> bash`
※コンテナ側のhost_folderはDockerfileでRUN mkdierを記述してディレクトリを作成しておかなくても共有先のディレクトリに指定するだけで作成してくれます。

#ファイルへのアクセス権限 [-u]
ファイルシステムを共有することによってコンテナからホストのファイルシステムにアクセスできるようになります。コンテナは特に指定しない場合はrootで実行している状態になります。
そのままホスト側にアクセスするとよろしくないのでアクセス権限を設定する必要があります。
自分のユーザid、ユーザグループを指定して実行ユーザを指定してコンテナを実行するとroot権限以外のユーザでコンテナ内を操作することができるようにコンテナを作成することができます。

###-u オプションの指定の仕方
`-u 501:20`
ただこのように毎回ユーザid,ユーザグループを調べてコマンドを実行するのは面倒なので、ユーザid,グループを実行してrunできるように記述すると便利です。
`-u $(id -u):$(id -g)`
$()のなかにlinuxコマンドを入れるとその実行結果を使用してコマンドを実行してくれます。実際にrunしてbashを実行すると下記のようにユーザが表示されていると思います。
`I have no name!@<serial>`

コンテナ上に501などのユーザがないことが原因ですので、適宜ユーザを作成しておくと正しいユーザ名で表示されるようになります。

※自分のパソコン内だけで実行する場合は、それほどナーバスになる必要もない部分だと思いますが、共有環境な内で実行する場合などに有効なオプションです。。


#ポートをつなげる
コンテナを複数立てる場合、ホストのポートとコンテナのポートを紐づけておかないとアクセスできません。
記述方法は今まで紹介したものとあまり変わらず、下記の通りです。

###-p オプションの指定の仕方
`-p <hostのポート>:<containerのポート>`

#コンピュータリソースの上限の設定
ホストのCPU、メモリを使い切らないように設定しないとリソースが枯渇することがおきます。そうならないための上限設定のオプションが存在します。

###オプションの指定の仕方
`-cpus <コア数> --memory <メモリ容量byte>`

ex.2つのコア、4Gのメモリの上限を設定してコンテナを立ち上げる。
`docker run --cpus 2 --memory 4g <イメージ> bash`

#コンテナの情報を表示する
コンテナのid、作られた時間、環境変数、割り当てられたCPU、メモリを確認することができます。そのコマンドは下記です。
`docker inspect <コンテナID>`

上記コマンドに`| grep -i cpu`、`| grep -i memory`をつなげて設定を確認してみてください。


今回は以上です。
【Docker】その他のよく使う(と思われる)Docker Instructions

続いては今回はCOPY, ADD, CMD, ENTRYPOINT, ENV, WORKDIRの紹介です。


## COPY
ホストからファイルをコンテナに渡す時に使います。

```docker:記述の仕方
COPY <コピーするファイル名> <コンテナ内のコピー先ディレクトリ>
```
簡単な例ですが、ubuntuのOSでディレクトリを作ってファイルをコピーする場合の記述です。

```docker:Dockerfile
FROM ubuntu:latest
RUN mkdir /test_dir
COPY hoge.txt /test_dir
```
もう一つファイルをコンテナに追加するコマンドとして`ADD`というものが存在します。
##  ADD
ファイルやフォルダをコンテナにコピーすることができるコマンドですが、`COPY`と決定的に違う点があります。**tarの圧縮ファイルをコピー＋解凍する**ことができます。
ファイルが重かったり、フォルダ階層で転送するサイズが大きいものをそのままコンテナに渡すと、コンテナに渡すだけでも時間がかかります。そう言った場合にtarで圧縮してコンテナにコピーする際に`ADD`で記述すると送信自体も早く済み、解凍された状態で展開されます。

```docker:記述の仕方
ADD <コピーする圧縮されたファイル名> <コンテナ内のコピー先ディレクトリ>
```
COPYと違うのはファイルが圧縮されているかどうかだけなので例は割愛します。

## ENTRYPOINT
`CMD`と同じようにdocker run時に最後に実行するコマンドを指定する。
`CMD`はdocker run時にコマンドを上書きすることができますが、`ENTRYPOINT`は最後のコマンドを上書きできません。
記述の仕方は`CMD`は["コマンド"(, "引数1", "引数2")]のように引数も続けて指定しましたが、`ENTRYPOINT`はコマンドのみを指定し、その引数は`CMD`を使って指定します。
**`ENTRYPOINT`はコマンドは変更できませんが、`CMD`で指定している引数部分は上書きができます。**

```docker:CMDの場合の記述の仕方
FROM ubuntu:latest
CMD ["コマンド", "引数1", "引数2"]
```

```docker:ENTRYPOINTの場合の記述の仕方
FROM ubuntu:latest
ENTRYPOINT ["コマンド"]
CMD ["引数1", "引数2"]
```

基本的には`CMD`だけで事足りると思います。

## ENV
環境変数を設定できます。記述の仕方としてはいろいろあります。下記3つ目の例のように複数並べての記述も可能です。

```docker:記述の仕方
ENV key1 val
ENV key2=val
ENV key3=val3 key3=val3
```
複数を一度に記述する場合で環境変数値(上記のval)に半角スペースがある時はダブルクォーテーションで括るか、エスケープすることで設定できます。

```docker:複数ENVの設定を一行で記述の仕方
ENV key4="v a l 4" key5=v\ a\ l\ 5
```
１行だけの場合は下記のように記述することもできます。

```docker:一つのENVでスペースまじりの環境変数設定の記述の仕方
ENV key6 v a l 6
```

これでコンテナ内でパスを通す、などの作業ができるようになります。

## WORKDIR
Dockerfileに記述した`RUN`で実行しているコマンドを実行するディレクトリを変更することができます。

```docker:記述の仕方
WORKDIR 絶対パス
```

`cd`だと`RUN`するたびにルートに戻るので作業ディレクトリを固定して`RUN`実行したい時に`WORKDIR`を使ってディレクトリ移動してください。。

## おしまい
今回のコマンドで基本的なDocker instructionについての紹介は終わりです。前回の紹介したコマンドと合わせることでおおよそ頻繁に使うコマンドについては網羅できているかと思います。
Docker、便利なんでぜひお試しください。
CSSのhoverで別の要素を変化させる場合

## ■ はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・CSSの基礎知識が増える
・hoverした要素以外を変化させる方法

## ■ 例

例えば、2つのクラスがあって、<font color=red>a.category</font>にマウスを乗せたら.<font color=green>a.title</font>に下線を出したいと思った時

![スクリーンショット 2020-11-05 13.03.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/9b1e3fda-bced-6c15-3bae-ee542c1dd7d0.png)

```scss:index.scss
a.category:hover + a.title {
  border-bottom: 1px solid #47b39d;
  }
```

実際に<font color=red>マウスを乗せるクラス</font>と<font color=green>下線を出すクラス</font>の間にプラスでつなぐと

![7929cd178e4b95e1a9597121ea08e1d9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/0e10f7ee-6396-831c-05ba-0e560edacb88.gif)

この様に、<font color=red>a.category</font>にマウスを乗せたら.<font color=green>a.title</font>に下線を出すことができます
raile newでPostgreSQL関連エラーのトラブルシューティング

## 環境
Vagrant + Ubuntu 16.04.5 LTS
Rails 5.2.4.2

## やった事

DBにpostgresqlを指定して、rails newをすると、エラーが出てきてしまいました。

```cmd
$rails new test_postgre -d postgresql
Fetching pg 1.1.4
Installing pg 1.1.4 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

    current directory: /home/vagrant/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/pg-1.1.4/ext
/home/vagrant/.rbenv/versions/2.5.1/bin/ruby -r ./siteconf20190920-2701-1dz6d99.rb extconf.rb
checking for pg_config... yes
Using config values from /usr/bin/pg_config
You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for
building a client-side application.
You need to install postgresql-server-dev-X.Y for building a server-side extension or libpq-dev for
building a client-side application.
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/home/vagrant/.rbenv/versions/2.5.1/bin/$(RUBY_BASE_NAME)
        --with-pg
        --without-pg
        --enable-windows-cross
        --disable-windows-cross
        --with-pg-config
        --without-pg-config
        --with-pg_config
        --without-pg_config
        --with-pg-dir
        --without-pg-dir
        --with-pg-include
        --without-pg-include=${pg-dir}/include
        --with-pg-lib
        --without-pg-lib=${pg-dir}/lib

To see why this extension failed to compile, please check the mkmf.log which can be found here:

/home/vagrant/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/pg-1.1.4/mkmf.log

extconf failed, exit code 1

Gem files will remain installed in
/home/vagrant/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/pg-1.1.4 for inspection.
Results logged to
/home/vagrant/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/extensions/x86_64-linux/2.5.0-static/pg-1.1.4/gem_make.out

An error occurred while installing pg (1.1.4), and Bundler cannot continue.
Make sure that `gem install pg -v '1.1.4' --source 'https://rubygems.org/'` succeeds before
bundling.

In Gemfile:
  pg
         run  bundle exec spring binstub --all
Could not find gem 'pg (< 2.0, >= 0.18)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```

どうも、libpq-dev関連のエラーっぽい。
libpq-devとは、PostgreSQLを使う時は必須になるライブラリーのようです。

libpq-devの最新版をインストールすると回避できました。
インストールには相当時間がかかります。:sweat:

```
$sudo apt install libpq-dev
```

参考記事
http://smot93516.hatenablog.jp/entry/2018/10/05/152936
Mockery\Exception\BadMethodCallException: Received 自分の関数(), but no expectations were specified

表題のエラーにハマったので共有します。

# 背景
Repositoryにアクセスが必要なメソッドを書いたあと、全体テストをしていました。
おかしなことに、自分のテストではなく他人の書いたMockを使ったテストが落ちました。
ちなみに自分のコードではMockを使っていませんし、完全に独立したメソッドを書いていたはずなのに。。。

```CorrectLoadFactorCommand.php
public function __construct(ShopRepository $shop_repository)
    {
        parent::__construct();
        $this->shop_repository = $shop_repository;
        $this->occurrence_day = today()->day;
        $this->target_measuring_day = today()->subDay(2)->day;
        $this->target_day_end_of_month = today()->subDay(2)->endOfMonth()->day;
        $this->fetched_cn_cds = $this->fetchLoadFactorCnCds($this->occurrence_day, $this->target_measuring_day, $this->target_day_end_of_month);
    }

    /**
     * 今日から2日前の検査日の店舗一覧を取得する。
     * @param int $occurrence_day
     * @param int $target_measuring_day
     * @param int $target_day_end_of_month
     * @return string
     */
    private function fetchLoadFactorCnCds(int $occurrence_day, int $target_measuring_day, int $target_day_end_of_month): string
    {
        //　省略

        return
            $this->shop_repository
                ->fetchLoadFactorCnCds($target_day_list)
                ->implode(',');
```

```ShopRepository.php
    /**
     *
     * @param array $target_date_list
     * @return Collection
     */
    public function fetchLoadFactorCnCds(array $target_date_list): Collection;
```

```EloquentShopRepository.php 
public function fetchLoadFactorCnCds(array $target_date_list): Collection
    {
        return $this->shop
            ->with('eSettings')
            ->join('e_settings', 'stores.cn_cd', 'e_settings.cn_cd')
            ->where('status_id', '=', 1)
            ->where('e_contract_id', '=', 70)
            ->whereIn('measuring_date', $target_date_list)
            ->pluck('stores.cn_cd');
    }
```

# 試行１（返り値や引数の型）
もしかしたらno expectations were specifiedと言われるので、返り値指定や
引数指定がされてないのかと思ったがハズレ。
nullが返ってくる様なこともなく、期待通りCollectionでした。


# 試行２（config:clear）
https://qiita.com/tkek321/items/26d420215b92a1d98e95
こちらにconfig:clearで動くとあったので、やってみましたが関係ありませんでした。

# 試行３（$this->fetched_cn_cdsをローカル変数化）
コンストラクタで読んでいるのを、ローカル変数に変更して呼び出す様変更しました。

```CorrectLoadFactorCommand.php
public function handle()
    {
        $logger = new BatchLogger(array_slice(explode('\\', get_class($this)), -1)[0]);
        $fetched_cn_cds = $this->fetchLoadFactorCnCds($this->occurrence_day, $this->target_measuring_day, $this->target_day_end_of_month);
    // 省略
    }
```

テストが通る様になりました！
おそらく他人の書いたMock呼び出し部分で、DBを参照をコンストラクタで
呼び出されると不都合なことになるのでしょう。
Shopify Liquid言語

#Liquid言語について
Rubyをもとに作られているShopify独自の言語。:ring::sparkles:
HTMLでいつも変わらない部分（静的）が書かれて、場合によって変わる部分（動的）はLiquidで書かれる
`{{ }}`で区切って出力を表す。PHPのecho的なやつ
`{% %}`でロジックと制御フロー・・・if文とかforはこれで書く


##オブジェクト
管理画面からデータを出力。オブジェクトは各プロパティのリストを持ってる。
たとえば、product(製品)オブジェクトなら製品１、製品２・・・などのリストを持っていて、それぞれに設定されているtitleとかを`{{product.title}}`で表示できる。
Shopifyのストア内で同じテンプレートをつかっていたとしても、それぞれのtitleが出力される。

##タグ
・コントロールフロータグ
・イテレーションタグ
・テーマタグ
・バリアブルタグ　変数タグ
などがある

##フィルター
数値、文字列、オブジェクト、変数の出力を変更するために使用され、
`{{ | }} `で表される（パイプ文字）
例えば、capitalize （大文字にする）remove（外す）
capitalizeは１文字目を大文字にしてくれる。:point_up_tone2:

```
{{ ‘hello,world!’  | capitalize}}　　　→(出力結果) Hello,world!
{{ ‘hello,world!’  | capitalize  | remove: "world" }}   →(出力結果) Hello,!
```

他にもいろいろなフィルターがある。

###contains
特定の文字列を含んでいるか検索する。:eyes:
配列の中にあるオブジェクトに対しては検索かけられない:no_good_tone1:

```liquid
{% if 	customer.email contains “@gmail.com” %}
<h1>こんにちはgmailユーザー！</h1>
{% endif %}
```


#参考
[Shopify Developers-Getting started with the Liquid markup language-](https://shopify.dev/docs/themes/getting-started)
Shopify公式さん（英語）

#おまけ
続編として、[liquidのasset_urlフィルタについて](https://qiita.com/aliceroot0678/items/0115d5544ca321dd787a)を書いたのでよろしければ。
zsh環境のAnacondaをアンインストールする

# やること

以前`Jupyter Notebook`学習用にインストールした `Anaconda`環境がいらなくなったので、
アンインストールしていきます。

今後しばらくはPython環境を`pyenv`と`pipenv`で管理するようにするので、その前提のお片付けです。

zsh環境といってもやることはbashと一緒です。

# 手順
Step1: `anaconda-clean`をインストール
Step2: `anaconda-clean`を実行
Step3: ライブラリの実体をフォルダごと削除
Step4: zsh, bashに通っていたパスを削除


## Step1: `anaconda-clean`をインストール
condaのライブラリが生成したデータファイルを自動で削除を行うパッケージをインストールします。

```:$
conda install anaconda-clean
```

途中インストールしてもいいか確認がでるので `y`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/d5de3e1c-ec29-bcb9-2046-e2720c980fc5.png)
バックアップファイルも不要な場合、削除します。

```:$
rm -rf ~/.anaconda_backup
```

## Step2: `anaconda-clean`を実行

```:$
conda install anaconda-clean
```

確認がでますが、今回はどのファイルも残さないためすべて `y`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/6319c02c-e8ee-c745-053a-946344886e8a.png)
試しに`python`で確認するとまだパスが通っているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/a27d244f-61f8-9dbe-bcf8-db075bb06c19.png)

## Step3: ライブラリの実体をフォルダごと削除
私の環境ではユーザー/opt以下にインストールしていたため以下を削除

```:$
rm -rf ~/opt/anaconda3
```

削除後、再び`python`コマンドで確認すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/c58a6aac-6f2c-2933-6d1e-e72915b0069f.png)
デフォルトのものだけになっています。

## Step4: zsh, bashに通っていたパスを削除
今回はzshを使っていたため`~/.zshrc`の該当行を削除

```:~/.zshrc
export PATH="$HOME/opt/anaconda3/bin:$PATH"
```
bashの場合は、`~/.bash_profile`の該当行を削除

```:~/.bash_profile
export PATH="$HOME/opt/anaconda3/bin:$PATH"
```

# おわり
綺麗になりました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331415/8b5cd144-d2a8-86ee-aabc-2c1e120cdab7.png)


---
また`Anaconda`使うことがあったらヨロシク！🐍
競プロに興味のある方へ。AtCoderの始め方

# はじめに
今回はAtCoder (競技プログラミング) を始めてみようかなという方に向けて

- AtCoderとは、どういうものか
- コンテスト参加前にすると良いこと
- 効率が良いテストの解答方法

を紹介していきます！

動画も用意してます！
[【YouTube動画】 観てはいけない。AtCoder沼から戻れなくなります。](https://youtu.be/vxBOC08XZ44)
[![Collation](https://img.youtube.com/vi/vxBOC08XZ44/0.jpg)](https://www.youtube.com/watch?v=vxBOC08XZ44)

# そもそも競技プログラミングって？
制限時間内に、どれだけ速く正確に問題を解けるかを競います。
また、競技**プログラミング**とある通り、プログラムを提出する必要があります。

提出したプログラムにサンプルデータを入れテストしますが、プログラムが処理する時間や消費するメモリも考慮され、正解かどうか判断されます。

そんな競技プログラミングで求められる能力は

- アルゴリズムをうまく扱う能力
- 数学的な特性を理解する能力
- コーディング能力

です。
やっていくうちに、鍛えられると思うので、めげずに挑戦してみてください！

# AtCoder
AtCoderは日本語の問題文を利用でき、開催頻度が高い競技プログラミングコンテストです。
だいたい、土曜日か日曜日の21時から開催されます。


https://atcoder.jp
![スクリーンショット 2020-11-05 10.10.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/e99eacef-6b19-6fe7-350a-9d361f0de02c.png)

## ランク
AtCoderに参加すると、コンテストの成績に応じて、レーティングが変化します。
レーティングは灰、茶、緑、水、青、黄、橙、赤の8種類あります。

ただ、始めたての場合、灰色になります。
AtCoderではリセマラ防止のため、初回5回のレーティングは上がりにくくなってます。
めげずに続けましょう！

上位50%になると、茶色になります。
ここまでいくと、脱初心者という感じです。

さらにランクを上げていくと、緑色、水色、青色になっていきます。
緑はAtCoderの第一関門で、青色までいけたら十分すごいです。

それより先の黄、橙、赤は天才の域です！
どうやったらいけるんでしょうね。


chokudaiさんによるランクの目安もあるので、興味のある方はこちらもどうぞ。
http://chokudai.hatenablog.com/entry/2019/02/11/155904

# AtCoderの始め方
AtCoderにいきなり参加すると、撃沈します。

こちらのサイトで過去問と自分が解いた問題を確認できます。
https://kenkoooo.com/atcoder#/table

このような感じで問題に色が付いてるので、灰色から解き尽くすとやりやすいです。
ログインすると、自身が解いた問題やどの期間問題を解き続けているかが表示されるようになります。
![スクリーンショット 2020-11-05 11.04.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/754ecff1-0563-0653-ba03-4407cd4986d3.png)



# AtCoderで効率的に問題を解くために

AtCoderでは、以下のようなテキストボックスに、プログラムを貼り付けて提出します。

![スクリーンショット 2020-11-05 11.48.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751408/19a4c306-5da6-0300-2c91-e7f854340ff7.png)

しかし、ローカルで実験して、コード貼り付けて提出って面倒ですよね。
どうせなら、ローカルで実験して、そのままコードを提出できるようにしたいですよね。

## AtCoder CLI

そのためのツールが有志の方により提供されています！
めちゃくちゃ便利です。
https://github.com/Tatamo/atcoder-cli


# まとめ
AtCoderの始め方に関する記事は以下も良さそうです。

- [AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)
- [レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編：競プロを始めよう】](https://qiita.com/e869120/items/f1c6f98364d1443148b3)


では、快適なコーディングライフを。
Firebaseメソッドの返り値を知りたければ、Firebase API Referenceを活用しよう！！ 

Firebaseを使っていて、もしくはfirebaseを使ったアプリなどの作成の解説動画や記事をみていると、いきなり、

「`createUserWithEmailAndPassword`はuserを返すので、」
とか、
「`get`はsnapshotを返すので」

のようなことを言われて、Firebase初心者だと、「なんで？？」ってなることが多かったので、この記事を作成しました。

## 結論：Firebase API Referenceに全部書いてあった🤣

まずは結論から言ってしまいますが、[Firebase API Reference](https://firebase.google.com/docs/reference?hl=ja)に全て書いてあります。

これはFirebaseの公式ドキュメントの一部なのですが、残念ながら現時点(2020年11月)では日本語化はされておらず、英語のみとなっています。しかしながら、以下の画像ように説明は英語ですが、メソッドごとに取る引数やその型、返り値などが実際のコードのような形で書かれているので、英語が苦手な方でも理解しやすいと思います。
![スクリーンショット 2020-11-05 12.38.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/f61622b8-2956-2b6a-f1bd-bbbf613b288d.png)

例えば、冒頭で例にあげた、`createUserWithEmailAndPassword`が`user`を返すのをどうやって知るのか、というと、

![スクリーンショット 2020-11-05 12.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/3226b94a-b9ec-12dc-156c-138fc639ccf1.png)

まずは、該当のメソッドのところまで行って、返り値を確認します。
今回は`Promise <UserCredential>`となっている！

つまり、ユーザーの作成が完了した段階で`UserCredential`が返ってくることになります。

で、`UserCredential`とはなんぞやというと、そのリンク先を見ればわかるわけです。
早速みてみましょう。

![スクリーンショット 2020-11-05 12.53.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/dc2cca59-0af8-aed4-bf0d-a49e86662a0a.png)

ここに`user`がありました！！

## まとめ

というわけで、もう一度この例を振り返ってまとめてみると、

1. 返り値や引数がわからない🤔
2.  [Firebase API Reference](https://firebase.google.com/docs/reference?hl=ja)を開いて、該当のメソッドを見つける
3.  引数、返り値を確認
4.  引数、返り値のより詳細な情報を知りたい場合はそれらをクリック
5.  Happyになる🙆‍♀️🙆‍♂️

ちなみに、最近は翻訳技術がすごくなってきているので、翻訳機能使って訳しつつ読むのも良いかもしれません。[DeepL](https://www.deepl.com/ja/translator)がおすすめです。
SQLでデータ集約やグループ化を行なう

### はじめに
SQL学習のために備忘録として、残しております

### データを集約する

関数を用いてSELECT文で取り出したレコードの結果をまとめる

#### 集約関数

SQLでも計算を行う為の**集約関数**が用意されている
計算を行う事で、SELECT文で取り出した結果をまとめることができる

| 関数名 | 説明 |
| --- | --- |
| AVG | カラムがNULLでないレコード数を計算する<br>カラム名に「＊」を指定すると、NULL値を含めてテーブルの全レコードを計算する<br>COUNT(DISTINCT カラム名)で重複値を排除したレコードを計算する |
| MAX | カラムの最大値を計算する |
| MIN | カラムの最小値を計算する |
| SUM | カラムの合計値を計算する |

集約関数ではレコードのグループ単位で計算を行い、1つの結果を返す

`SELECT SUM(計算したいカラム名) FROM 対象のテーブル名;`

### 抽出データをグループ化

一つのテーブル内にあるレコードを複数のグループごとに分割する事を**グループ化**という

`SELECT 取得したいカラム数 FROM 対象とするテーブル名 (WHERE 取得したいカラムの条件) GROUP BY グループ化したいカラム名;`

### グループ化した結果に条件を指定して絞り込む

WHERE句は条件を与えて抽出するレコードを絞り込めるが、グループ化したグループに対して条件を設定できない。
そこでグループ化されて抽出されたレコードに対して条件を設定して絞り込むには、**HAVING句**を使用する

`SELECT 取得したいカラム FROM 対象とするテーブル (WHERE 取得したいレコードの条件) GROUP BY グループ化したいカラム名 HAVING 取得したいグループの条件;`

HAVING句には、取得したいグループの条件として、**集約関数を条件に含める**ことができる

**※重要**
WHERE句とHAVING句は性質が似ているため混同されがちである
ここで抑えておきたいポイントは、**WHERE句はSELECT句に対する絞り込み条件を設定する際に使われ、HAVING句はGROUP BY句に対する絞り込み条件を設定する際に使われる**
【Python】（線）グラフの画像から値を抽出する

#はじめに
グラフの画像はあるけどデータはない...ってことありませんか？
画像があるなら抽出しましょう。

[![image.png](https://pandas.pydata.org/pandas-docs/version/0.7.3/_images/frame_plot_basic_noleg.png)](https://pandas.pydata.org/pandas-docs/version/0.7.3/visualization.html)
[pandas 0.7.3 documentation -Plotting with matplotlib](https://pandas.pydata.org/pandas-docs/version/0.7.3/visualization.html)
　　　　　　　　　　　　$\downarrow$
array([-0.4028436 , -0.09518499,  0.21247362, ..., 39.12322275, 39.12322275, 39.12322275])
　　　　　　　　　　　　＋
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501281/9489bc94-f0fb-b02b-777b-942a617e5a2b.png)

↑ ~~これだけ細かいとあまり精度は望めない。。。~~

#処理の流れ
色域選択で目的のグラフを取得
　　↓
縦軸方向に平均
　　↓
欲しいサンプル数分補間
　　↓
スケール調節
　　↓
出力

#実装
[**こちらからColabで実行出来ます**](https://colab.research.google.com/github/Cartelet0423/graph_image2value/blob/main/graph_image2value.ipynb)

```python
import numpy as np
import matplotlib.pyplot as plt
from ipywidgets import interact
import requests
from PIL import Image
import io
```
### 画像データの取得、とりあえずアルファは無視

```python
path = "画像のパス"
im = plt.imread(path)
if im.shape[2] == 4:im = im[:,:,:-1]
if im.max() > 1:im /= 255
h, w, _ = im.shape
plt.imshow(im[::-1])
```

### 後のスケール調節用にグラフの範囲のみトリミング

```python
@interact(x_min=(0, w), x_max=(0, w), y_min=(0,h), y_max=(0,h))
def Plot(x_min=0, x_max=w, y_min=0, y_max=h):
    global imag
    plt.figure(figsize=(7, 7))
    imag = im[min(y_min,y_max-1):max(y_min+1, y_max), min(x_min,x_max-1):max(x_min+1, x_max)]
    plt.imshow(imag[::-1])
```

### 色域選択で抽出したいグラフを選択, Threshold(閾値)を調節して無駄な部分が入らないようにする

```python
@interact(x=(0, imag.shape[1]), y=(0,imag.shape[0]), thresh=(1,10))
def Plot(x, y, thresh):
    global p
    p = ((imag - imag[y, x]) ** 2).sum(axis=2) < (1 / (1<<thresh))
    print(p.sum())
    plt.imshow(p[::-1])
    plt.plot([x, x], [0, imag.shape[0]], color="r")
    plt.plot([0, imag.shape[1]], [imag.shape[0]-y, imag.shape[0]-y], color="r")
```
### 縦軸方向に平均を取る

```python
p = np.pad(p, 1, "constant")
sx = np.arange(len(p[0]))[p.argmax(axis=0)!=0]
sy = []

for i in p.T:
    j = np.where(i!=0)[0]
    if j.tolist():
        sy.append(j.mean())
```
### サンプル数の選択, 移動平均（畳み込み）でノイズの除去

```python
@interact(sample=(5, 1250), conv_size=(1, 21, 2))
def fit(sample, conv_size):
    global y
    x = np.linspace(sx.min(), sx.max(), sample)
    y = np.convolve(np.pad(np.interp(x, sx, sy), (conv_size-1)//2, "edge"), np.ones(conv_size) / conv_size, "valid")
    plt.plot(x, y)
    plt.xlim(0,len(p[0]))
    plt.ylim(0, len(p))
```
### 最初に切り取ったグラフの範囲を入力

```python
yl = list(map(int,input("Y-range of trimmed graph?         ").split(",")))
```
### スケール調整, 出力

```python
y_out = y * (yl[1] - yl[0]) / p.shape[0] + yl[0]
y_out
```
### グラフ出力

```python
plt.plot(y_out)
plt.ylim(*yl)
```
↑ はJupyter用のプログラムなので分けてある部分でセルを区切らないと実行出来ません

#さいごに
HTMLとか使ってトリミングとか色域選択をもっとインタラクティブにしたら使い勝手が良くなりそう。
AWS〜VPCでネットワークを構築する②〜

# この記事を読んでできるようになること
AWSで**VPCを作成し、ネットワークを構築**することができる。
# 記事を読むにあたってのお願い
私は**AWSの初学者**で、アウトプットをすることで知識を定着させるためにこの記事を書いています。内容に誤りがある場合は、コメントをいただけますと幸いです。
`学習に使用した教材`
AWS：ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得
https://www.udemy.com/course/aws-and-infra/
# 今回作成するもの
![スクリーンショット 2020-11-05 10.44.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/047ec065-42e1-20ed-7001-e048564f9ce9.png)
①VPC･･･AWSから家（サービス）を建てる土地（プライベートクラウド）をレンタルするイメージ
②パブリックサブネット･･･①で借りた土地に建てる家のイメージ（玄関がインターネットゲートウェイ※）
③プライベートサブネット･･･家の2階部分または地下のイメージ（パブリックサブネットからしかアクセスできない）
※インターネットとつながるところ
# VPCの作成
AWS マネジメントコンソールにログインしている前提で説明します。
⓪AWSユーザーネーム右のリージョンが東京になっていることを確認
（なっていない場合は`アジアパシフィック東京`を選択）
①左上のサービスから`VPC`を選択
②VPCダッシュボードから`VPC`をクリック
③`VPCを作成`（オレンジのボタン）をクリック
④画像のように入力し、`VPCを作成`をクリック（赤枠のところは好きな名前でいいです）
![スクリーンショット 2020-11-04 16.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/c7b9f995-5759-00e4-02e5-83926866ed8d.png)
⑤VPC画面のお使いのVPCに先ほど作成したVPCが存在することを確認
# サブネットの作成
①VPCダッシュボードから`サブネット`をクリック
②`サブネットの作成`（ブルーのボタン）をクリック
③画像のように入力し、`作成`をクリック（名前タグは好きな名前でいいです）
![スクリーンショット 2020-11-04 17.00.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/86f56a81-cfec-03c2-ebe1-56de3b09123c.png)
④サブネット画面に先ほど作成したサブネットが存在することを確認
⑤もう一つサブネットを作成（IPv4 CIDR ブロックは「10.0.20.0/24」で作成）
# インターネットゲートウェイの作成
①VPCダッシュボードから`インターネットゲートウェイ`をクリック
②`インターネットゲートウェイの作成`（オレンジのボタン）をクリック
③名前タグに好きな名前を入力し、`インターネットゲートウェイの作成`をクリック
![スクリーンショット 2020-11-05 11.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/72cdcadb-809e-c295-051c-db6322a590c4.png)
④インターネットゲートウェイ画面で、先ほど作成したインターネットゲートウェイを選択（「Name」の左隣のチェックボックスをクリック）
⑤`アクションボタン`より`VPCにアタッチ`を選択
⑥使用可能なVPCで先ほど作成したVPCを選択し、`インターネットゲートウェイのアタッチ`をクリック
![スクリーンショット 2020-11-04 17.04.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/4697c43e-96e9-cc83-2059-e68e06440df9.png)
⑦「状態」が"✅Attached"になっていることを確認
# ルートテーブルの作成
①VPCダッシュボードから`ルートテーブル`をクリック
②`ルートテーブルの作成`（ブルーのボタン）をクリック
③画像のように入力し、`作成`をクリック
![スクリーンショット 2020-11-04 17.06.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/8a4455fa-8afd-93c5-f295-618863b95493.png)
④ルートテーブル画面で、先ほど作成したルートテーブルを選択（「Name」の左隣のチェックボックスをクリック）
⑤画面下の「サブネットの関連付け」を選択し、`サブネットの関連付けの編集`をクリック
⑥インターネットに接続する予定のサブネット（パブリックサブネット）を選択し、`保存`をクリック
⑦画面下の「ルート」を選択し、`ルートの編集`をクリック
⑧`ルートの追加`を選択し、画像のように入力後、`ルートの保存`をクリック
![スクリーンショット 2020-11-04 17.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/807318/5b3d2607-ed04-bb89-4888-1c045231aaab.png)
**VPCの作成とネットワークの構築**は以上となります。

次回は、**EC2でWebサーバを構築**していきたいと思います。
iOS/Androidアプリの新バージョンを指定のタイミングで公開する方法

## 導入
iOSやAndroid等のアプリ開発をしていると、両プラットフォームで同時リリースしたいかと思います。
しかし、デフォルトでは審査完了と同時にリリースされてしまうという問題がありましたので、自分のタイミングで公開する方法を調べてみました。

## 手順
### iOSの場合
iOSは非常にわかりやすく、審査用のリリースを作成する際に、選択肢として表示されています。

【手順】
1. App Connectからアプリのリリースを作成する
2. 「バージョンのリリース」にて、設定を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91900/f3318179-be7f-cb64-d4b2-1d05ce7b100e.png)

- 手動リリース：審査完了後に、「このバージョンをリリース」というボタンが表示され、手動で公開できます。
- 自動リリース：審査完了次第、自動で公開されます。
- 次の日付で自動リリース：審査完了後、設定日に公開されます。(審査完了日が設定日より遅くなった場合は、完了次第公開されます)


### Androidの場合
Androidは少しわかりづらく、別のメニューになっています。

【手順】
1. メニューから「公開の概要」を選択する
2. 管理をクリック
3. 「管理対象の公開をオンにする」を選択
4. 審査が完了次第、「変更の公開準備完了」にストックされるので、好きなタイミングで「確認して公開」ボタンをクリックし、リリースする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91900/a144e026-0682-22ce-f34c-ebc7a8ef04cc.png)

## 終わりに
以上、モバイルアプリのちょっとしたTipsでした！
[Java]HTTPヘッダのfilenameに日本語名ファイルを返す

`日本語_1.tsv` をダウンロードさせようとすると、 `_1.tsv` になってしまった。日本語でダウンロードさせるにはURLエンコードが必要になってくる

Spark のレスポンスヘッダに埋め込む例

```java
    Spark.res.header("Content-disposition", "attachment; filename=日本語_1.tsv")
```

これをエンコードして埋め込んであげる必要がある

```java
    Spark.res.header("Content-disposition", "attachment; filename=" + URLEncoder.encode("日本語_1.tsv", "UTF-8"))
```
【kotlin】AutoClosableにuseが使えない？

# それってkotlin1.0の頃の仕様じゃないの？

```db.kt
DriverManager.getConnection(url).use { conn ->
    // use がコンパイルエラーに・・・？
```

# まさかこんなにハマるとは・・・

```build.gradle
dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib'
}

　↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

dependencies {
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10'
}
```

いつもbuild.graldeを使い回ししててこんな引っ掛かり方しないんで、テンパってしまいましたとさ。
ReactNativeのライブラリreact-native-gifted-chatでメッセージを上から表示されるようにする

ReactNativeでよく使われている`react-native-gifted-chat`はデフォルトで画面の下から表示されますが、多分日本人は上から表示されている方が慣れていると思うので変えます。

変えると言っても`alignTop={true}`を指定するだけなのでめちゃ簡単です。

```tsx
<GiftedChat
      alignTop={true}
    />
```

これで上から表示されました。

閲覧していただきありがとうございました。
[Android] [Material Design] テーマの参考になったページまとめ 2020

Android アプリ開発時のテーマを決める際に参考になったページをご紹介したいと思います。

## 1. Material Design > Color > The color system
<a href="https://material.io/design/color/the-color-system.html#color-usage-and-palettes">Material Design > Color > The color system</a>
Material Design の公式ページです。基本的にAndroid はMaterial Design に準拠したものにしたいため、まずはこちらを眺めてみることをオススメします。

## 2. COLOR TOOL
<a href="https://material.io/resources/color/#!/?view.left=0&view.right=0">COLOR TOOL</a>
カラーパレットから色を選択すると、アプリがどのようになるのかわかるツールです。
色はMaterial Design color palettes に存在する色からの選択や、カスタムカラーのお試しも可能です。

## 3. Material UI Web Development Tools（※Material Design 非公式）
<a href="https://www.materialui.co/">Material UI Web Development Tools</a>
Material Design 以外のカラーパレットもあり、色選びの参考になると思います。

## 4. MATERIAL DESIGN PALETTE GENERATOR（※Material Design 非公式）
<a href="http://mcg.mbitson.com/#!?mcgpalette0=%233f51b5">MATERIAL DESIGN PALETTE GENERATOR</a>
ベースの色を選択すると、自作テーマに必要な50~900の16進カラーコードを表示してくれるツールです。
Flutter での開発時にデフォルトテーマのColors.blue だと少し濃く感じるのでベースカラーを少し薄くしたいときに使ったりします。
自作テーマの作り方はこちらの記事を参考にさせていただきました。
<a href="https://qiita.com/granoeste/items/352d19157c21cd35e21f">Flutter アプリテーマのカスタマイズ</a>

## 5. material design palette（※Material Design 非公式）
<a href="https://www.materialpalette.com/">material design palette</a>
2つの色（Primary と Accent）を選択するとアプリのイメージを確認できるツールです。
手軽に試せるのが良かったです。

## まとめ
他にも便利なツールが色々あると思いますので、追記していけたらと思います。
ご指摘やご紹介いただけますと嬉しいです。
react-native-gifted-chatで送信ボタンをカスタマイズする


ReactNativeでreact-native-gifted-chatというライブラリを使ってチャットを実装してる人は多いと思いますが、送信ボタンがデフォルトでは Send になっています。

それをここでは 送信 に変えたいと思います。

そのためにはrenderSendプロップスを指定します。
これにはreactコンポーネントを渡します。

```tsx
import {GiftedChat, Send} from 'react-native-gifted-chat';

// 省略

<GiftedChat
      renderSend={(props) => {
        return (
          <Send {...props} containerStyle={styles.sendContainer}>
            <Text style={styles.sendButtonTitile}>送信</Text>
          </Send>
        );
      }}
    />
```

```tsx
const styles = StyleSheet.create({
  sendContainer: {
    justifyContent: 'center',
    alignItems: 'center',
    alignSelf: 'center',
    marginRight: 15,
  },
  sendButtonTitile: {
    color: '#4fa9ff',
    fontWeight: 'bold',
  },
});
```

TextのところをIconなどにすればアイコンも簡単に使用できます。

ありがとうございました。
WSL2 環境で Amplify の Git-based deployments を設定しようとしたらエラーになった話 

# 発生したエラー

WSL2 環境で `amplify hosting add` で、Git-based deployments を選択したら下記のエラーが発生しました。

    spawn wslvar ENOENT
    Error: spawn wslvar ENOENT
        at Process.ChildProcess._handle.onexit (internal/child_process.js:267:19)
        at onErrorNT (internal/child_process.js:469:16)
        at processTicksAndRejections (internal/process/task_queues.js:84:21)

# 原因

ググったら同じような事象に見舞われたという issue が別の OSS プロジェクトで見つかりました。

- [Error: spawn wslvar ENOENT when using create-snowpack-app on WSL2 #1285](https://github.com/snowpackjs/snowpack/discussions/1285)

内容を読んでみると Amplify CLI で発生した事象と同じ原因であることがわかりました。

内部で使用している [open](https://github.com/sindresorhus/open) という npm パッケージが、ブラウザを開く際に `wslvar` というコマンドを呼ぶ動作をしているようで、それが環境に入っていなくてエラーになっているようです。

実際に Amplify CLI の hosting カテゴリで使用されている [package.json](https://github.com/aws-amplify/amplify-cli/blob/955022cbc5d792868240e4e1bd8b024085da1c0f/packages/amplify-console-hosting/package.json) を見ると、 `open@^7.0.0` が依存関係に含まれていて、コードでも[使われている](https://github.com/aws-amplify/amplify-cli/blob/955022cbc5d792868240e4e1bd8b024085da1c0f/packages/amplify-console-hosting/hosting/cicd/configure.js)ようです。

# 解決

空気読まずに `xdg-open` で WSL2 上のブラウザ開いてくれてこっちはええんやで、とも思いつつ、素直に `wslvar` コマンドが含まれる [wslu](https://github.com/wslutilities/wslu) をインストールすることでエラーが回避できました。

# まとめ

今回はたまたま Amplify CLI で遭遇した事象ですが、WSL2 環境で `open` パッケージを使用する CLI ツール全般で起こる事象のようです。[^1]

以上。

[^1]: 試してなかったですが、もしかしたら VS Code（Remote WSL）上の統合ターミナルだったら問題ないとかあるのかな。
備忘録）文字列に含まれた特定の記号を辞書で一括変換する

#概要
「データに含まれる文字の一括変換方法」
https://qiita.com/wellwell3176/questions/1345ab14964d2a050b5a

上記質問への回答を元にプログラムを作成した。
質問ページに貼ると長くなりすぎたので分割のために投稿。


#仕様
表1の生データに対し、表2に在る変換表を用いて記号を分離・変換して新たな列に格納する
今回のデータでは表2の変換表が小さいが、実際のデータでは記号が30種類、列ラベルが10種類ほどあるので、
「1枚のエクセルファイルで変換表をなるべくまとめたい」という希望があった。
※表2くらいのサイズならエクセルファイルのタブごとに「個人予想の変換表」「新聞予想の変換表」と作って管理したほうが絶対楽

表1　生データ

|	No.	|	馬名	|
|	:-:	|	:-:	|
|	1	|	コシヒカリ○③	|
|	2	|	ササニシキ◎	|
|	3	|	ヨモギダンゴ✕②	|
|	4	|	タナカタロウ①	|

表2　変換表

|		|	個人予想	|	新聞予想	|
|	:-:	|	:-:	|	:-:	|
|	①	|	1番	|		|
|	②	|	2番	|		|
|	③	|	3番	|		|
|	◎	|		|	本命	|
|	○	|		|	対抗	|
|	✕	|		|	大穴	|




#実装したプログラム
```python:完成品
import pandas as pd

#質問回答で提示いただいた汎用プログラムを流用
def tagging(df, column, trdict): #もとのDataFrame, 分類に使用するカラム, 分類用の辞書
    for key, d in trdict.items():
    #データフレームの1st key（個人予想、新聞予想）ごとに処理を行う。
        df_ = df[column].str.extract(f'({"|".join(d.keys())})')
        for k, v in d.items():
            df_ = df_.replace(k, v)
        　　#2nd key(◎✕など)で抽出して新列を作った後、2nd key と valueを変換
            df[column] = df[column].str.replace(k, "")
        df[key] = df_.fillna("")
        #抽出元の列から2nd keyを削除
    return df

df = pd.DataFrame( #サンプルデータを作成。実際にはエクセル読み込み
    data=[{
        'No.': 1,
        'horse': 'コシヒカリ○③',
    }, {
        'No.': 2,
        'horse': 'ササニシキ◎',
    }, {
        'No.': 3,
        'horse': 'ヨモギダンゴ✕②',
    }, {
        'No.': 4,
        'horse': 'タナカタロウ①',
    }])

dict_raw = pd.read_excel("hogehoge.xlsx",index_col=0)
#hogehoge.xlsxは表2のエクセルデータに等しい
dict_process=dict_raw.to_dict(orient='dict')
#to_dictで辞書形式に変換
list_key=list(dict_process.keys())
#for文で使うので、keyの中身をリスト化（辞書のままだと順序を持たないのでfor文の対象として選べない）

dict_comp=dict() #update()を使うので、完成品を空の辞書として先に生成

#辞書から値を持たないkeyを削除（今回の場合、"個人予想":"◎"にはnanが格納されていて邪魔）
for i in list_key:
  output_dict = dict(filter(lambda item: item[1] is not np.nan, d3[i].items()))
  dict_comp.update({i:output_dict})

tagging(df,"horse",dict_comp)
```
```
＜出力結果＞
	No.	horse	個人予想	新聞予想
0	1	コシヒカリ　	3番　  対抗
1	2	ササニシキ	　　　　　本命
2	3	ヨモギダンゴ	2番	大穴
3	4	タナカタロウ	1番	
```


#参考リンク
辞書フィルタリングの参考元：
https://tombomemo.com/python-dict-filter/