OmniAICreator/Qiita-1.07M huggingface dataset:
Flutter image_pickerでpngを選択するとクラッシュする場合の対処法

## はじめに
みんな大好き[image_picker](https://pub.dev/packages/image_picker)のプラグイン 

<div style="text-align: center;">
<img width="500" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184792/aa78faa0-247d-69ac-8f3b-847e739ad81c.png"></div>

備忘録。


## 現象
Androidの場合に、

以下で選択したファイルがPNGの場合にクラッシュ。

```dart
var file = await ImagePicker().getImage(source: ImageSource.camera);
```

https://github.com/flutter/flutter/issues/41346

## 対策
FileクラスにExtensionを生やして、Jpegに変換して対応。

```dart:IOFileExtensions.dart
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:image/image.dart';

extension IOFileExtensions on File {
  Future<File> convertJpg({int resizeWidth = 500}) async {
    if (this == null) { return null; }
    try {
      final image = decodeImage(readAsBytesSync());
      final aspect = image.height / image.width;
      final thumbnail = copyResize(image, width: resizeWidth, height: resizeWidth * aspect.toInt());
      return await writeAsBytes(encodeJpg(thumbnail));
    }
    catch(error) {
      debugPrint('convert jpg error: ${error.toString()}');
      return this;
    }
  }
}
```
docker for macでThe data couldn’t be read because it is missingのエラーが出る場合

`mac 10.15.6`、`docker 2.3.0.5`

以下のエラーが出ます。

> Failed to analyse
>
> The data couldn’t be read because it is missing

以下のページから`docker 2.3.0.4`にダウングレードすると起動できました。

https://docs.docker.com/docker-for-mac/release-notes/#docker-desktop-community-2304

issue : https://github.com/docker/for-mac/issues/4526
ERROR:  While executing gem ... (Gem::FilePermissionError)というエラーの対処法

Re:Viewをインストールした際に起きたGemのエラー対処法です。
※Re:Viewのインストールでなくても起きます。

```
$ gem install review
```

>ERROR:  While executing gem ... (Gem::FilePermissionError)
    You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory.

このようなエラーが出力されます。

## gemのインストール先の権限が許可されていない

```
$ sudo gem install review
```
上記のように`sudo`すればインストール出来ると思いますが、今回はユーザー領域にインストールしたいので、**インストール先(GEM_HOME)**を明示的に指定してエラーを回避してみます。

```
$ mkdir -p $HOME/rubygems
$ export GEM_HOME=$HOME/rubygems
$ export PATH=$GEM_HOME/bin:$PATH
```
この3行を`~/.zshrc`などに記述しておき完了。

権限によるトラブルがなくなりました。

## 参考

[[ruby] gemをユーザー領域にインストールする - 生活。](http://samurai20000.hatenablog.com/entry/20100414/1271230641)
nginx-upload-module on レポ版 nginx

# nginx-upload-moduleをレポ版nginxで使用する
service や systemctl コマンド等を使い慣れてるので、Debianのapt版nginxで動かしてみたいと思った次第。
いろんな質問フォーラムを覗いても、ソースコードからインストールしろとしか書かれてないので書いてみた。

環境は Debian 10

## nginxのインストール環境を整える

http://nginx.org/en/linux_packages.html

```bash
apt install vim curl git gnupg2 ca-certificates lsb-release -y
echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | tee /etc/apt/sources.list.d/nginx.list
echo "deb http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" |  tee /etc/apt/sources.list.d/nginx.list
curl -fsSL https://nginx.org/keys/nginx_signing.key | apt-key add -
apt-key fingerprint ABF5BD827BD9BF62

apt update
```

## nginx-upload-module のダウンロード

公式マニュアルにリンクされてるvkholodkov版を使用した

```bash
cd /opt;
git clone https://github.com/vkholodkov/nginx-upload-module.git
```

## nginxソースコードのダウンロードと環境構築

deb-src のレポジトリ設定が必要

/etc/apt/sources.list

```
deb http://ftp.debian.org/debian buster main contrib
deb-src http://ftp.debian.org/debian buster main contrib

deb http://ftp.debian.org/debian buster-updates main contrib

deb http://security.debian.org buster/updates main contrib
```

インストールに必要な環境構築

```bash
apt update
apt build-dep nginx -y
```

ソースコードのダウンロード

```bash
cd;
mkdir nginx && cd nginx;
apt source nginx -y
```

`vim nginx-*/debian/rules`
どのパッケージで --add-moduleするか確認する。commonの時点でインストールしたかったので以下のように記述した

```
common_configure_flags := ...
                        --add-module=/opt/nginx-upload-module
```

## debファイルの生成
```bash
dpkg-buildpackage -b
```

## インストール
色々あるが、dbgsymが含まれてるのはデバッグ用なので除外する。
インストール順は libnginx-mod系 → nginx-common → nginx-full/nginx/nginx-light になる。

ワンライナーでfull版をインストールする場合は以下の通り

```bash
ls | egrep '.deb$' | grep -v dbgsym | grep -v light | grep -v extras | grep -v nginx_ | xargs dpkg --install
```

## アップデートされない為に
2日程放置していたら、正式版にアップグレードされていた。
自動アップデートを停止しておくといいが、脆弱になる可能性がある。定期的なメンテナンスは欠かさないようにしよう。

```bash
apt remove unattended-upgrades -y
```
ABC179 C - A x B + C 解法メモ

# はじめに

今日の見直し問題は ABC179 C - A x B + C です。

問題URL: https://atcoder.jp/contests/abc179/tasks/abc179_c  
解説URL: https://atcoder.jp/contests/abc179/tasks/abc179_c/editorial

> ### 問題文  
> 正整数 $N$ が与えられます。 $A \times B + C = N$ を満たす正整数の組 $(A, B, C)$ はいくつありますか？

> ### 制約  
> - $2 ≤ N ≤ 10^6$
> - 入力はすべて整数

# step 1: A, B, C がとりえる値の範囲
$A$、$B$、$C$ がとりえる値の範囲を考えます。

まず、問題文に正整数とあるので、$1 \leq A$、$1 \leq B$、$1 \leq C$ であることが条件です。
$A = 1$、$B = 1$、$C = 1$ のとき、$N = 2$ となるので、制約を満たします。

次に、$A$、$B$、$C$ の上限値を考えます。
$C$ が最小（ $C = 1$ ）のときに $A$ または $B$ が上限値をとることができ、その上限値 $A_{max}$ 、 $B_{max}$ は

$$
A_{max} = N - 1\\\\
B_{max} = N - 1
$$

です。
また、$A$ 、 $B$ がともに最小（ $A = 1$ かつ $B = 1$ ）のときに $C$ が上限値をとることができ、その上限値 $C_{max}$ は

$$
C_{max} = N - 1
$$

です。

以上より、$A$、$B$、$C$ がとりえる値の範囲は、

- $1 \leq A \leq N - 1$
- $1 \leq B \leq N - 1$
- $1 \leq C \leq N - 1$

であることがわかります。

# step 2: 単純な解法
単純な解法として全探索を考えてみます。

```c++
int getABCCombinationsCount(int N) {
    int ABCCombinationsCount = 0;
    for(int a = 1; a < N; a++) {
        for(int b = 1; b < N; b++) {
            for(int c = 1; c < N; c++) {
                if(a * b + c == N) {
                    ABCCombinationsCount++;
                }
            }
        }
    }
    return ABCCombinationsCount;
}
```

全探索で $A \times B + C = N$ を満たす正整数の組 $(A, B, C)$ の数を計算する関数 getABCCombinationsCount() を考えてみました。
時間計算量は $O(N^3)$ です。
$N$ は最大で $10^6$ なので、実行時間が制限に間に合いません。


# step 3: 改良アプローチ
別のアプローチを考えてみます。

条件式 $A \times B + C = N$ を変形してみます。

```math
\begin{align}
&A \times B + C = N\\\\
&\Leftrightarrow A \times B = N - C\\\\
\end{align}
```

最終行の等式の右辺がとりえる値の範囲は、step 1 より


$$
1 \leq N - C \leq N - 1\
$$

です。

ということは、$1 \leq A \leq N - 1$、$1 \leq B \leq N - 1$ を前提として、$A \times B \leq N - 1$ を満たしてさえいれば、$A$、 $B$ はどんな値をとってもいいことになります。$A \times B$ がどんな値になっても、$C$ で辻褄を合わせて条件式 $A \times B + C = N$ を成り立たせることができます。




# step 4: A * B ≦ N - 1 を満たす (A, B) の組を求める
わかりやすさのため、具体例として $N = 6$ の場合を考えてみます。
条件 $A \times B \leq N - 1 = 5$ を満たす (A, B) の組を以下に列挙します。

| A | B |
|---|---|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
| 4 | 1 |
| 5 | 1 |

$A$ の値に対し条件を満たす $B$ は、$\lfloor \frac{5}{A} \rfloor$ 個あることがわかります。
一般化すると、$\lfloor \frac{N-1}{A} \rfloor$ 個です。

したがって、$A$ を $1$ から $N - 1$ の範囲で変化させることで、各 $A$ における条件を満たす正整数の組 $(A, B, C)$ の数を各回即座に得ることができます。
以下のような関数 getABCCombinationsCount_improve() で $O(N)$ で解答を得ることが可能です。

```c++
int getABCCombinationsCount_improve(int N) {
    int ABCCombinationsCount = 0;
    for (int a = 1; a < N; a++)
    {
        ABCCombinationsCount += (N - 1) / a;
    }
    return ABCCombinationsCount;
}
```



# まとめ
今回の解法ポイントは

- 各変数がとりえる値の範囲の特定
- 式の変形

でした。

ご覧いただきありがとうございました。
Matplotlibで棒グラフを作成する時の基本

棒グラフを作る時は以下のコードを記載。

matplotlib.pyplot.plot()

カッコ内に棒グラフに入れたい要素を記載して棒グラフを作成。

以下、横軸のデータxとこれに対応する縦軸のデータyを指定して作成、描写する場合。

↓横軸のデータxとこれに対応する縦軸のデータyを指定して作成
matplotlib.pyplot.bar(x, y)

↓描写時のコード
plt.show()

・横軸にラベルを設定する
横軸にラベルを設定する場合は以下のコードを記載。
matplotlib.pyplot.bar(x, y, tick_label=[ラベルのリスト])

・積み上げグラフを作成する
積み上げ棒グラフを作成する際は以下のコードを記載。
matplotlib.pyplot.bar(x, y, bottom=[データ列のリスト])
Kubernetesで「error: a container name must be specified for pod」エラーが発生したときの対処方法

# エラー内容
Kubernetesで複数コンテナを含むDeploymentのLogを確認しようとした際に、以下のエラーが発生しました。


```bash
$ kubectl logs pod/app-664dd8bdf5-cq62j
error: a container name must be specified for pod app-664dd8bdf5-cq62j, choose one of: [app web]
```

# 解消方法
複数コンテナを含むPodのログを確認しようとしていたため、複数コンテナのうちのどのログを見るのか、-cオプションで指定してあげる必要がありました。

```bash
$ kubectl logs pod/app-664dd8bdf5-cq62j -c web
```
温位(potential temperature) の数式の求め方

#温位とは

気象予報士の勉強をしてると突然出てくる式で計算したら出てくるもの。

気象予報士の実質的バイブルである 一般気象学( 第2版補訂版  小倉義光著)のp.53 式(3.34)には以下のような式が記されている。

```math
\theta = T \left( \frac{p_0}{p} \right)^\left( R_d/C_p \right)
```

$\theta$  :  温位
$R_d$  :  乾燥空気に対する気体定数
$C_p$  :  定圧比熱
$p_0$  :  たいてい1000hPa
$p$  :  ある気圧[Pa]

逆に言うと、この式だけがポンと出されているだけで、どうやって求めたのかは書いてません。
というわけで、どうやって上記の式が求まったかを示してみました。


#前提となる法則とか。

##断熱過程

wikipedia先生の[断熱過程](https://ja.wikipedia.org/wiki/%E6%96%AD%E7%86%B1%E9%81%8E%E7%A8%8B)によると、

>理想気体が断熱準静的に変化するとき、圧力と体積の間にはポアソンの法則
> $pV^{\gamma}=\mathrm {const.}$
>が成り立つ。
>ここで、 $p$:圧力    $V$:体積     $\gamma$:比熱比

この式は熱力学を学ぶと覚えさせられる式で、ある圧力と体積と比熱比が決めると断熱変化だと仮定すると、$p$か$V$が決まると$V$か$p$が求まる。
というわけで、以下のような式が成り立つ。

```math
p_0V_0^{\gamma}=p_1V_1^{\gamma}
```

##状態方程式

wikipedia先生の[理想気体](https://ja.wikipedia.org/wiki/%E7%90%86%E6%83%B3%E6%B0%97%E4%BD%93)から状態方程式がある。

```math
pV=RT
```
これを変形すると

```math
V=\frac{RT}{p}
```

が現れる。

さらに、気体定数$R$と比熱比$\gamma$には以下のような法則があるらしい。

```math
C_p-C_v=R
```

```math
\gamma = \frac{C_p}{C_v}
```

#数式変形

```math
p_0V_0^{\gamma}=p_1V_1^{\gamma}
```

上記の式に下記の式を代入する。

```math
V=\frac{RT}{p}
```

```math
p_0 \left( \frac{RT_0}{p_0} \right) ^ {\gamma}=p_1 \left( \frac{RT_1}{p_1} \right)^{\gamma}

```

Rは右辺・左辺共に共通なので消す。

```math
p_0 \left( \frac{T_0}{p_0} \right) ^ {\gamma}=p_1 \left( \frac{T_1}{p_1} \right)^{\gamma}
```

指数を展開

```math
\frac{T_0^\gamma}{p_0^{\gamma-1}}  = \frac{T_1^\gamma}{p_1^{\gamma-1}} 
```

式変形

```math 
T_0^\gamma=\frac{p_0^{\gamma-1}}{p_1^{\gamma-1}}T^\gamma
```

式変形

```math 
T_0 =\frac{p_0^ \frac{\gamma-1}{\gamma}}{p_1^\frac{\gamma-1}{\gamma}}T_1
```

式変形

```math 
T_0 =T \left( \frac{p_0}{p_1} \right)^{\frac{\gamma-1}{\gamma}}
```

次に$\frac{\gamma-1}{\gamma}=1-\frac{1}{\gamma}$を求める。

```math
C_p-C_v=R
```

```math
\frac{C_p}{C_p}-\frac{C_v}{C_p}=\frac{R}{C_p}
```

```math
1-\frac{C_v}{C_p}=\frac{R}{C_p}
```

```math
1-\frac{1}{\gamma}=\frac{R}{C_p}
```

以上より、

```math 
T_0 =T \left( \frac{p_0}{p_1} \right)^{\left( \frac{R}{C_p} \right)}
```


#まとめ

この式変形から筆者が思う温位の定義は、上空のどこかの高度（気象予報士試験の世界では圧力）に乾燥空気が温度$T_1$[K]で存在するとき、温度ってのは$pV=RT$に従って圧力その他諸々で変化するし、評価できないから、1000hPaまで断熱変化したとした時の温度にしたのだろうなぁと。
Rust開発でオススメのVSCode拡張機能

# TL;DR
- Rust開発時に、個人的オススメのVSCode拡張機能がまとめてあります。
- 随時更新していきます。

# 実行環境
**ハードウェア**

|項目|情報|
|:---------|:------------------|
|OS|macOS Catalina(10.15.4)|
|ハードウェア|MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)|
|プロセッサ|1.4 GHz クアッドコアIntel Core i5|
|メモリ|16 GB 2133 MHz LPDDR3|

# ライブラリ
## Better TOML
> Better TOML is vs code extension to support TOML file.

- シンタックスハイライトが付きます。
- シンタックスバリデーションがかかります。
- `Syntax Hightligting for markdown frontmatter`（使い所がよく分からなかった）


## Rustfmt
> Register rustfmt as a formatter for Rust code.

> Currently VSCode has a great extension for Rust, vscode-rls. However that extension doesn't have support for single .rs file. Especially formatting action does not triggered when file saved. This extension solves that problem.

VSCode上で、`cmd + shift + p`で「ドキュメントのフォーマット」を選択すると実行できます。


# 参考情報
npm から取得した Node-RED をカスタマイズして起動する(2)

# 何のため？

Node-RED を Heroku で動作させたかったのだが想定外の動作をしていました。
Node-RED で発生している事象を調査するための環境構築手順を整理した記録です。

セオリーから外れているかもしれませんので、間違っていたらコメントをお願いします。

# 0. 準備

[前の記事](https://qiita.com/eurogrve/items/0638e8dce7bd508d03c3)で node-red-sample ディレクトリ配下に Node-RED のソースがある状態の環境を構築した。
本記事では、[『2.2 カスタマイズ方法(2) : settings.js を userDir に入れておく』](https://qiita.com/eurogrve/items/0638e8dce7bd508d03c3#22-%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E6%96%B9%E6%B3%952--settingsjs-%E3%82%92-userdir-%E3%81%AB%E5%85%A5%E3%82%8C%E3%81%A6%E3%81%8A%E3%81%8F) の方法で進めていく。

準備としては、下記コマンドを入力したところから開始となります。

```shell
$ mkdir node-red-sample
$ cd node-red-sample
$ npm -y init
$ npm install node-red
$ mkdir data
$ cp ./node_modules/node-red/settings.js ./data/
```

Node-RED を起動するには下記コマンドを入力する。

```shell
$ node ./node_modules/node-red/red.js  --userDir ./data
```

# 1. npm で入手した Node-RED をローカル管理に変更

前述の通り、Node-RED のコアをデバッグしたいので、ソース管理内に保持する手順を実施する。

## 1.1. Node-RED をローカルフォルダに移動

改変を加える Node-RED ソースは local_packages ディレクトリに置いて作業を進める事にする。

```shell
$ mkdir local_packages
$ mv node_modules/node-red ./local_packages/
$ mv node_modules/@node-red ./local_packages/
# 念のため依存パッケージからnpmjsのnode-redを取り除く
$ npm uninstall node-red
$ rm package-lock.json
```

## 1.2. package.json を書き換え

local_packages フォルダのモジュール類を dependencies 記述する。

```package.json
  "dependencies": {
    "node-red": "file:local_packages/node-red",
    "@node-red/nodes": "file:local_packages/@node-red/nodes",
    "@node-red/editor-api": "file:local_packages/@node-red/editor-api",
    "@node-red/editor-client": "file:local_packages/@node-red/editor-client",
    "@node-red/registry": "file:local_packages/@node-red/registry",
    "@node-red/runtime": "file:local_packages/@node-red/runtime",
    "@node-red/util": "file:local_packages/@node-red/util"
  }
```

## 1.3. 書き換えた package.json の内容を node_modules に反映させる

```shell
$ npm install
```

以上で、node_modules 配下には local_packages からのハードリンクが張られる。
Node-RED Core 実体は local_packages にあるものが利用される。

**→ コメント追加するなりして、自由にデバッグが出来るので HAPPY !!!**

# まとめ

本手順で作ったソース一式を git で管理し、herokuで好きなようにデバッグ出来るようになった。

**→ その後の調査でherokuとは関係なく発生する問題であることが判明した。**

続く...
チラシの裏に書くこと

ガラクタ箱の奥から太古のタブレットが出てきたので触っていたらまとめがほったらかしになってた。
Android3.1なんだけどhttpsが動かない。多分証明書だと思うんだけど・・・・・・・・・・・で進まない。
ちくそう。
ghについて知っておきたい3つの事

`gh`が正式版としてリリースされました。

結構、記事も出ているので、この投稿では知っておくと良いことを3点ほど紹介したいと思います。


## 1. diffはあるがWebほど見やすくない
`gh`にはPRに対して変更した内容を表示するコマンド、`diff`があります。
linux,macOSで`diff`コマンドを使ったことある人はわかるかと思いますが、このghのdiffはオプションが色付けだけなので、見づらいです。
変更が数行レベルのPRならいいですが、数十行単位かつ複数ファイルにまたがる変更だとあんまりCLIでレビューする利点はないかなぁと思います。
```zsh
$ gh pr diff
```

![](https://storage.googleapis.com/zenn-user-upload/o49ddn62edu2beykac65m53hm82j)


## 2. 自分のPRはApproveできない
1点目Reviewで気をつける必要があることは`gh`は自分で作成したPRの`Approve`はできないという事です。なので、自分のPRをReviewしたい場合はWebで行う必要があります。
```zsh
$ gh pr review 1
? What kind of review do you want to give? Approve
? Review body <Received>
? Submit? Yes
failed to create review: Can not approve your own pull request
```


## 3. Default Editorは`nano`
デフォルトだと`nano`がエディタとして設定されているので、使い慣れたエディタに(`code`/`vim`)に変更します。
`nano`の方がしっくりくる方は変更する必要はありません。
今回は`code`(VScode)をは見送りました、理由はVSCodeだとPRのBodyのPreviewが簡単に見られるからです。
git同様、ファイルを閉じると変更がghの方で認識されるようです。

ちなみ、過去のコミット時のコメントが全て入力されたものが、表示されます。

```zsh
$ gh config set editor "code --wait"

# vim
$ gh config set editor vim

```

![](https://storage.googleapis.com/zenn-user-upload/kqpfb91uaflswmcdivs2pqp5ua1m)
MacのTimeMachineのバックアップ先としてUbuntu 20.04のnetatalkを使う

## 背景
手元のMacを修理に出す前にバックアップを取る必要があった。
ディスクに余裕があるLinuxマシン（物理マシン）があったので、それを使うことにした。

ググって出てくる情報が古くて今のバージョンに当てはまらないものだったので、情報を残しておく。

## 注意点
とりあえず動いたというレベルなので、設定が適当だったりします。

## 環境
* MacBookPro（macOS Catalina）
* Ubuntu 20.4
    * netatalk 3.1.12


## 手順
### Ubuntu側

#### netatalkインストール

```
$ sudo apt install netatalk
```

#### netatalk設定

```
cd /etc/netatalk/

# 念のためバックアップを取る
cp afp.conf afp.conf.bk

vim afp.conf
```

```text:afp.conf
;
; Netatalk 3.x configuration file
;

[Global]
; Global server settings

; [Homes]
; basedir regex = /xxxx

; [My AFP Volume]
; path = /path/to/volume

[My Time Machine Volume]
path = /var/timemachine_bk
time machine = yes
vol size limit= 256000
```

pathはバックアップファイルが保存される場所を指定する。
vol size limitは、自分の環境に合わせて設定する。

自分の場合は、ディスクが256GBなので、それっぽい値にした。


#### netatalkサービス再起動
必要かわからないけどやっておく。

```
sudo systemctl restart netatalk.service
```


#### 保存先ディレクトリの準備
自分の環境に合わせて設定する。

```
mkdir /var/timemachine_bk
chown aki:aki /var/timemachine_bk
```

## Mac側

設定で、TimeMachineを選択する。

自動的にUbuntuに作成したボリュームが認識されているはず。

あとはTimeMachieの設定なので割愛。
symfony4 セッションの利用

#sessionの利用
```
public function index(Request $req , SessionInterface $session)
    {
        $session->set('sessionKey', 'session');
        $session->get('sessionKey');
        $session->remove('sessionKey');
        return $this->render($this->twig_base . 'index.html.twig', [
        ]);
    }
```
Matplotlibで折れ線グラフを描く時の基本

折れ線グラフ

折れ線グラフについては以下コードを記載

matplotlib.pyplot.plot()

カッコ内に折れ線グラフの構成要素を記載することで折れ線グラフを作成できる。

・マーカーの種類の選択と色を選択
以下コードでマーカーの種類と色を選択できる。
matplotlib.pyplot.plot(x, y, marker="マーカーの種類", markerfacecolor="マーカーの色")

マーカーの種類や色は以下の通りにかけばOK

マーカー

"o": 円
"s": 四角
"p": 五角形
"*": 星
"+": プラス
"D": ダイアモンド

色

"b" : 青
"g" : 緑
"r" : 赤
"c" : シアン
"m" : マゼンタ
"y" : 黄色
"k" : 黒
"w" : 白

・線のスタイルと線の色設定

以下コードで線のスタイルや色を設定する。
matplotlib.pyplot.plot(x, y, linestyle="線のスタイル", color="線の色")

線のスタイルや色は以下の通りにかけばOK

線のスタイル

"-": 実線
"--": 破線
"-.": 破線（点入り）
":": 点線
色

"b" : 青
"g" : 緑
"r" : 赤
"c" : シアン
"m" : マゼンタ
"y" : 黄色
"k" : 黒
"w" : 白
Excelで統計分析①　カイ二乗検定（1/2）

:exclamation:9/21修正：期待度数の算出方法を修正

統計検定２級を苦労して取得したものの、なかなか普段の業務で知識を使うことがなく、このままではせっかく勉強したのにすぐに忘れてしまう。。。
そこで、Excelで統計分析を行う方法を勉強しつつ、復習した内容を残していこうと思います。

まずはカイ二乗検定。
あやふやになっていた適合度の検定と独立性の検定の違いについても、この機会にまとめてみます。

1. カイ二乗検定
---------------

カイ二乗検定とは、カテゴリカルデータ※を対象とした検定手法で、カイ二乗分布を用いる検定の総称。

※名義尺度（血液型や性別といった単に分類するために整理番号として数値を割り当てたもの）、
　順序尺度（順位や好き/普通/嫌いといった順序や大小には意味があるが間隔には意味がないもの）からなるデータ

2. 適合度の検定
---------------------
クロス集計表において、実測度数がある特定の分布に適合（一致）するかどうかを検証する仮説検定

　度数分布表において、実測度数と理論度数のズレを検定統計量とし
　その値がカイ二乗分布の棄却域にあるかどうかで「ズレが偶然かそうでないか」を判断する。

　・帰無仮説と対立仮説
　　𝐻0 ：観測度数は理論度数の分布から得られた
　　𝐻1 ：観測度数は理論度数の分布から得られていない

　・検定統計量
　　n個の階級の度数分布において、i番目の階級の観測度数を、期待度数をとすると
　　統計量は自由度のカイ二乗分布に従う

```math
\chi_0^2 = \sum_{i = 1}^n \frac{(O_i - E_i)^2}{E_i}
```

3. 独立性の検定
---------------------
クロス集計表において、要素間に関連があるかどうかを検証する仮説検定

　「独立＝各セルの生起確率が事象の積に分解できる」との仮定の元で、観測度数と
　期待度数のズレを検定統計量とし、その値がカイ二乗分布の棄却域にあるかどうかで
　「独立の仮定が正しいかどうか」を判断する。

```math
P(A_i\cap B_j) = P(A_i)\cdot P(B_j) 
```

　・帰無仮説と対立仮説
　　𝐻0 ：行と列が独立
　　𝐻1 ：行と列が独立ではない

　・検定統計量
　　n個の階級の度数分布において、i番目の階級の観測度数をOi、期待度数Eiをとすると
　　統計量は自由度のカイ二乗分布に従う

```math
\chi_0^2 = \sum_{i = 1}^n \frac{(O_i - E_i)^2}{E_i}
```


４. Excelを使用した算出方法
---------------------------------------

|  | B1 | B2 | 合計 |
|:-:|:-:|:-:|:-:|
|  A1 | X11  | X12  |  a1 |
|  A2 | X21  | X22  |  a2 |
|  合計 | b1 | b2  | N  |


①クロス集計表の行合計の構成比率を計算する

|  | B1 | B2 | 合計 |
|:-:|:-:|:-:|:-:|
|  合計 | b1/N  | b2/N  | 1  |

②周辺和の積を総数で割って期待度数を算出する
　:exclamation:9/21修正：期待度数の算出方法を修正

|  | B1 | B2 | 合計 |
|:-:|:-:|:-:|:-:|
|  A1 | a1×b1/N  | a1×b2/N  |  a1×1 |
|  A2 | a2×b1/N  | a2×b2/N  |  a2×1 |

③CHISQ.TEST関数を使用して有意確率（P値）を算出する

　カイ・スクエアド・テスト
　CHISQ.TEST(観測度数の値,期待度数の値)


５. 有意確率（P値）
---------------------------------------
上記で算出された有意確率（P値）は「変数間の関係性が、どのくらい"たまたま"起こりうるか」を表している。

　P値が大きい場合 ： 関係性があるのはたまたまの可能性が高いので、関係性があるとは限らない
　P値が小さい場合 ： 関係性があるのはたまたまの可能性が低いので、関係性があると考える

事前に決めた有意水準（誤判断リスクの上限）より低い場合に「関係性がある」と判断する


References
---------------------------------
統計WEB
いちばんやさしい、医療統計
Excelで学ぶ 実践ビジネスデータ分析
【小ネタ】さっそく、ジブリの画像をダウンロードする

<font color="FF0000">※大した内容ではありません。今だけの「小ネタ」です。</font>

スタジオジブリのサイトで、いくつかの作品のシーンの画像がダウンロードできるようになりました。

[今月から、スタジオジブリ作品の場面写真の提供を開始します](http://www.ghibli.jp/info/013344/?s=03)

zoom等の背景とかAIのスタイル変換とか、色々使い道がありそうなのでダウンロードしようかと思ったのですが、一つ一つ手でダウンロードするのがめんどくさかったので、Pythonで書きました。

# ソース
```python
import urllib

works = ["marnie", # 思い出のマーニー
         "kaguyahime", # かぐや姫の物語
         "kazetachinu", # 風立ちぬ
         "kokurikozaka", # コクリコ坂から
         "karigurashi", # 借りぐらしのアリエッティ
         "ponyo", # 崖の上のポニョ
         "ged", # ゲド戦記
         "chihiro"] # 千と千尋の神隠し

url_base = "http://www.ghibli.jp/gallery/"
local_base = "C:/Users/hogehoge/Desktop/ghibli/"
ext = ".jpg"

for work in works:
    for i in range(50):
        name = work + str(i+1).zfill(3)
        url = url_base + name + ext
        local = local_base + name + ext
        
#        print(url)
#        print(local)

        urllib.request.urlretrieve(url,local)
```

はい。力技です。
作品名のところは、スクレイピングすればいいのですが、数が少なかった（8作品）だったので手打ちにしました。
もっと多くなったら、ちゃんとスクレイピングしましょう。
「class="panelarea"」で引っ掛けて、hrefの文字列から抜き出せばよさそうです。

※気が向いたら、後日ソースを書き直すかもしれません

# 注意事項
「常識の範囲でご自由にお使い下さい。」とのことですので、常識の範囲で使用させていただきましょう。
AWSのrootユーザー権限が必要となるタスク（Tasks that require root user credentials）

#本記事概要
AWSアカウントについて、公式が
・極力rootユーザーを使うのではなく、IAMで作ったユーザーを使いなさい
・しかしrootユーザー権限でしかできないタスクもある
と言っているので「rootユーザー権限でしかできないタスク」を日本語訳して残しておく。

https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_root-user.html

#rootユーザー権限でしかできないタスク
以下URLの「Tasks that require root user credentials」部分
https://docs.aws.amazon.com/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root
※特に英語力はないので自身に理解できる程度の意訳の可能性あり。
※URL先の内容は変更されている可能性あり。あくまで記事投稿時点のもの（2020/09/20）
※自身用に多少の注釈も追記している。

- **アカウント設定**
  アカウント名、rootユーザーパスワード、メールアドレス。
  連絡先情報、お支払い通貨の設定、リージョンといった他の情報は含まない。

- **特定の請求書表示**
  アクセス許可名「aws-portal:ViewBilling」を持つIAMユーザーは
  AWSヨーロッパからはVAT請求書を表示およびダウンロードできるが、
  AWS IncまたはAmazon Internet Services Pvt Ltd(AISPL)からはできない。
  **※以下用語**
  「aws-portal:ViewBilling」：Billing and Cost Management コンソールのページを表示するアクセス権限
  VAT：付加価値税。日本の消費税のようなもので、EUやアジアなどの国で、物やサービスの購買時に課せられる間接税のこと。
  AISPL：インドで AWS サービスのリセラーとして機能する現地法人。

- **アカウントの閉鎖**
  アカウントの閉鎖はAWSに連絡して代行してもらうということは不可。

- **IAMユーザー権限の復元**
  唯一のadministrator権限のIAMで誤って自身の権限を取り消してしまった場合は、
  rootユーザーとしてサインインして、ポリシーを編集し、権限を復元できる。

- **AWSサポートプランの変更、キャンセル**
  より詳しい情報を知りたいなら「IAM for AWS Support」を見るべし。
  個人で触ることはなさそう。

- **リザーブドインスタンスマーケットプレイスに出品者として登録すること**
  リザーブドインスタンスマーケットプレイス：さまざまな期間と料金オプションの未使用スタンダード リザーブドインスタンス の販売をサポートするプラットフォーム
  個人で触ることはなさそう。

- **CloudFrontのキーペア作成**
  CloudFront：AWSが提供する高速コンテンツ配信ネットワーク (CDN) サービス。
  そのサービス作成時にプライベートキーの取得が必要になる。

- **MFA Deleteを有効にするようにAmazon S3バケットを構成すること**
  S3 MFA Delete：MFA（多要素認証）削除

- **無効なVPC IDまたはVPCエンドポイントIDを含むAmazon S3バケットポリシーの編集、削除**
  バケットポリシー：S3のバケットおよびバケット内のオブジェクトにアクセス許可を付与できる。
  ※ココはどういうことなのか詳細には理解しきれていない。

- **GovCloudへのサインアップ**
  アメリカ人かつ政府関係者向けのサービスなので個人で触ることはなさそう。


以上。
Vec

# Vec
VecとはRustにおける可変長の配列です。
複数のデータを保存して番号で管理したり、順番に処理することが簡単にできます。

##使い方
`push()` `pop()`メソッドにより、スタックのように値を追加・削除出来ます。
要素数を知るには`len()`メソッドを使用します。
`[]`演算子により、任意の要素にアクセスできます。
Vecには他にも様々な機能がありますが、以上の操作とfor文・イテレータで大抵のことは出来ると思います。

~~~rust
fn main() {
    //空のVecを作成。
    //型推論が可能であれば、型の注釈は不要。
    let mut my_vec = Vec::new();
 
    //push()メソッドは最後尾にデータを追加する。
    //5を追加したため、要素の型がi32であると推論できる。
    my_vec.push(5);

    //いくつか適当に追加する。
    my_vec.push(2);
    my_vec.push(7);
    my_vec.push(4);

    //len()メソッドで要素数を取得できる。
    //4つ値を入れたため、要素数は4となる。
    println!("my_vecの要素数は{:?}です。",my_vec.len());

    //要素にアクセスするには[]を使う。
    //インデックスは0始まり。
    println!("0番目のデータは{:?}です。",my_vec[0]);

    //my_vecの各要素をelementに束縛してループ処理をする。
    let mut average = 0;
    for element in &my_vec {
        average += element;
    }
    average /= my_vec.len();

    //イテレータを作成することが出来る。
    let sum:usize = my_vec.iter().sum();
    println!("合計は{}、平均は{}です。",average,sum);

    //pop()メソッドは最後尾のデータを取り出す。
    //データが１つも無い場合はNoneを、それ以外の場合はSome(要素)を返す。
    println!("最後尾のデータは{:?}です。",my_vec.pop());
    println!("最後尾のデータは{:?}です。",my_vec.pop());

    //pop()メソッドを2回呼び出したため、要素数は2個減る。
    println!("my_vecの要素数は{:?}です。",my_vec.len());
}
~~~
実行結果

~~~
my_vecの要素数は4です。
0番目のデータは5です。       
合計は4、平均は18です。      
最後尾のデータはSome(4)です。
最後尾のデータはSome(7)です。
my_vecの要素数は2です。
~~~

##Vecの作成方法
`Vec::new()`以外にも、作成する方法がいくつかあります。
特に、`vec!`マクロはリテラルのようにVecを記述出来て便利です。

~~~rust
fn main() {
    //vec!マクロでリテラルのようにVecを記述することが出来る。
    let names = vec!["太郎","花子","京子","剛士","博之","佳代子"];
    println!("{:?}",names);

    //イテレータをcollect()メソッドで収集することで作成できる。
    let nombers = (1..10).collect::<Vec<i32>>();
    println!("{:?}",nombers);

    //あらかじめ要素数を指定することが出来る。
    //最大の要素数が分かっている場合、メモリの再確保を未然に防ぐことが出来る。
    //メモリは確保しているが、要素数は0。
    let capacity:Vec<f32> = Vec::with_capacity(100000);
    println!("{:?}",capacity);

    //to_vec()メソッドで配列をVecに変換することが出来る。
    let array = [1,2,3,4,5,6,7,8,9,10];
    let mut from_array = array.to_vec();

    //append()メソッドでVec同士を繋げることが出来る。
    let mut base = vec![10,9,8,7,6,5,4,3,2,1];
    base.append(&mut from_array);
    println!("{:?}",base);
}
~~~

[目次](https://qiita.com/tonesuke/items/52e469f18e747c794376)
子クラスのプロパティやメソッドを定義した場合、親クラスの定義を上書きするわけではない

これも、当たり前といえば当たり前・・・
しかし、気をつけてないと「あれ？」と思うことがあります。例えば、こういうクラスを考えます。


```python
class A:
    prop1 = 123
    prop2 = prop1
    
    def hoge(self):
        return 'superhoge'
    
    fuga = hoge
    


class SubA(A):
    prop1 = 777
    
    def hoge(self):
        return 'hoge'
```

SubAのオブジェクトを生成すると、hoge()やprop1は当然こうなります。

```
>>> a = SubA()
>>> print(a.hoge())
hoge
>>> print(a.prop1)
777
```

ところで、prop2やfugaはどうなるでしょうか？
それぞれ、prop1とhogeを参照してるので、仮に上書きされるのであれば同じ結果になりそうです。
しかし、実際はこうなります。

```
>>> a = SubA()
>>> print(a.fuga())
superhoge
>>> print(a.prop2)
123
```

このことより、prop2やfugaが親クラスの定義を参照してることがわかります。
オブジェクト指向の仕組みとして、「子クラスで上書きする」という言い方がなされることがしばしばありますが間違っています。言葉の使い方には気をつけたほうが良いと思います。
material ui の modal で Cannot read property 'hasOwnProperty' of undefined エラーが起きたときの解決法

# 概要
material ui の modal コンポーネントを使用したときに `Cannot read property 'hasOwnProperty' of undefined` というエラーが起きてしまいました。そのときの対処法を共有します。

# 解決法
`<Modal>` の中に div タグを書くようにしてください。

```javascript
return (
<Modal>
  <div>
    test
  </div>
</Modal>
)
```

参考:
https://stackoverflow.com/questions/56622246/react-material-ui-modal-typeerror-cannot-read-property-hasownproperty-of-unde
Blender 2.9, Python, 16進で色指定


今日の課題は、HTMLで使う16進のカラーコードを使って
マテリアル色指定して、それを立体に反映させること。
まずは3色ほど指定。色合いは 「坊ちゃん団子 / つぼや菓子舗」（愛媛みやげ）を参考にしました。（数日前 Blender 2.8から 2.9に変えました。 2.8用Pythonスクリプトは2.9でも動いている様子です。）
(2024.5.3 追記。Blender 4.1.1でもこのままのスクリプトで動作しました。 )
References : StackExchange [Blender 2.8 (python) - How to set material color using hex value instead of RGB](https://blender.stackexchange.com/questions/153094/blender-2-8-python-how-to-set-material-color-using-hex-value-instead-of-rgb)

![bochadango1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690216/b18c600f-7011-7e98-d646-23819008458f.png)


```python3
#bpy_nh20 (material color using hex value)
#(HEX色指定 )Blender 2.8 (python) - How to set material color using hex value instead of RGB

import bpy

# ========= DELETE ALL mesh, light, camera, みな削除する2行 =========
for item in bpy.data.objects:
    bpy.data.objects.remove(item)

# ======NEW CAMERA
bpy.ops.object.camera_add(enter_editmode=False, align='VIEW', location=(4, -6, 4), rotation=(1.3, 0, 0.5))
##(1.3, 0, -0.3)
# ====== NEW CUBE 
bpy.ops.mesh.primitive_cube_add(size=2,  align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

def hex_to_rgb( hex_value ):
    b = (hex_value & 0xFF) / 255.0
    g = ((hex_value >> 8) & 0xFF) / 255.0
    r = ((hex_value >> 16) & 0xFF) / 255.0
    return r, g, b

def add_material(obj, material_name, h):
    material = bpy.data.materials.get(material_name)
    if material is None:
        material = bpy.data.materials.new(material_name)
    material.use_nodes = True
    principled_bsdf = material.node_tree.nodes['Principled BSDF']
    if principled_bsdf is not None:
        principled_bsdf.inputs[0].default_value = (*hex_to_rgb(h), 1)  
    obj.active_material = material

#h = 0xE7E7FF
#h = 0x87ceeb #skyblue#87ceeb
#h = 0xadff2f #greenyellow#adff2f
#h = 0xee82ee #violet#ee82ee
#saddlebrown#8b4513
#moccasin#ffe4b5
#olive#808000

obj = bpy.context.object
add_material( obj, "test1", 0x8b4513)  #saddlebrown#8b4513

bpy.ops.mesh.primitive_cube_add(size=2,  align='WORLD', location=(0, 2, 2), scale=(1, 1, 1))
obj = bpy.context.object
add_material( obj, "test2", 0xffe4b5 ) #moccasin#ffe4b5

bpy.ops.mesh.primitive_cube_add(size=2,  align='WORLD', location=(0, 4, 4), scale=(1, 1, 1))
obj = bpy.context.object
add_material( obj, "test3", 0x808000 ) #olive#808000

# ============== "light_spot1" ==== HIGH 
# create light datablock, set attributes
light_data = bpy.data.lights.new(name="light_spot1", type='SPOT')
light_data.energy = 700
# create new object with our light datablock
light_object1 = bpy.data.objects.new(name="light_spot1", object_data=light_data)
# link light object
bpy.context.collection.objects.link(light_object1)
# make it active 
bpy.context.view_layer.objects.active = light_object1
#change location
light_object1.location = (-5, -7, 4)
light_object1.delta_rotation_euler = (1.3, 0, -0.3) #ゼロゼロゼロで真下を向く。
# update scene, if needed
dg = bpy.context.evaluated_depsgraph_get() 
dg.update()
# ================
# =========================== end of bpy_nh20
```
Rails ルーティングの基礎

備忘録のために投稿。

## 環境
ruby 2.7.1
Rails 6.0.3.2

Rails の導入は済んでいる前提です。

## generate コマンドで必要なファイルを作成
```
bundle exec rails g controller <controller_name> <method_name>

↓

bundle exec rails g controller home index
```

必要なファイルが作成される。削除したいときは delete コマンド

```
 bundle exec rails d controller home index
```



## routes.rb

```
bundle exec rails routes

or

bundle exec rails routes | grep xxx
(絞り込み)
```
ディレクトリ内のルーティングの設定が見れる。


### 見るべきポイント
```
 URI Pattern                        Controller#Action
  /articles/index(.:format)         articles#index
```
/articles/index にアクセスすると Controller articles の Action index に飛べる。rails s でサーバ立ち上げて localhost::3000 にアクセスすれば見れる。  
Rails のルールとして Controller 名はそのまま View 側の階層構造になっている。  


例：HomeController(コントローラー名)  
View のディレクトリ → home(ディレクトリ名)/index.html.erb(ファイル名)  


## Controller から View への値の渡し方

### インスタンス変数を使用する
```rb
class HomesController < ApplicationController
  def index
    # インスタンス変数
    @message = "message"
  end
end
```
変数の前に @ を付ける事で、Controller 内で値をどこでも呼べる。View に変数の値を渡すこともできる。今回の例の場合、インスタンス変数 @message に入った文字列 "message" が渡される。

```rb
<h1>Homes#index</h1>
<%= @message %>
```
HTML で Ruby を呼び出したい場合、<% %> で使用できる。何か出力したい場合、<%= %> とイコールを付けると出力される。インスタンス変数 @message を渡しているので、文字列 "message" が HTML で表示される。
Route53でホストゾーンの作成

## ドメインの取得

有名なのは、[お名前.com](https://www.onamae.com/)。
定番の`.com`や`.jp`もあり、`.work`だと1円のドメインもあります。
アカウント登録から、ドメイン取得まで10分もかからずに出来ました。

また、無料ドメインだと[freenom](https://www.freenom.com/ja/index.html?lang=ja)があります。
無料でドメインが取れますが、日本のサイトではないので少し見づらいかも？
こちらも簡単にドメイン取得ができます。

## Route53でホストゾーンの作成

- Route53でホストゾーンの作成

Route53のダッシュボードから`ホストゾーンの作成`に進みます。
![](Route 53 Console - Google Chrome 2020-09-14 21.14..png)![Route 53 Console - Google Chrome 2020-09-14 21.14..png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c2cff59e-4d58-2415-3522-9783cbb312d1.png)

- ホストゾーンの設定を記載

`ドメイン名`と`説明-オプション`を記載、
タイプは外部に公開するので`パブリックホストゾーン`を選択します。
選択が出来たら、`ホストゾーンの作成`を押して、完了です。
![Route 53 Console Hosted Zones - Google Chrome 2020.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b2ac0ceb-5982-9875-fc72-00c6d645ec37.png)

ホストゾーンの内容設定画面に移行し、ホストゾーンの作成は完了です。

## ネームサーバの設定

今回私はお名前.comでドメインを取得したので「ネームサーバの設定をRoute53でしましたよ」とお名前.comで設定しないといけないです。

- Route53でNSレコードの確認

黒で消してしまっているのですが、赤い枠の中に4つレコードがあります。
そちらをお名前.comで設定します。

![無題 - ペイント 2020-09-16 21.01.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c153a49c-3f18-74fe-c9e9-c395288dcc7f.png)

- お名前.comでネームサーバの設定

ご利用状況 > ドメイン一覧 > 指定のドメイン名クリック > ネームサーバの変更
その他 > 「その他のネームサーバーを使う」 > 4つレコードを記載して確認・保存

![お名前.com Navi - Google Chrome 2020-09-16 21.02.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/50e296f3-936e-f4a0-356b-6aac83fc59dd.png)

![無題 - ペイント 2020-09-16 21.04.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/ee056bf7-a5f0-08ea-b045-76b9044f9961.png)

![無題 - ペイント 2020-09-16 21.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3de6a0ba-98b0-f0c5-ba97-9a1666b20d24.png)

![お名前.com Navi - Google Chrome 2020-09-16 21.06.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/8965f7d6-98cd-8aa0-2b64-eb80606534d2.png)

これで、「DNSの管理はRoute53で行います」という設定が出来ました。
Re:VIEWで作成した電子書籍(PDF)に裏表紙を付ける

##1. はじめに
[技術書典](https://techbookfest.org/)9で頒布している電子書籍「[Lチカで始めるテスト自動化](https://techbookfest.org/product/5661312486998016)」を、プリントアウトした書籍の利便性を改善するため裏表紙を付けて改版しました。この記事ではその手順を示します。

##2. 手順
###2.1 裏表紙の画像の作成
幅489ピクセル[^1]、高さ約750ピクセルの裏表紙の画像をPNG形式で用意します。

![cover_b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221758/2bec5b9d-9d52-7e8c-14df-b0d0450d5329.png)

###2.2 backcover.texの作成
Re:VIEW(TeX)で拡大縮小をされないようwidthとkeepaspectratioパラメータを指定したTeXファイルを作成します[^2]。

```tex:backcover.tex
\includefullpagegraphics[width=\textwidth,keepaspectratio]{./images/cover_b.png}
```

###2.3 config.ymlの編集
pdfmakerセクションでパラメータを与えます。

```yml:config.yml
pdfmaker:
  # 裏表紙追加
  backcover: backcover.tex

```

##3. 参考にさせていただいたWebページ

- [裏表紙を入れるにはどうしたらよいですか？](https://review-knowledge-ja.readthedocs.io/ja/latest/faq/faq-tex.html#732c59539192eec34b69a97f76ff6af5)

[^1]: 幅489ピクセルは、筆者のRe:VIEW環境で拡大縮小なく表示される画像の横幅の値です。
[^2]: Re:VIEW 4.1以降はuse_original_image_sizeをtrueにして画像ファイルを原寸で作成するのが良いのかもしれません。
DBのテーブル名は複数形か？単数形か？

## 目的

久々にテーブル名を考える機会があったので、思考内容を残しておくという意味で。
あくまで個人（しかもDB詳しくない人間）の考えなので、こいつこんな事考えてるんだなー程度に。

## テーブルとして考える

まず、テーブルとして考えてみます。テーブルはレコードの集合です。
ユーザテーブルを考えると以下のようになります。

| id | name | 
|:-:|:-:|
| taro  |  太郎 | 
| goro  | 五郎  |   
|:|:|

太郎はUserです。五郎もUserです。
Userが複数入っている。つまり複数形であるUsersになるのが自然な気がします。

次に関連で考えてみます。
### User
| id | name | 
|:-:|:-:|
| taro  |  太郎 | 

### Activities
| user_id | action| 
|:-:|:-:|
| taro |  踊る | 
| taro | コケる  | 
| taro | 捻挫する | 

ユーザとアクティビティを表すならこんな感じでしょうか。
1対多のデータ構造の場合も複数形が妥当な気がします。

しかし、1-1で関連を持つものや1レコードしかデータが存在しない場合などは単数形でも問題ないと思います。


## SQLで考える
次にSQLベースで考えてみます。

### 単数形の場合
```sql
SELECT *
FROM user
WHERE user.id = 1
```
このWHERE句だけ見ればユーザIDが1、またIDという名前から一意のレコードをとることがすぐに認識できるので複数系より好ましく思えます。
しかし、FROM句を見るとuserという単一のものから絞り込もうとしているように見えて違和感があります。

### 複数形の場合

```sql
SELECT *
FROM users
WHERE users.id = 1
```
FROM句は複数形の方がしっくりきます。

### WEB APIとして考える
WEB APIのエンドポイントも複数形が多用されます。
必ずしもAPIのリソース名 = テーブル名、という訳ではないですが統一されていた方が混乱は少ないと思います。

## ORMを使う場合
基本的にエンティティ名やクラス名は単数形で付けます。
そしてORMによって自動生成されるテーブルの名前はクラス名と同名になります。

しかし、これはORMを使う上での都合でありテーブルの名づけには関係がありません。
エンティティで扱う単位とDBのテーブルで扱う単位が違うので比較対象にもなりません。


## まとめ

- テーブル名は基本的には複数形で良い。
- データ構造から単数形が相応しい場合は単数形の名称を付ける。

といった感じです。

実際にお仕事やチームで開発する時は周りと相談して付けるのをおススメします。

### 余談

英単語には複数形がないものも存在します。使おうとしている単語が存在するかは一度調べておくべき。
誤用だったりスペルミスだったりが意外とあるものです。
Goの学習備忘録 #2 goenvでバージョン管理しようとしたら古いバージョンしか見つかりません

## 概要
Go言語を扱う際に、goenvを導入しようとしたら、古いバージョンしか見つからず詰まった話 

## homebrewでgoenvをダウンロード
macだしhomebrewでいいかなと思い、
`$ brew install goenv`
無事にインストールは完了

インストールできるgolangのバージョンを確認

```bash
$ goenv install -l
=> Available versions:
  1.2.2
  1.3.0
  1.3.1
  :
  :
  1.11.0
  1.11beta2
  1.11beta3
  1.11rc1
  1.11rc2
  1.11.1
  1.11.2
  1.11.3
  1.11.4
  1.12beta1
```

あれ？1.15.2がstable versionになってたから入れたいのにリストにない
あーgoenvのバージョン古いからか

```bash
$ brew upgrade goenv
=> Warning: goenv 1.23.3 is already installed
```

ん？どういうこと？

## goenvでバージョン管理
### homebrewじゃなくてgitでインストール
1.23系から2.0系にする場合は、git cloneで入れればよいという記事がちらほらあったので、gitでインストールする

公式に倣いインストール
`$ git clone https://github.com/syndbg/goenv.git ~/.goenv`


PATHを通す

```bash
export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
eval "$(goenv init -)"
export PATH="$GOROOT/bin:$PATH"
export PATH="$PATH:$GOPATH/bin"
```

PATHを通したところで、コードを実行

```bash

$ go run main.go 
main.go:1499:2: package myProject/mylib is not in GOROOT (/myProject/mylib)
main.go:1500:2: package myProject/mylib/hogehoge is not in GOROOT (myProject/mylib/hogehoge)

$ go build
go: cannot find main module; see 'go help modules'
```

runもbuildもうまく動かない

##　gomod
> Goのコードはライブラリも含めてすべて\$GOPATH/src以下に置くという約束になっている。
> 将来の Go 1.12 からこのやり方を改め、\$GOPATH/srcやvendorは廃止となりGo Modulesという物を採用する事になった。

今回は1.15.2を使用しているので、gomodを作成する必要があるみたい

### golangの設定変更

```bash
go env -w GO111MODULE=on 
```

### gomod作成
プロジェクトの直下で

```bash
$ go mod init myProject
$ go build
$ go run main.go
=> Human!!
```

無事動いた
Unix系とLinux系の差は何か？

**Unix系OS**としてまとめて同じカテゴリーで扱われることが多いが、実際は以下のようにUnix系とLinux系の２つに分けられている。

Unix系OS
　　① Unix系 
　　　　　・ BSD系：SunOS、FreeBSD、MacOS・・・
　　　　　・ 商用Unix系：AIX、HP-UX、Solaris・・・
　　② Linux系
　　　　　・Red Had系：Red Hat Enterprise Linux(RHEL)、CentOS、Fedora・・・
　　　　　・Debian系：Debian、Ubuntu、Linux Mint・・・
　　　　　・Slackware系：Slackware、openSUSE・・・

上記２つの系統の差は何がというと、**`「カーネル部分にLinuxを利用しているかどうか」`**である。

- Unix系：カーネル部分にLinuxを利用していない

- Linux系：カーネル部分にLinuxを利用している

Linuxの各ディストリビューションは、オープンソースとして公開されているLinuxという名のカーネル(OSの中核部分)を基盤として、その上に独自のOSを開発している。
これら各ディストリビューションの名称が、一般的に呼称されているLinuxのOS名(Red HatやDebianやUbuntuなど)となっているのである。
【Vue.js】Promiseのcallback処理にComponentで定義したmethodの使用

## 概要
Vue.jsを使用する際、外部の通信などでPromiseを使用することはあると思います。Promiseを使用する際に、callbackで事前にComponentで定義したメソッドを使おうとしたのですが、うまく呼び出せずにはまったのでメモとして残しておきます。

## はまったこと
以下のようにfirebaseにクエリを投げて、取得した内容を事前に定義したメソッドで下記のようなイメージで処理します。この際に、定義したmethodの`processDoc`がundefinedになってしまいます。

```js

methods: {
  getFirebaseData() {
    const db = firebase.firestore();
    // firestoreの最新情報の取得
    const docRef = db.collection("test_collection").doc("test_doc_id");
      docRef
        .get()
        .then(function(doc) {
          // 受け取ったdocの処理
          this.processDoc(doc);
        })
        .catch(function(error) {
          console.log(error);
        });
  },
  processDoc(doc) {
    // ここでデータを処理
  }
}

```

## 対応
[how to call a method in the Promise in Vue component](https://stackoverflow.com/questions/54442983/how-to-call-a-method-in-the-promise-in-vue-component)によると、コールバックの処理時に、無名関数でなくアロー関数を使う対応が挙げられています。なお、無名関数を使う場合は、事前にPromiseの外側でthisの変数を定義してから関数を呼び出す形になるそうです。アロー関数を使って下記のように書き直すと、methodの呼び出しができました。

```js

methods: {
  getFirebaseData() {
    const db = firebase.firestore();
    // firestoreの最新情報の取得
    const docRef = db.collection("test_collection").doc("test_doc_id");
      docRef
        .get()
        .then((doc) => {
          // 受け取ったdocの処理
          this.processDoc(doc);
        })
        .catch((error) => {
          console.log(error);
        });
  },
  processDoc(doc) {
    // ここでデータを処理
  }
}

```

## なぜか
[Vue.jsに書いてある「アロー関数は、this が期待する Vue インスタンスではなく・・・」とは？](https://qiita.com/drafts/710a757031f26bf79ac0/edit)に解説されていますが、無名関数とアロー関数で同じ機能と思いきやthisの取り扱いが変わってきます。従来の無名関数では、「それが何を指し示すかは文脈によって変化する」、「そのメソッドにアクセスしたオブジェクト（インスタンス）が、this」となるのに対し「アロー関数は呼び出された場所をthisとする」といった違いがあります。
Promiseのコールバックにおいては、無名関数だと指し示されるオブジェクトが自分自身なので、その外のmethodが参照できないです。アロー関数だと呼び出し元からthisのスコープが引き継がれるので、methodも参照ができるわけです。
pandas.DataFrame.locの使い方まとめ

「loc」は、DataFrameの内で条件を満たした行、列を抽出することができます。pandasを利用していると頻繁に出てくる「loc」ですが、データの指定方法にバリエーションがあるので、その辺をまとめていきたいと思います。

# データ指定について
locは、大きく分けると以下のデータ指定が可能です。

- 単一ラベル
- ラベルリスト
- ラベルのスライスオブジェクト
- 真偽値リスト
- 条件式の指定

色々な使い方がありますね・・・  (゜_゜)
プログラムを書くときも注意が必要ですが、読むときにどのパターンで実装されているか冷静に見分けないと、「？？？？」ってなりそうです。それぞれのサンプルコードを書いてみて動作を確認してみようと思います。

# 実際に使ってみた
今回動作確認で利用するデータは自分で作ったものです。

```python
import pandas as pd
loc_sample_data = pd.read_csv("loc_sample_data.csv",index_col="item_name")
loc_sample_data.head()
```
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/ff4bae80-cb92-ddb2-437f-54aec9068903.jpeg)

行インデックスはitem_name、列はprice、stock、producing_areaで構成されています。

## 単一インデックスラベルの指定
抽出したい行のインデックスラベル（単一）を指定してデータを抽出します。
今回はitemCの抽出をしていきます。

```python
loc_sample_data.loc["itemC"]
```
![キャプチャ1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/3fc5de88-b297-89f6-740f-e558d7189903.jpeg)

抽出できました。抽出されたデータはSeries型です。

## インデックスラベルリストの指定
上の例は単一行のみの抽出ですが、複数行を指定/抽出することが可能です。複数指定する場合はリストで指定します。
今度はitemA、itemDの抽出をしていきます。

```python
loc_sample_data.loc[["itemA", "itemD"]]
```
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/51fa97a6-17ce-ff2f-c2ea-b08f839e2079.jpeg)

抽出できました。抽出されたデータはDataFrame型でした。

## 単一の行ラベル、列ラベルの指定
行と列のそれぞれのラベルを指定してデータを抽出することも可能です。今回は行→itemB、列→producing_areaを指定してデータ抽出します。

```python
loc_sample_data.loc["itemB", "producing_area"]
```
![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/8a8950fa-8d83-8e68-b619-a71bb0777520.jpeg)
抽出できました。抽出されたデータstr型です。今回の例では抽出されたデータstr型ですが、これはDataFrame内に格納されているデータの内容で変わります。

## スライスを利用した行ラベル、列ラベルの指定
スライスを利用して行、列を複数指定することができます。これを利用してitemA、itemBのpriceを抽出します。

```python
loc_sample_data.loc["itemA":"itemB","price"]
```
![キャプチャ4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/97a199fa-7af1-785c-2442-6ca50eabe58f.jpeg)

抽出できました。これ使うかな・・・？

## 真偽値リストを使ったデータ指定
抽出元のデータフレームと同じ長さ（行数）の真偽値リストを指定することで、Trueの行のみを抽出することができます。今回はitemBとitemDを抽出してみる。

```python
loc_sample_data.loc[[False, True, False, True]]
```
![キャプチャ5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/16290adb-fdb0-1b25-b9fc-82b750d723d4.jpeg)
抽出できました。これ単発だと使う機会なさそうですが、事前に各行ごとに抽出条件を満たすかどうかを判定し、リストを作成したら使い道がありそうですね。

## 条件式を利用したデータ指定
一番使いそうなやつですね。今回はpriceが500より大きいデータ（itemC、itemD）を抽出してみます。

```python
loc_sample_data.loc[loc_sample_data["price"] > 500]
```
![キャプチャ6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/c5464521-dade-2515-ce20-fe8dc132d30f.jpeg)

抽出できました。やっぱこれ単体だったら一番使いそう。

## 条件式を利用して特定列だけ抽出
さっきの条件式に加えて、特定の列を指定して抽出します。条件は先ほど同様ですが、今回はproducing_area列のみを抽出します。

```python
loc_sample_data.loc[loc_sample_data["price"] > 500, ["producing_area"]]
```
![キャプチャ7.JdPG.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541501/a365d499-e6a8-34cd-6f47-fb286d38715c.jpeg)

# 最後に
色々使い方ありますが、必ず身に付けた方が良いのは条件式を利用したデータ抽出ですかね。今回ちょっと長くて疲れたので終わりにします。それではまた次回の投稿でー！
ダイクストラ法：ソフトウェアデザイン 10月号のけんちょんさんの記事内容を元にPythonでAOJの問題を問いてみた

#解いた問題
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_2_A

#ソース


+ AOJの問題は始点の指定があることに注意
+ 蟻本ではフラグを使って更新の有無を確認していたが、けんちょんさんのやり方は、更新されなければ確定（優先度付きキューに入れない）という手法。
+ 優先度付きキューをpopして取得した頂点（スタートからの距離が最小の頂点）から探索をする。

```Python
import heapq
INF = 10**10

class Edge:
    to = -1
    w = -1
    def __init__(self, to, w):
        self.to = to
        self.w = w

def Dijkstra(Graph, s):
    dist = [INF] * len(Graph)
    dist[s] = 0

    prev = [-1] * len(Graph)

    #スタート頂点をキューに入れる
    #[該当頂点までの最短距離（現時点）,該当頂点のインデックス]
    que = [[0,s]]

    #優先度付きキューに変換
    heapq.heapify(que)

    while len(que) > 0:
        # 優先度付きキューの先頭の要素を取り出す
        # vは頂点番号, dは該当頂点までの現在の最短距離
        p = heapq.heappop(que)
        v = p[1]
        d = p[0]

        #ソフトウェアデザインだと以下処理があるが不要？
        #必要性がよくわからん
        #if d > dist[v]:
        #   continue

        #該当頂点vから行くことのできる頂点毎に距離を計算
        for e in Graph[v]:
            #最短距離を更新できない場合は何もしない
            if dist[v] + e.w >= dist[e.to] :
                continue

            #以下は、最短距離を更新できた場合

            #優先度付きキューに行先頂点の情報をプッシュ
            heapq.heappush(que,[dist[v] + e.w, e.to])

            #行先の最短距離を更新
            dist[e.to] = dist[v] + e.w

            #行先の前のノードを記憶
            #AOJの問題では使わない
            prev[e.to] = v

    for d in dist:
        if d == INF:
            print("INF")
        else:
            print(d)

    return

def main():
    n, m, s = map(int, input().split())
    Graph =  [[] for j in range(n)]
    for i in range(m):
        a, b, w = map(int, input().split())
        Graph[a].append(Edge(b, w))
        #AOJの問題は有効グラフ（http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_2_A）
        #Graph[b].append(Edge(a, w))

    Dijkstra(Graph, s)

main()
```
GitHub Actionsで Self Hostする際の注意点

# GitHub Actionsをセフルホストする際の注意メモ

GitHub Actionsめちゃくちゃ便利ですよね。自分もプロジェクトでは利用させてもらってます。ただ、無料プランを超えてしまうのでセルフホストでコストを節約しようと試みています。

その際に注意する点があったのでメモがてらこちらにまとめます。

## 権限設定をしよう
https://github.com/actions/checkout/issues/211#issuecomment-611986243
問題の経緯はissueを見てもらうこととして、権限設定の問題があるのでその対応策を忍ばせましょう。

## docker buildをする際は docker imageを削除するコマンドをしのばせよう
Fargate/ECSへデプロイするためにdocker imageをビルドしてると容量を食いますので、その対応をしましょう！


# サンプルコード
```
on:
  push:
    branches:
      - master

name: Deploy to Some Environment

jobs:
  deploy:
    name: Deploy
    runs-on: self-hosted

    steps:
      - name: Setup
        run: |
          sudo chown -R ec2-user. /home/ec2-user/actions-runner/_work/some_project_name/*
          docker image prune --force
```
Google App EngineにLaravelをデプロイしようとしてハマったのでメモ

# 環境
PHP 7.3
Laravel 7.4
React 16.10

# 設定ファイル
gcloud app deploy 時に利用する設定ファイルです。
一部省略してます。また、余計な物が入ってるかもしれません。

```yaml:app.yaml

env: standard
instance_class: F1

env_variables:
    APP_NAME: Laravel Project
    APP_ENV: *
    APP_KEY: *
    APP_DEBUG: true
    APP_STORAGE: /tmp
    VIEW_COMPILED_PATH: /tmp

    LOG_CHANNEL: stackdriver // googleのstackdriverを使うため

    BROADCAST_DRIVER: log
    CACHE_DRIVER: file
    QUEUE_CONNECTION: sync
    SESSION_DRIVER: cookie //stackdriver時にはcookieにする必要あり
    SESSION_LIFETIME: 120


handlers:
    # Serve images as static resources.
    - url: /css
      static_dir: public/css
    - url: /js
      static_dir: public/js
    - url: /fonts
      static_dir: public/fonts
    - url: /images/(.*)
      static_files: public/images/\1
      upload: .+\.(gif|png|jpg)$

    # Serve your app through a front controller at index.php or public/index.php.
    - url: .*
      script: auto

automatic_scaling:
    min_idle_instances: 1
    max_idle_instances: 1
    max_pending_latency: 2000ms

```

# エラー別対応
### There is no existing directory at "/var/www/storage/logs" and its not buildable: Read-only file system
未確認ですが、GAE環境のこのディレクトリはRead only環境となっているのではと推測しました。今回は次の設定で利用先のディレクトリを変更して回避しました。

```yaml

APP_STORAGE: /tmp
```

### Class 'Facade\Ignition\IgnitionServiceProvider' not found
依存関係の問題です。
dev環境とprod環境で設定を変えている場合は、composerで依存関係を修正して下さい。
基本的には、dev環境とprod環境の両方でファイルを使えるように設定すればOKです。
また、依存関係を変更した後はcasheを削除してから再実行するようにしてください。（これではまってました）

詳細は下記のURLをご覧ください。
[stackoverflow laravelをGAEにデプロイした時のエラー](https://stackoverflow.com/questions/58087153/laravel-with-app-engine-standard-class-facade-ignition-ignitionserviceprovider)
   

### Uncaught SyntaxError: Unexpected token <
ビルドしたフロントのファイル(app.js)が読み込めなかったために起きた事象です。
app.yamlのhandlerを適切に設定していれば回避できました。

```yaml
handlers:
    # Serve images as static resources.
    - url: /css    // <- ここで読み込むファイルの種類を設定
      static_dir: public/css   // <- 実際の置き場所を指定
    - url: /js
      static_dir: public/js
    - url: /fonts
      static_dir: public/fonts
    - url: /images/(.*)
      static_files: public/images/\1
      upload: .+\.(gif|png|jpg)$
```

正直細かいところが分からなかったので詳細は公式リファレンスをご参照ください。
[GCPリファレンス GAEのapp.yamlの設定 PHP7](https://cloud.google.com/appengine/docs/standard/php7/config/appref?hl=ja)
Wordpressで構築済みのWebサイトにEpsilonの決済システムを組み込んだメモ

# 状況
* すでに構築済みのWorpdress上のWebサイト
* クレジットカードの決済を追加したい
* Epsilonとすでに契約済みで決済代行の選択の余地なし
* リンク決済を使用したい

という制限された状態。

# 調査

EpsilonがPHPのサンプルコードを提供していたのでそれを活用。 

必要なモジュールを個々でダウンロードしサーバー上へ設置。
（訳があって個々にしています）

### 使用したモジュール

Epsilonのサンプルコードで以下を使っていたので同じものを使用

* HTTP_Request2 (https://pear.php.net/package/HTTP_Request2/download)
* Net_URL2 (https://pear.php.net/package/Net_URL2/download/)
* XML_Parser (https://pear.php.net/package/XML_Parser/download)
* XML_Serializer (https://pear.php.net/package/XML_Serializer/download)


```
Wordpressのディレクトリ
  └ wp-content
      └ themes
         └ インストールしたテーマ
             L epsilon（作成）
                 L ここにモジュール設置
                 L ここに決済用PHPを設置
```

# 困ったこと
#### Wordpressで自作PHPを実行する方法を知らない

これはサーチしたらたくさん情報があったので簡単に解決。

function.phpに以下のコードを追加しショートコードを使用可能にする。

```
function Include_my_php($params = array()) {
    extract(shortcode_atts(array(
        'file' => 'sample'
    ), $params));
    ob_start();
    include(get_theme_root() . '/' . get_template() . "/epsilon/$file.php");
    return ob_get_clean();
}
add_shortcode('credit', 'Include_my_php');
```

このショートコードをWordpressの記事に貼り付けで解決。


#### Wordpress用に作成されたテーマのPHPを修正しなければいけない

クレジット決済へ飛ばすためのボタンをすでに存在するページに追加をしたい。

Wordpress用のコードを解析。
よくわからなかったけど、とりあえず該当のページのソースは発見。

var_dumpやexitなんかで動かしたり、止めたりしてなんとなく理解。

ボタンを設置し、submit先に上記のショートコードが設置されたURLを指定。

うまく動いた(^^)


# いざ動作確認

### エラー①
> Warning: require_once(Net/URL2.php): failed to open stream: No such file or directory in /home/javijavi/www/central/lifewave/wp-content/themes/phlox-pro/epsilon/HTTP/Request2.php on line 24

URL2.phpが見つからないと怒られる。
ディレクトリは間違っていないのに。。。

##### 解決
特殊なディレクトリ構造にしているためパスをインクルードする必要があった。

```
$path = dirname(__FILE__);
set_include_path(get_include_path().PATH_SEPARATOR.$path);
```

これを決済用PHPに追加で解決。


### エラー②
> string(63) "エラー : 908このCGIを実行する権限がありません"

無事PHPは実行されたようだがEpsilon側から怒られる。

##### 解決

Epsilonの設定で「オーダー情報発信元ホスト情報」をホスト名にしており逆引きが出来ていなかったらしい。なのでIPアドレスへ変更。
参考ページ　https://02kaz.x0.com/it/ec2ep/


### 無事完了

あとはhtml(レイアウト)やパラメータを修正。

この他にもつまずいた箇所があった気がするけど忘れたので割愛。

仕組みが分かれば意外と簡単でした。