OmniAICreator/Qiita-1.07M huggingface dataset:
Azure DevOps で使用する iOS の証明書などの保存方法

#はじめに

Pipelines で iOS や Android のビルドを行うにあたって P12 ファイルやプロビジョニングプロファイル、Keystore などが必要になります。
これらを特定の端末でビルドする場合であれば端末に入れておけばいいのですが、Pipelines を利用する場合は特定の端末に入れることが出来ません。
また、Microsoft-hosted 環境の場合は予めインストールしておくということができないため、Pipelines 上でインストール作業を行う必要があります。

それを実現するのが Pipelines の『**セキュアファイルライブラリ**』です。

セキュアファイルライブラリは証明書などを予め保管しておいて、ビルド時にそれを参照するような仕組みです。


#ゴール

- 証明書類を Pipelines 上に保管
- 自動ビルドの際に証明書を参照可能

#証明書の登録

各プロジェクトの左のサイドバーにある『Pipeliens > Library』を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/9f33a201-abfa-0bf1-374c-1a004239e40a.png)

そうすると下のような画面になりますので、ここで上部にある『Secure files』を選択し中央部にある『+Secure file』を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/9117cccb-f668-ffea-452a-6863b5731d0b.png)

証明書のアップロード画面になりますので、ここで用意しておいた P12 ファイルやプロビジョニングプロファイル、Keystore ファイルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/174fb35b-252f-673d-4e1b-1d092a01d5cf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/95bc9a69-5f93-7368-63c9-effdfbb5a9e2.png)

正常なファイルが選択されると登録されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/bab928c3-54ce-df16-91b2-979373a9f630.png)

ただし、このままではファイルが登録されただけで、実際に Pipelines で利用するときにはこのファイルへのアクセス許可が必要になります。
各 Pipelines で証明書にアクセスするような YAML を書いた場合、以下のようなメッセージが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/51ee22a6-9043-7389-940e-7043bc838768.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/058f364f-2354-f21a-26fd-805315419288.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/7d0bba71-d2a2-a701-4dd5-419f21944085.png)

必要なファイルへのアクセス許可を与えることで YAML 内でファイルにアクセスすることが可能になります。

また、それぞれのファイルにはプロパティ設定が可能でファイル名やアクセス権なども変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19224/ed1a6548-3e0e-45e9-d27a-bff321612f7f.png)

#おわりに

この証明書の保存のメリットとしてはファイル管理がブラウザだけで済むということもありますし参照が非常に簡単です。
証明書類は意外と年に１回だけということもあるので忘れがちなのですが、これですごく楽になるのではないでしょうか。

ダウンロードまで出来れば保管場所としては完璧なんですけどね。
【環境構築】WindowsTerminal & GitBash

# この記事 is 何？
windows10homeにWindowsTerminalインストールして、そこからGitBash使えるようにした手順。
忘れそうなのでメモった。

書いた日：2020/06/27

# 各種インストール
## WindowsTerminal
[公式ドキュメント](https://docs.microsoft.com/ja-jp/windows/terminal/get-started) 参照。

## git for windows
[こちら](https://git-scm.com/download/win) からダウンロード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393020/f2471a12-f583-59e0-264a-d4c3f740ff9a.png)
自動でダウンロードされるらしい。
このときは自動ダウンロードされなかったので、**Click here to download manually**をクリックして手動でexe取得。

インストール時の設定はすべてデフォルトにしました。


# 設定
## WindowsTerminal
### フォントの指定
せっかくだからプログラミングフォントにしようぜー
お好みのフォントをインストールして、settings.jsonを修正。

`"profiles":{"defaults":[ ]}`の中に書けば、全てのlistに対して設定が適用される。
ウチは [Source Han Code JP(源ノ角ゴシック)](https://github.com/adobe-fonts/source-han-code-jp/blob/master/README-JP.md)にしてます。

``` JSON:settings.json
"fontFace": "Source Han Code JP",
"fontSize": 10
```

### GitBashを使えるようにする
1. powershell開いて、guidを新規取得

    ``` powershell
    [guid]::NewGuid()
    ```

2. settings.json修正
`"profiles":{"list":[ ]}`の中にPowerShallとかの設定があるはずなので、コピペしてGitBashの設定を作る。
※ guidは 1 で取得したヤツを使う。
こんな感じに設定した。

    ``` JSON:settings.json
            {
                "guid" : "{d8b7db0c-378a-4605-abca-65f46997540b}",
                "name" : "Git Bash",
                "commandline" : "C:\\Program Files\\Git\\bin\\bash.exe --login -i",
                "hidden": false,
                "acrylicOpacity" : 0.5,
                "useAcrylic" : true,
                "icon" : "C:\\Program Files\\Git\\mingw64\\share\\git\\git-for-windows.ico",
                "startingDirectory" : "D:\\git/"
            }
    ```

## GitBash
### 日本語対応
日本語のファイルが文字化けするので、`~/.bashrc`にロケール設定を書いとく。
`~/.bashrc`は無ければ作る。

``` sh
export LANG=ja_JP.UTF-8
```

## git config
GitBash開いて、とりあえず下の2つ(commit時のユーザー名とメアド)だけ設定。

``` bash:.gitconfig
$ git config --global user.name "ユーザー名"
$ git config --global user.email "メールアドレス"
```
ChromeOSのLinux betaでDebian以外のディストリビューションを使う

ChromeOSでLinuxを動かすには、以前にはDeveloper Modeにして[crouton](https://github.com/dnschneid/crouton)を使う必要がありました。現在（2020/06/27）、ChromeOSでは[Linux (beta)](https://support.google.com/chromebook/answer/9145439?hl=en)という機能でVM上でLXDを使ってLinuxを動かす機能が搭載されました。

現在（Version 84.0.4147.64 beta）は、まだこの機能ではDebianのディストリビューション（のコンテナ）しか提供されていませんが、LXDを直接操作することで、任意のディストリビューションを実行することもできます。penguinという名前のコンテナとして用意しておけば、認識するようです

参考元の記事 
https://www.reddit.com/r/Crostini/wiki/howto/run-ubuntu

しかし、1つだけこの機能は、cros-guest-tools、cros-ui-configというGoogleが提供するパッケージに依存しています（機能的にはVirtualBoxのGuest Addition的なの）。このパッケージは現在Debianでしか提供されていないようです。そのため、前述の記事ではDebianパッケージからコードを取り出して改変することで、実現しています。

## 構築手順

Version 84.0.4147.64 beta、Ubuntu 20.04で実行する手順を示します。

### コンテナの作成まで

ChromeOSのSettingsを開き、Linux betaをTurn onし、ターミナルにログインできるところまですすめる。

Chromeを開き、Ctrl+Alt+Tを押し、ターミナルを開き、以下のコマンドでVMに入る。

```
vmc start termina
```

元のDebianのコンテナを一旦止めて、別の名前に変更する。

```
lxc stop penguin --force
lxc rename penguin debian
```

起動したいディストロのコンテナをpenguinという名前で起動する。

```
lxc launch ubuntu:20.04 penguin
```

以後、以下のコマンドでpenguinコンテナのrootになって作業する

```
lxc exec penguin -- bash
```

### デフォルトユーザ名の変更

デフォルトユーザ名がGoogleアカウントの名前になるので、変更する。

```
mkdir /home/nnyn
usermod -l nnyn -d /home/nnyn ubuntu nnyn
groupmod -n nnyn ubuntu
```

### パッケージのインストール

既存パッケージのアップデートと、作業に使うツールをインストールする。

```
apt update
apt upgrade
apt install binutils
```

ChromeOSのツールのリポジトリを追加する。

```
echo "deb https://storage.googleapis.com/cros-packages buster main" > /etc/apt/sources.list.d/cros.list
if [ -f /dev/.cros_milestone ]; then sudo sed -i "s?packages?packages/$(cat /dev/.cros_milestone)?" /etc/apt/sources.list.d/cros.list; fi
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 04EE7237B7D453EC
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 7638D0442B90D010
apt update
```

cros-ui-configというパッケージを取り出して、競合するパッケージを取り除く。そして、cros-guest-tools cros-ui-configをインストールする。

```
apt download cros-ui-config # ignore any warning messages
ar x cros-ui-config_0.12_all.deb data.tar.gz
gunzip data.tar.gz
tar f data.tar --delete ./etc/gtk-3.0/settings.ini
gzip data.tar
ar r cros-ui-config_0.12_all.deb data.tar.gz
rm -rf data.tar.gz
apt install cros-guest-tools ./cros-ui-config_0.12_all.deb
```

以下のパケケージもインストールすると、GUIアプリでマウスカーソルが小さくなりすぎるのを防ぐ。

```
apt install adwaita-icon-theme-full
```

### 再起動する

一度、コンテナを終了させる。

```
shutdown -h now
```

このあと、Linux betaを再度起動させるために、一度ChromeOSをシャットダウンして再起動する。

ChromeOSのランチャーからLinux Apps->Terminalを選択する。すると、そのコンテナ上で実行されます。
NVIDIA container toolkitを使って、dockerのコンテナ上でcudaを動かす

## 概要
docker上でcudaを動かしたいと思うときがあったので、その方法を調べたところnvidia container toolkitを使えばいいとわかったので、その手順をまとめました。nvidia-dockerやnvidia-docker2の進化系がnvidia container toolkitです。詳しくは[こちら](https://qiita.com/ksasaki/items/b20a785e1a0f610efa08)のリンクにまとめられています。
![Screenshot from 2020-06-27 13-42-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663246/576f8d8b-67e6-99ea-7635-0dbd2a09b17d.png)
https://github.com/NVIDIA/nvidia-docker

## 目的
nvidia container tookitを使って、dockerのコンテナ上でcuda(10.1)を動かします。また、opencvとpytorchもコンテナ上に入れます。


## 環境
- Ubuntu 18.04
- docker 19.03
- nvidia driver 450.36 


## 手順
### 1. nvidia container toolkitをインストールする
[公式](https://github.com/NVIDIA/nvidia-docker)通りに進めます。まずは、nvidia container toolkitのインストールです。

```
# Add the package repositories
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
```


###2. cudaの動作確認

下のコマンドを打てば、自分の入れたいcudaが入っている仮想環境を動かすことができます。今回は、cuda10.1&ubutu18.04のイメージをもとに作成しました。[こちら](https://hub.docker.com/r/nvidia/cuda/tags)にcudaのイメージの一覧があるので、自分の作りたい環境に合わせて、コマンドのnvidia/cuda:10.1-base-ubuntu18.04の箇所を入れ替えてください。また、gpusのところで使いたいgpusの個数を選べます。今回はgpuを全て使うallとしていますが、例えばgpuを4個中2個使いたいときは--gpus 2とすれば大丈夫です。

```
docker run --gpus all nvidia/cuda:10.1-base-ubuntu18.04 nvidia-smi
```



### 3. pytorchのイメージを入手する

```
docker pull pytorch/pytorch
```

### 4. コンテナを作成、起動する
ローカルのディレクトリをdockerのディレクトリにマウントします。

```
docker run -it --gpus all -v ホストpcのディレクトリ:docker上のディレクトリ --shm-size 16G --name ml pytorch/pytorch
```

-itでそのままbashを起動します。--gpusで使うgpuの数を決められます。-vでホストpcのディレクトリをdockerのディレクトリにマウントできます。--shm-sizeはコンテナに割り当てるメモリのサイズです。--nameはコンテナ名です。自由に決められます。pytorch/pytorchはpullしてきたimageの名前です。bashが起動してlsコマンドを打つと、ローカルのディレクトリがマウントされていることが確認できると思います。

### 5. opencvをインストール
```
pip install opencv-python
```
>ImportError: libgthread-2.0.so.0: cannot open shared object file: No such file or directory

import cv2したときに上のようなエラーが出る場合は、下のコマンドを打てば大丈夫だと思います。

```
apt update
apt-get install -y libglib2.0-0 libsm6 libxrender1 libxext6
```

### まとめ
nvidia container toolkitを使えばローカルを汚さずに環境構築できるし、楽チン。

**間違いや質問、ご意見等ありましたらお気軽にコメントください。頑張って答えますので(笑)。**
ターミナルでPATHをunsetしてしまった。 解決済♬

今回は、PATHがよくわからず、まあ一度全て消してみるか！と思い

＄unset PATHをしてしまいました！！！！
lsやpwdなどが全て使用出来なくなり大変焦りましたが、、、、。


＿＿解決策＿＿
コマンドを打っただけであれば、そのシェル限りなので、いちどウィンドウを閉じて、開き直せば大丈夫です♬
JUCE でかっこいいボタンを描く方法

<img width="640" alt="スクリーンショット 2020-06-27 13.08.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/944/0ff0aa6b-3710-ef62-45d4-2523aa4797b7.png">

このような CSS でよく見る感じのかっこいいボタンを JUCE で描くには以下のようにします。[^reference-code]

[^reference-code]: この描画処理は [nanogui](https://github.com/wjakob/nanogui) というプロジェクトのボタン描画処理を参考にしました。

1. 背景のハイライト色でボタン背景を描画
2. 背景色でボタン背景を描画。このときに下側にボタン背景のハイライトが見えるようにする。
3. 背景より小さい範囲に、ボタン前面のハイライト色でボタンを描画
4. ボタン前面を緩やかなグラデーションで描画。このときに上側にボタンのハイライトが見えるようにする。
5. テキストをハイライト色で描画
6. テキストを描画。このときに上側にテキストのハイライトが見えるようにする。

コードで書くと以下のようになります。

```cpp
    juce::Graphics &g = /*...*/;
    int w = /*ボタンの幅*/; 
    int h = /*ボタンの高さ*/;

    // ボタン背景のハイライトを描画する
    g.setColour(background_highlight_colour);
    g.fillRoundedRectangle(0, 0, w, h, round);

    // ボタン背景を描画する。
    // （ハイライト部分を見せるために高さを 1px 減らしている）
    g.setColour(background_colour);
    g.fillRoundedRectangle(0, 0, w, h-1, round);

    // ボタン前面のハイライトを描画する。
    // （ボタン背景を見せるために、
    // 　background_colour で描画した範囲から 1 ずつ減らしている）
    g.setColour(front_highlight_colour);
    g.fillRoundedRectangle(1, 1, w-2, h-3, round);

    // ボタン前面を描画する。
    // （ボタン前面のハイライトを描画するために、
    // 　front_highlight_colour で描画した範囲より 1px 下に描画している）
    juce::ColourGradient grad(grad_top_side_colour,
                              0.0f, 0.0f,
                              grad_bottom_side_colour,
                              0.0f, (float)h,
                              false);
    g.setGradientFill(grad);
    g.fillRoundedRectangle(1, 2, w - 2, h - 4, round);

    // テキストのハイライトを描画する
    g.setColour(text_highlight_colour);
    g.drawText(getButtonText(), 0, 0, w, h - 2, juce::Justification::centred);

    // テキストを描画する
    // （テキストのハイライトを描画するために、
    //   text_highlight_colour で描画したものより 1px 下に描画している）
    g.setColour(text_colour);
    g.drawText(getButtonText(), 0, 0, w, h, juce::Justification::centred);
```

[juce::Button](https://docs.juce.com/master/classButton.html) クラスを継承したクラスで [paintButton()](https://docs.juce.com/master/classButton.html#a5d9f37df2a5b19df32fe1c68867eafd0) 仮想関数をオーバーライドして、この描画処理を行うように実装すれば、冒頭に貼ったようなボタンが描画できます。

この仕組みをもう少し整備した CoolButton クラスと、 CoolButton クラスの動作を確認できるサンプルプロジェクトを公開しているので、試してみたい方はここから clone してください。

https://github.com/hotwatermorning/juce-cool-button
Matplotlibによるpythonのグラフ作成マニュアル。

#超基本Matplotlibのグラフ生成

コピペして自分用に変えて使ってください。この記事はxの一次関数の描画です。

1.ライブラリーインポート

```.py
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
```
2.式記述

連続的なx値をnp.arangeで定義します。
arangeでは決めた範囲での等差数列のデータをリストに格納します。
第一引数:範囲の最小
第二引数：範囲の最大
第三引数：等差
第三引数を小さくすればするほどグラフが滑らかになります。

```.py
x = np.arange(1.0,5.0,1) #1から5までの0.01刻みの等差数列
y = np.log(x) #引数xのy関数 #例:対数
```

3,グラフの描写

グラフの描写にはmatplotlib.pylotの関数を使用します。事前に、インポートをしておきます。
pylotモジュールはグラフの描画を行うためのインターフェイスです。グラフを描画するための関数群がまとめられています。
グラフの描画は２通りあります。

①　グラフの土台になるオブジェクトを生成し、pyplotのメソッドを使用して、折れ線や棒グラフなどのグラフ要素、
　　さらに軸のラベルなどをグラフに必要な描画していく方法
②　plotモジュールの関数群を直接、呼び出してグラフ要素を描画していく方法

今回はシンプルな描写なため、後者の方法です。
簡単な描写の例です。流れとしては

①　pylotライブラリーの関数を呼び出し、グラフの設定。
②　①で設定したグラフ情報をshow関数で描画する。

```.py
#グラフ情報を設定
#水平(x軸)と垂直(y)軸の値を代入　、グラフの色の設定、
plt.plot(x,y,color = "red")
plt.ylabel('y-label') #x軸のタイトル
plt.xlabel('x-label') #y軸のタイトル

#グラフ情報を描画
plt.show()
```
実行結果
![スクリーンショット 2020-06-27 13.29.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526754/ef82226b-c76c-ccaa-8f42-0d023ae63729.png)


色のデフォルトは黒なので、記述しなかったら黒になります。
もっと細かくグラフの設定描画はできますが、この様にシンプルなコードで一次関数を描画できます。
文系卒だけどいきなりRuby on Railsの勉強をはじめてみた #5 レイアウトを作成する

いよいよチュートリアルも5章に突入。
社会人で本業もありながらのプログラミング勉強はガチできつい。
きついけど、とりあえずちょっとづつでもいいので進めていく。

#第5章 レイアウトを作成する
なにやら、レイアウトを追加したり修正したりするらしい。
#5.1 構造を追加する
読み進めていると、文章の9割が聞いたこともない単語で構成されており、心が折れそうになる。
わからない単語は調べつつ、なんとなく理解していく。

>ワイヤーフレームとは、webページのレイアウトを定める設計図のことです。
webサイトの制作現場で聞かないことがない、といえる単語であり、サイト制作において決して欠かせない要素です。

どうやらこの章ではWebサイトの見た目をきれいにしていくっぽい。ちょっと楽しそう。

ブログをちょいちょい書いたりしているので、`header`や`div`はまあなんとなくわかるレベル。

`link_to`では、リンクを生成することができるっぽい。

演習。

>Webページと言ったらネコ画像、というぐらいにはWebにはネコ画像が溢れていますよね。リスト 5.4のコマンドを使って、図 5.3のネコ画像をダウンロードしてきましょう8 。
>>コピペして実行すればok

>mvコマンドを使って、ダウンロードしたkitten.jpgファイルを適切なアセットディレクトリに移動してください (参考: 5.2.1)。
>>`mv ファイル名 移動先のパス`でok
mvの構文はぐぐった。

>image_tagを使って、kitten.jpg画像を表示してみてください (図 5.4)。
>>`<%= link_to image_tag("kitten.jpg", alt: "hoge"),
            'hoge' %>`
でok
hogeの使い方ってこれでいいのかな。

そして、突然`Bootstrap`という単語が出てくる。

>BootstrapはTwitter社が開発したCSSの「フレームワーク」です。通常CSSを書く場合、全てのスタイルを自分で作っていく必要がありますが、このフレームワークにはよく使われるスタイルがあらかじめ定義してあるので、ルールに沿って利用するだけで整ったデザインのページを作成できます。

Twitter社が開発したんか、という感じ。

Gemを書き換え、`bundle install`をする。
もしかして、`bundle install`ってgemファイルに記載したものをインストールするための呪文なのか。

ちなみに、演習5.1.3はむずすぎたからすべてコピペした。
パーシャルがなにかもわかっていない。

## 5.2 Sassとアセットパイプライン
アセットパイプラインの最大のメリットの1つは**本番のアプリケーションで効率的になるように最適化されたアセットも自動的に生成されること**らしい。

Sassってなんのことかと思っていたけど、CSSの上位互換みたいなものっぽい。

ネストという構造でコードを書くと、より簡潔になる。
とにかくプログラミングは「重複」を嫌うようだ。
のちに出てくる「変数」という機能もコードの重複を避けるためにあるように思える。

## 5.3 レイアウトのリンク
この章ではリンクを書き換えることで、異なるページへの導線が確保できるようになる。

この章をやっているうちに「そういえば、routes.rbってなんのためにあるんだっけ」と思い始めた。
調べると、ルーティングを登録するファイルとのこと。
ルーティングとは、ブラウザからRailsアプリへ渡される情報をもとに、登録された動きを行わせるための振り分け設定のことらしい。
だから、`rails s`をしてlocalを開くと、勝手にHomeに飛ばされていたのか。という時代遅れの発見をした。

## 5.4 ユーザー登録:最初のステップ
この章では、ユーザー登録用のページを用意する。
そして、ホームページからユーザー登録用ページまではリンクから飛べるようにしておく。

ここまでチュートリアルをやってみて、なんとなくroutes.rbと各ページの関係を理解してきた感はあるけど、何周もやらないと完璧には理解できないだろう感がある。
【UE4：View】UnityでいうSceneViewどこ？

Unityだと再生中でもSceneViewで自由にカメラ動かしてオブジェクトの確認できるんだけど
UE4しばらく触っててそれをどうやるのかがわからなかった

Toolbarの一番右に「Eject」ってボタンがあって「Eject - Possess」で
UnityでいうGameViewとSceneViewの切り替えができた（同時に表示するのはできない？）
![SceneView.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216261/1aeda445-42e6-490d-84eb-6f7542eca750.png)
ショートカット「F8」押下でも切り替えできた
Arduino IDEで直接バイナリファイルをROMに取り込む

# どんな内容か？
前回WioTerminalで[Jpeg画像をSDカード無で取り込む方法](https://qiita.com/carcon999/items/4fbcef49bcb667737390)について記述しましたが、@fujitanozomuさんからコメントで、『インラインアセンブラで書けるよ』と情報をいただいたので試してみました。（fujitaさんありがとうございます。）
確かに、コードがスッキリしますし画像のように大きなデータの場合は、このような記述が良さそうです。
今回、WioTerminalを利用していますが、もちろん他のArduinoでも利用できますし応用範囲は広いのではないかと思います。

# プログラムについて
前回は、Jpeg画像を使ってサンプル作りましたが、利用している[LovyanGFXライブラリ](https://platformio.org/lib/show/7359/LovyanGFX)は、PNGの表示もサポートしていることに気づいたので今回はPNGにしてみました。

```c:WioMemoryPng.ino
#include "arduino.h"

// https://platformio.org/lib/show/7359/LovyanGFX
#include <LGFX_TFT_eSPI.hpp>

static TFT_eSPI tft;

#define IMG_WIDTH  (320)
#define IMG_HEIGHT (240)

// これが重要なインラインアセンブラで指定したファイルをROMに配置するコードです。
#define  INC_BIN(file, sym) \
__asm(\
  ".globl " #sym "\n"\
  #sym ":\n"\
  ".incbin " #file "\n"\
  ".global _sizeof_" #sym "\n"\
  ".set _sizeof_" #sym ", . - " #sym "\n"\
);

extern const uint8_t png[], _sizeof_png[];

// ここは、各自の環境に合わせてフルパスを記述する必要がある。（相対パスだとファイルが見つからない）
INC_BIN("C:\\Projects\\GitHub\\WioMemoryPng\\data\\wio.png", png);

void setup()
{
  tft.init();
  tft.setRotation(3);
  tft.drawPng(png, (int)_sizeof_png, 0, 0, IMG_WIDTH, IMG_HEIGHT);
}

void loop() {
}
```

少し残念だったのは、上手く相対パスで指定することができませんでした。（やり方が分からなかった）
もし上手いやり方知っている方いれば教えてください。

肝は、『incbin』ですね。ファイル名を指定すると指定場所に配置してくれるようです。
残念ながらC言語のsizeofでサイズが取得できないので、別途名前を定義してファイルサイズが分かるようになっています。

[前回作ったサイト](https://wioterminal.s3-ap-northeast-1.amazonaws.com/index.html)がムダになってしまいそうですが、まあアレはアレで何か別な使い道もあるかと思いますのでそのまま残しておくことにします。

<img width="640" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143415/12fc947f-9b2a-dcb5-25e1-c94e53b66484.png">
やっぱりイラストは、JpegよりPngの方が綺麗だし、サイズも小さくて良いですね。素晴らしい画像ライブラリにも感謝。

以上です。

参考にしたサイト
https://gsmcustomeffects.hatenablog.com/entry/2019/02/05/055259
MacでDockerをインストールして起動しようとしたらThe operation couldn’t be completed. (Docker.VmnetdError error 1.)と出た

# Dockerを起動できなくなったので、再インストールしてしている時に起こった

The operation couldn’t be completed. (Docker.VmnetdError error 1.)

単純にオペレーション終わってないですよ！ということなのだが、これがDockerを起動しようとしたら起こり、そしてインストール後にも同様のエラー。

何事かと思い、ひとまずググる。
すると同じエラーを抱えた人がたくさんいたらしく、Issuesに投稿されていた。

# 解決法

https://github.com/docker/for-mac/issues/3886

![スクリーンショット 2020-06-27 12.54.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412789/d8f0bc91-56c8-0754-c2b2-1511597428d1.png)

インストールした後にそのままこの画面から起動するのではなく、Applicationから起動すると起動できた。

ただ、これだけでは起動できないパターンもあるらしく、その場合はbrewをインストールし直すと解決した例があるらしい。
expo-cliの基本的なコマンド一覧

* expoプロジェクトを作成する

```
$expo init プロジェクト名
```

* expoにログインする

```
$expo login
```

* expoからログアウトする

```
$expo logout
```

* expoを起動する（プロジェクトのディレクトリに移動した上で）

```
$expo start
```

* expoに残っている前のキャッシュを削除して起動する

```
$expo start -c
```

* expo clientアプリからインストールするためのURLを発行する

```
$expo publish
```

* 本番用にビルド（iOS）

```
$expo build:ios
```

* 本番用にビルド（Android）

```
$expo build:android
```

* expoにモジュールをインストールする

```
$expo install モジュール名
```
Firebase Cloud Functionsのレスポンス遅延に対応する with TypeScript

firebase cloud functionsで処理速度を高めるための遅延ローディングをTypeScriptでやる際に、namespaceとかを使っているとやりにくかったのでメモ。

## 前提

TypeScriptでfirebase cloud functionsのコードを書いていて全体像はなんとなくこんな感じでした。

```ts:index.ts

import { Foo } from "./foo";

export const doBar = Foo .bar;
export const doBaz = Foo .baz;
```

```ts:foo.ts

export namespace Foo {
   export const bar = functions.firestore
     .document("barDocuments/{barId}")
     .onWrite(async (snapshot, context) => {
        // do something...
     });
   export const baz= functions.https.onCall((data, context) => {
        // do something...
     });
}
```

## 動作が遅くなる問題

ただ、実はこれでは関数実行時の速度が遅くなります。

functionsは一つの関数呼び出しに対して仮想インスタンスが一つ作られ、一定時間アクセスがないと削除されます。
インスタンスの作成時（関数の実行時？）に`index.js` が読み込まれるわけですが、上のようにべた書きにすると実行しない関数のimportまでしてしまい、処理が遅くなります。

。。。といったことと解決策が [https://tech.ginco.io/post/ginco-engineer-meetup-2018-cloud-functions/](https://tech.ginco.io/post/ginco-engineer-meetup-2018-cloud-functions/) に書いてあったので試してみたのですが、最初詰まりました。

サイトには `process.env.FUNCTION_NAME` に実行予定の関数名が入っていることを利用して遅延読み込みするべしと書いてあります。

```js
if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === 'Func1') {
    const Foo= require('./foo');
    exports.bar = Foo.bar; 
}
```

ただ、これをTypeScriptでやろうとしたときに問題に遭遇しました。


## TypeScriptで速度改善するときの問題と解決策

### deploy時に関数が認識されない
configとかいじればいけるのか（？）もしれませんが、`index.js` では最終的に

```js
exports.baz = functions.https.onCall((data, context) => {
        // do something...
     });
```

と評価されないとfunctionだと認識してくれないようで、サイトのマルパクではdeployできませんでした。

これは、いったん関数はexportしたうえで、中で `process.env.FUNCTION_NAME` を評価して解決します。

```ts:index.ts
export const doBar= functions.https.onCall((data, context) => {
  if (
    !process.env.FUNCTION_NAME ||
    process.env.FUNCTION_NAME === "doBar"
  ) {
    // ...
  }
  return null;
});
```


### namespace使ってるときに遅延読み込み & トランスパイル後の動作保証どうやるの問題
遅延読み込みは

```ts
import("hoge").then(loaded => /* do something... */ );
```

でいけますが、namespace？

結局、いろいろやっていたら

```ts
import("@/foo").then(({ Foo }) =>
   Foo.bar(data, context)
);
```

でいけました。（勉強不足）


## 完成形

```ts:index.ts
export const doBar= functions.firestore
  .document("barDocuments/{barId}")
  .onWrite(async (snapshot, context) => {
     if (
        !process.env.FUNCTION_NAME ||
        process.env.FUNCTION_NAME === "doBar"
     ) {
        return import("@/foo").then(({ Foo }) =>
           Foo.bar(data, context)
        );
     }
     return null;
});

export const doBaz= functions.https.onCall((data, context) => {
     if (
        !process.env.FUNCTION_NAME ||
        process.env.FUNCTION_NAME === "doBaz"
      ) {
         return import("@/foo").then(({ Foo }) =>
           Foo.baz(data, context)
        );
      }
      return null;
});
```

## その他
- もちろん、これ以外にリージョンを東京にしたら早くなるとかあります。（ジェニさえ払えば速くなんでぇ）
- そもそもインスタンスのスペックを256MBのままにしてるのが無理ゲーという話もあります（ジェニさえ...（略））

ちゃんと勉強します。
ゼロから始めるLeetCode Day69 「279. Perfect Squares」

# 概要

海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

どうやら多くのエンジニアはその対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイトであり、海外のテックカンパニーでのキャリアを積みたい方にとっては避けては通れない道である。

と、仰々しく書いてみましたが、私は今のところそういった面接を受ける予定はありません。

ただ、ITエンジニアとして人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

Python3で解いています。

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day68 「709. To Lower Case」](https://qiita.com/KueharX/items/e97ae6928fd2b61300c4)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

**[技術ブログ](https://kueharx.blogspot.com/)始めました！！**
技術はLeetCode、Django、Nuxt、あたりについて書くと思います。**こちらの方が更新は早いので**、よければブクマよろしくお願いいたします！

# 問題
[279. Perfect Squares](https://leetcode.com/problems/perfect-squares/)
難易度はMedium。
Top 100 Liked Questionsからの抜粋です。

正の整数nが与えられたとき、足してnになる完全な平方数の最小数（例えば、1, 4, 9, 16, ...）を求めよ、という問題です。

>Example 1:

>Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

>Example 2:

>Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.

#解法

```python
class Solution:
    def numSquares(self, n: int) -> int:
        dp = [i for i in range(n+1)]
        for i in range(2,n+1):
            for j in range(1,int(i ** 0.5)+1):
                dp[i] = min(dp[i],dp[i-j*j]+1)
        return dp[n]
# Runtime: 4608 ms, faster than 39.65% of Python3 online submissions for Perfect Squares.
# Memory Usage: 14 MB, less than 60.54% of Python3 online submissions for Perfect Squares.
```

動的計画法を使って実装しました。
問題をみた時にあー・・・これDPや・・・ってなりました。
値が小さければ全探索でもいけますが、どう考えても効率が悪いので以上のように書いています。

なお、個人的なQiitaの記事の動的計画法のおすすめとして
[動的計画法超入門！ Educational DP Contest の A ～ E 問題の解説と類題集](https://qiita.com/drken/items/dc53c683d6de8aeacf5a)
とPythonでの実装において
[動的計画法 (Dynamic Programming：DP) 学習メモ　～by Python～　Part 1](https://qiita.com/Nary_/items/60be9361d787275d1dee)

が良い例じゃないでしょうか。
前者で概念を掴んで、後者でPythonでの実装について学ぶ、という方式が良いと思います。

そういえば日本語では動的計画法なのに英語ではDynamic Programmingなんですよね、不思議だ。

では今回はここまで。
お疲れ様でした。
Excelで重複しないユニーク数カウントをする（SQLのDISTINCTをExcelのCOUNTIF関数で表現）

単なるカウントだったら簡単なのですが、Excelで<b>ユニーク数</b>をピボットテーブルを使って調べたいときがあります。

※ユニーク数とは、重複しないカウントのことです。ポケモンを1000匹捕まえても、図鑑は151匹って出るじゃないですか（初代GB赤緑の話）ああいう"種類"のカウントのことです。

#ユニーク数の意味

例えば売上明細等々のデータがあって、

 - ① 商品ごとに売れた"個数"の集計
 - ② 商品ごとに買った人の"ユニーク人数"の集計

を抽出してください、みたいな仕事があります。

①は売れた数量の単なる合計。②のユニーク人数っていうのは、同じお客さんが同じ商品Aを3回買っていたとしても、商品Aの購入者数を1と数えるってこと。

（ユニーク数を調べることでどれだけ多くのお客さんに人気があるのかが分かります。

1人が10個まとめ買いした場合と、10人が1個ずつ買って行った場合とでは、「10個売れた」結果は同じですけど、人気度って異なりますよね。

その値が次回の商品仕入れや調達で参考にされたり…そんな使い方。）

#SQLでユニーク数を集計する

こんな売上明細があるとします。

PRODUCT_ID「0000001」の単なる"購入者数"は5ですが、
CUSTOMER_IDをよく見ると「100010」「100020」「100030」の3名に購入されているので、"購入者ユニーク数"は3です。

![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/86d0e6bf-873e-da20-4185-fb057990be54.jpeg)

```sql:SQLでユニーク数集計
SELECT
    PRODUCT_ID,
    SUM(QUANTITY), --①個数
    COUNT(DISTINCT CUSTOMER_ID) --②ユニーク人数
FROM
    URIAGE_MEISAI
GROUP BY
    PRODUCT_ID
```

#Excelでユニーク数を集計する

SQLだったら秒ですが、Excelではちょっと工夫します。作業列（列名:NUM）を作り、集計したい列（CUSTOMER_ID）に対して、COUNTIFした逆数を入れてオートで下まで入力。

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/7aafada8-b775-93ef-4b1b-afadcb75a865.jpeg)

```shell:Excelでユニーク数集計
=1/COUNTIF(F$2:F$11,F2)
```

すると、こうなります。

![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/6dad3683-edbc-1806-9a8d-f56a2d1b25ed.jpeg)

あとは、行に「PRODUCT_ID」・値に「合計/NUM」「合計/QUANTITY」を入れて、ピボットします。

![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398297/72743d0b-8f02-aa71-903a-2ce74332fcc3.jpeg)

他にやり方が思いつかなかったので、これでSQLの結果と比較してテストしてます。もっと良い方法あったら優しく教えて……
WSL2のUbuntu 20.04を日本語化する

# 概要

WSL2のUbuntu 20.04はデフォルトで英語モードなので日本語化する。

# 1．パッケージの更新とアップグレード

まずはパッケージの更新とアップグレードを行う。

```bash
$ sudo apt update && sudo apt upgrade
```

# 2．日本語言語パックのインストール

```bash
$ sudo apt -y install language-pack-ja
```

# 3．ロケールを日本語に設定

```bash
$ sudo update-locale LANG=ja_JP.UTF8
```
# 4．Ubuntu 20.04を再起動

［Ctrl］＋［D］で終了。
再起動後にロケール設定を確認する。

```bash
$ locale
LANG=ja_JP.UTF8
LANGUAGE=
LC_CTYPE="ja_JP.UTF8"
LC_NUMERIC="ja_JP.UTF8"
LC_TIME="ja_JP.UTF8"
LC_COLLATE="ja_JP.UTF8"
LC_MONETARY="ja_JP.UTF8"
LC_MESSAGES="ja_JP.UTF8"
LC_PAPER="ja_JP.UTF8"
LC_NAME="ja_JP.UTF8"
LC_ADDRESS="ja_JP.UTF8"
LC_TELEPHONE="ja_JP.UTF8"
LC_MEASUREMENT="ja_JP.UTF8"
LC_IDENTIFICATION="ja_JP.UTF8"
LC_ALL=
```
# 5．日本語マニュアルのインストール

```bash
$ sudo apt -y install manpages-ja manpages-ja-dev
```

# 参考

- [WSLのUbuntu環境を日本語化する] (https://www.atmarkit.co.jp/ait/articles/1806/28/news043.html)
RailsとDockerでよく使うコマンドまとめ

```ruby
docker-compose build #コンテナの作成
docker-compose up #コンテナ立ち上げ
docker-compose down #コンテナをダウン　ctrl+cでも止められるがserver.pidでエラーになる
docker-compose stop #コンテナをストップ
docker-compose up --build #docker関連のファイルの変更を反映した上に、サーバーを再起動
docker　images #イメージ一覧
docker ps #動いているコンテナ一覧
docker ps -a #動いていないコンテナも含めた一覧
docker rm `docker ps -a -q` #コンテナの一括削除
docker rmi `docker images -a -q` #イメージの一括削除
mysql -u root -p -h localhost -P 3306 --protocol=tcp #DockerからMYSQLへ

docker-compose run web bundle install #bundle install
docker-compose run web rails db:create #db作成
docker-compose run web rails db:migrate #マイグレート
```

以上、RailsとDockerでよく使うコマンドたちでした！
参考になれば幸いです。
間違えなどありましたらご指摘お願いします。
PowerShell で 指定ファイルを読み取るまで

# PowerShell で 指定ファイルを読み取るまで

## PowerShellバージョン
`Version : 5.1.18362.752`

## 目的
- 指定テキストファイルを読み取り、1行ずつ処理する方法を学ぶ。
- 1行ずつ取得したファイルを指定の文字でセパレートし、連想配列のキーとして登録後、カウントをする。
- 調べる過程で興味が沸いたものを取り込んでいく。

## 作ったサンプルコード

```powershell
#region Syslogd Log File Analys Tools
##################################################################################
#--------------------------------------------------------------------------------#
#
#
#
#
#
#--------------------------------------------------------------------------------#

#region Prompt Custom
function prompt {
    "[Tools]> "
    #(Split-Path (Get-Location) -Leaf) + " > "
}
#endregion

#region Clear
Clear-Host
#endregion

#region Path Move
# 現在のパスを取得/格納
$start_path = (Convert-Path .);
Set-Location $start_path;
# 実行中のパス取得/移動
$path = Split-Path -Parent $MyInvocation.MyCommand.Path;
Push-Location $path;
#endregion

#region Input File Path
$infile = "C:\workspace\access_combined_log";
#endregion

# IPベース連想配列を空準備
$ip_table = @{};

#region try-catch!
try {
    Write-Host "開始：ファイルをオープンします。" -ForegroundColor Yellow
    $fso = New-Object System.IO.StreamReader($infile, [System.Text.Encoding]::GetEncoding("UTF-8"));
    while (($line = $fso.ReadLine()) -ne $null) {
        # 1行分を空白で分割
        $ary_line = $line -split " ";
        If($ip_table.ContainsKey($ary_line[0])) {
            $ip_table[$ary_line[0]] = $ip_table[$ary_line[0]] + 1;
        } else {
            $ip_table.Add($ary_line[0],1);
        }
    }
} catch {
    # tryの中でエラーが発生した場合は、ここで処理
    $ErrorMessage = $_.Exception_Message
    $ErrorMessage
    Write-Host "エラー: $error" -ForegroundColor Yellow
} finally {
    Write-Host "終了：ファイルをクローズします。" -ForegroundColor Yellow
    $fso.Close();
}
#endregion

#region GridDisplay
[String]$row;
foreach ($invalue in $ip_table.Keys) {
    $ip_cnt = $ip_table[$invalue];
    $row += $invalue + "," + $ip_table[$invalue] + "`n";
}
$row | ConvertFrom-Csv -Header @("IP-Addr","Count")| Out-GridView -Title "IP Base Counter"
Remove-Variable row
#endregion

#region
Pop-Location;
#endregion

#endregion
#EOF
```

## まとめ

### 連想配列の定義場所
最初は、`try`文の中で定義してしまっていたので、連想配列が最後の一つだけしか登録されていなかった。

### プロンプト表示
プロンプト表示は変更出来る。

### カレントディレクトリの操作
スクリプトが格納されている場所に移動ができる。
pushとpopで戻れる。便利。
`Set-Location`もよいけれど、個人的には`push`や`pop`が感じよかった。

### Out-GridViewの出力情報
最初、`$row`変数を初期化しないで利用していたら、どんどん前のレコードが残ったまま表示されていた。
なので、`Remove-Variable`で削除する。削除する時は、`$`を付けない。
文字起こしの時短テクニック

#動画文字起こしの時短を考える
インタビュー動画など10分間ずっとしゃべっている動画では
文字起こしにはかなり時間がかかる。
文字数はおしゃべりな人が10分しゃべり倒していると5000文字ぐらい。。。
自分でも１時間ぐらいはかかる。

#今まで色々やってきた中で一番効率がいい方法を紹介
####➊まずはある程度自動で文字起こししてもらう
vrewという便利なソフトで動画を読み込んである程度自動で文字起こしをしてもらう。
文字起こしの精度としては
丁寧にしゃべってる人はかなりの精度を持っているけど
会話ぐらいラフにかんだり言い間違いしてる人に対しては60％あたりの精度かな。
それでもvrewはかなりいい文字起こしのソフトです。
昔はgoogleドキュメントでもやってたけどvrewを使ってからはこれ一択
googleはしゃべるスピードについてこれず、起こせない文字もあるのが
vrewは問題ない。
ただ会話の区切りが微妙なとこがあるからそこは誤字も含め次の工程で修正する。


####➋vrewで起こした間違いだらけのテキストを修正する
ここは手動で直していくほかない。
ただ一番効率を良くしている部分はこの部分
単純にショートカットキーを使いまくる方法で修正していく。
マウスを全く使わない分、かなり時短になる。

まずはvrewでデータをテキストとしてエクスポートする。
premiereで動画をシーケンスに入れて、再生できるようにしておく。

でpremiereで再生しながらテキストを見比べていく。

#ここからが効率を良くする方法
テキストに間違いがあった時点でpremiereを一度停止
Alt+Tab（アクティブウィンドウを切り替える）
でテキストウィンドウをアクティブにするテンキー矢印で修正したいとこまで移動する。
マウスでもいいけどテンキーの方が自分は早く出来る。
そしたらテキストを修正する。
動画をちょっと戻したり何回か聞きたくなるから
またAlt+Tab（アクティブウィンドウを切り替える）でPremiereに戻って
Shift + ← でシーケンスの指定した秒数戻れる
Shift + ←の秒数の設定は
環境設定→再生→SHIFT+左右カーソル移動量で設定出来る。
秒数ではなくシーケンスのフレームに対してなので、自分はとりあえず30Fpsで編集した場合5秒になるよう150フレームで設定している。

#その他のショートカットで素早くやれっ！！
私がその他に使うショートカットは
HomeキーとEndキー
これはカーソルを行の頭と後ろに移動できるショートカット
それにShiftを加えて
Shift+Home
Shift+End
で今カーソルがある場所から前や後ろを選択できる。
これで間違った部分とかを選択
あとはCtrl+Shift+End
これは現在カーソル位置からテキストの最後までを選択

他にマウスを使うなら
ダブルダブルクリックで単語選択
トリプルクリックで行選択

でもほとんどマウスは使わないです。

#まとめると
Premiereで再生
文字起こしの間違いを探す。
間違ってたらPremiere停止して
Alt+Tabでテキストに移動
文字修正
Alt+Tab で Premiere に移動
Shift + ←で再生場所を巻き戻す
再生する

これの繰り返し

#それとは別に毎回誤認識しているテキスト
私はテキストエディタにはNotepadを使っているのですが
毎回、乳の話しているのに父と誤認されているやつは
Ctrl+F で父を検索かけて
乳に全置換する方法で誤認識ワードは一発で直ります。

#これで自分はかなり早くなった
単純にマウスを使わずショートカットのみでやるようになっただけでかなりスピードアップした。
かつテキストの間違いチェックもこの時点で２重チェックできるからいいよね。
次にキャプション付けやテロップ付けで３重チェックして、最終プレビューで４重チェック。
是非皆さんも試してみて！！＆もっと俺の方が効率いいしスマートだぜ！！って人いたらお願いだから教えてください。

#もっと使い勝手を良くするために
vrewからタイムコード付きで書き出してやるとさらに便利
この発言どこだっけなっていう時タイムコード付きのテキストがあればPremiereで探しやすい。
最終的にNotePadで正規表現で検索もかけれるから
タイムコードだけ検索かけて削除すればいい。
S3 に アップロードした view ファイルの URL を一時的なものにする。( Severless Framework x Laravel )

# はじめに

セキュリティの面で、S3 にアップロードしている view ファイルの URL を一時的なものに変更する必要があったので、その手順を残します。

S3 に view ファイルをアップロードする記事はこちら
https://qiita.com/soma_sekimoto/items/5cdeb4b51141e95ba972

# 1. .env の "AWS_ACCESS_KEY=" などの AWS 関連の部分を複製する。そして、S3 のバケットのポリシーを持つキーを入力する。


```.env
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

+ AWS_ACCESS_KEY_ID_S3=XXXXXXXXXXXX
+ AWS_SECRET_ACCESS_KEY_S3=XXXXXXXXXXXX
+ AWS_DEFAULT_REGION_S3=XXXXXXXXXXXX
+ AWS_BUCKET_S3=XXXXXXXXXXXX

```

**理由としては、serverless framework を利用したときに、lambda の 環境変数がすでにセットされているため、それを使って S3 にアクセスしようとすると、Access Denied のエラーが出るから。**



# 2. config/filesystems.php に以下のように記述

```php
disks => {
  ~省略~
  's3'=> [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID_S3'),
    'secret' => env('AWS_SECRET_ACCESS_KEY_S3'),
    'region' => env('AWS_DEFAULT_REGION_S3'),
    'bucket' => env('AWS_BUCKET_S3'),
    'url' => env('AWS_URL_S3'),
    'endpoint' => env('AWS_ENDPOINT_S3'),
  ]
  ~省略~
}
```

# 3. app/helpers.php 作成・編集

```php
<?php
if (!function_exists('s3_asset')) {
    function s3_asset($path)
    {
        return \Illuminate\Support\Facades\Storage::disk('s3')->temporaryUrl($path, now()->addMinute());
    }
}
```

# 4. composer.json に追記

```json
"autoload": {
    "psr-4": {
        "App\\": "app/"
    },
    "classmap": [
        "database/seeds",
        "database/factories"
    ],
+    "files" : [        #<= ここから追記
+       "app/helpers.php"
+    ]
},
```

# 5. composer dump-autoload 実行。

```terminal

$ composer dump-autoload
```

これで、helpers.php の s3_asset 関数が使えるようになりました。

# 6. resources/views/layouts/app.blade.php に 関数の記述

```php
@if(env('APP_ENV') == 'local')
    <link href=" {{ mix('css/app.css') }} " rel="stylesheet"></link>
@else
    <link href=" {{ s3_asset('css/app.css') }} " rel="stylesheet"></link>
@endif

# 条件分岐で、local環境では違うところから asset をとってくるようにしている。

```

# 7. 以下コマンドを実行

```
$ npm run dev
$ php artisan config:clear
$ sls deploy -v
```


# 終わりに


Lambda の環境変数と S3 の環境変数、両方を扱わなくてはいけないので、ちょっと面倒ですが、これだけやってしまえれば、あとはもう何もしなくていいので、便利です。
iOSのExposureNotificationのAPIをサンプルアプリとドキュメントから見てみる

# ExposureNotification概要
ExposureNotificationはCOVID-19への潜在的な曝露を人々に通知します。
ExposureNotificationの機能を実現するにはExposure Notification Serverの実装が必須です。

# おことわり
リリースするには [Exposure Notification Entitlement Request](https://developer.apple.com/contact/request/exposure-notification-entitlement)で申請する必要があり、ハードルが高いので、
あくまで、公式ドキュメントとサンプルアプリのシミュレータでの確認になっています。
大いに間違っている可能性があるので公式ドキュメントを正としてください。

実機ビルドするだけであれば、`Code Signing Entitlements` の項目を外すことでビルドは可能ですが、機能を使える保証はないです。

# 公式ドキュメント
https://developer.apple.com/documentation/exposurenotification

# サンプルアプリ
https://developer.apple.com/documentation/exposurenotification/building_an_app_to_notify_users_of_covid-19_exposure 

## ENManager
#### activate
```swift
func activate(completionHandler: @escaping ENErrorHandler)
```
ENManagerを使う前に最初に呼び出す。
これを行い、完了ハンドラが戻ってきたところでENManagerの機能が使えるようになる。

#### setExposureNotificationEnabled

```swift
func setExposureNotificationEnabled(_ enabled: Bool,completionHandler: @escaping ENErrorHandler)
```
曝露通知を有効/無効にするクラス。
自動的に通知許可をもらうダイアログも表示する。
許可が断られた場合、completionHandlerは`ENError.notAuthorized`を返す？
enabledをfalseにした場合、 Bluetoothのスキャンとアドバタイズを停止するが、取得していた診断データはそのまま残る。
残念ながらシミュレータで動作させても`Domain=NSOSStatusErrorDomain Code=-71148` のErrorになります。

#### detectExposures

```swift
func detectExposures(configuration: ENExposureConfiguration, 
    diagnosisKeyURLs: [URL], 
   completionHandler: @escaping ENDetectExposuresHandler) -> Progress
```

曝露を検出する。
diagnosisKeyURLsは、Exposure Notification ServerからダウンロードしたキーのローカルURLとする。
configurationに関しても、Exposure Notification Serverから取得するデータから生成することをサンプルアプリでは想定している。

このAPIはBluetooth経由で得ているデータをワンショット返すようで、サンプルアプリではBackgroundTasksフレームワークを用いて定期的に検出を行っている。

completionHandlerで返ってくる `ENDetectExposuresHandler` には `ENExposureDetectionSummary` が含まれていて、後述の `getExposureInfo` で使用する。

#### getExposureInfo

```swift
func getExposureInfo(summary: ENExposureDetectionSummary, 
     userExplanation: String, 
   completionHandler: @escaping ENGetExposureInfoHandler) -> Progress
```

前述の `detectExposures` から得た `ENExposureDetectionSummary` をパラメータにして曝露情報を取得する。
`userExplanation` はUIの一部としてユーザーに表示するために使われる。
コールバックとして `ENExposureInfo` が受け取れる。
サンプルアプリではこの情報を独自の構造にマッピングしてローカルに保存している。

#### getDiagnosisKeys

```swift
func getDiagnosisKeys(completionHandler: @escaping ENGetDiagnosisKeysHandler)
```

`ENTemporaryExposureKey` を取得する。
このメソッドを呼び出すたびに、ユーザーは承認を行う必要がある。
このキーはそのままExposure Notification Serverに送信する必要があり、サンプルアプリでは一旦JSONにデコードして送信する想定となっている。


#### getTestDiagnosisKeys

```swift
func getTestDiagnosisKeys(completionHandler: @escaping ENGetDiagnosisKeysHandler)
```

`getDiagnosisKeys` のテスト用API。
シミュレータで動作させても`Domain=NSOSStatusErrorDomain Code=-71148` のErrorになります。

#### invalidate

```swift
func invalidate()
```

ENManagerを無効にする。


## ENStatus
曝露通知システムの有効状態を示すenum。
特筆したいのが`bluetoothOff`という種別であり、ENStatusにしかBluetooth使用を示すものがないので、ExposureNotificationのフレームワーク内で完全にBluetoothの処理は閉じていてBluetoothに対するコントロールは出来なさそう。

# tvOS14(おまけ)
tvOS14にもExposureNotification.frameworkが有効なんですが、

- ENAuthorizationStatus
- ENStatus
- ENError

と、限定的なAPIしか使えず、メインのENManagerが使えない模様。
10進数をn進数へ変換する[python]

#初めに
・初心者が勉強を兼ねてやってるのでご指導いただけるとありがたいです。
・n進数の説明が序盤あるので知ってる人は読まなくてもいいです
##10進数とは
僕たちの世界では基本的に10進数という概念で数字を扱っています。
例えば
1234という数字は
... + 10000*0 + 1000*1 + 100*2 + 10*3 + 1*4 という意味を持ち
10のべき乗数である、[1,10,100,1000,10000,......]を省略するという意味です。
(頭の0も省略してますけど)

この省略というのがミソで省略せずに数字を表す「漢字」で「1234」を書くと

千二百二十四と書くのがだるいんですよね。(見るのもだるい)

10のべき乗数を省略して書くというのは数学史における大発明の一つであると思います。
(アインシュタインの略記法もアインシュタインが残した一番の発明と呼ばれてたりしますし、便利すぎる略記法は凄いんだなあ(小並感))

##n進数とは
ただ数学が進歩するにつれ数学者たちは一般化にロマンを求めるようになりました(ロマンは求めてないと思います)
この数の表記法の一般化を考え始めたんですね。
なら10のべき乗数ではなくnのべき乗数を省略したらどうなるんだろう？
それがn進数という概念です。
###n進数のルール
まず基本的なルールとしては10進数世界と同じです。
ただ、意識してなかったかもしれないルールがあります。
それは
「nのべき乗の係数はn未満である必要がある」
というもの。
2進数世界で
a*4を考えるとき
a=3だったら
(2+1)*4
=8+1*4となり8が現れますよね？
これは繰り上がりの意味を持ちます。
計算途中で繰り上がりが出るのならわかりますが
数字の表記上で繰り上がりが出るのは嫌ですよね。もちろん、繰り上がりを認める表記法も存在するかもしれませんが、繰り上がりを認めると数の表記が一意に定まりません(二通り以上存在するということ)

例えば9という数は2進数表記だと
1*8+0*4+0*2+1*1なので1001と表記できます。
しかし、繰り上がりを認めると
0*8+1*4+2*2+1*1=121
2はこの世界では10と表記されるので
121=1(10)1となり1001と違う書き方になってしまい9を二つの方法で表してしまいます。
これを認める数学の世界はもちろん作れるでしょうが、
「係数はn未満」って条件つけるだけで一意に定まるんだからその条件を使いましょう。
そっちのほうが便利なので。
(よく考えてないけどwelldefinedとか絡んできたらめんどくさいですし)
##プログラムの解説
好きな進数に変換するプログラムを作りますが、今回は各係数をリストで返すことにします。
理由は100進数とかに変換したいとき、係数の87とかが見えやすいようにです。
もっと具体例で解説すると
「8765」は100進数表記で
(87)(65)となります。（(87)で1桁の数字になる）
ただ見えにくいのでリストで[87,65]と表記することにします。
意味は87*100+65*1ですね。

###プログラムの流れ
まず変換したい数を10進数で入力して、変換したい進数を入力してもらいます。

```
N=int(input())#変換したい10進数の値
K=int(input())#進数
```
あ、一応関数にします

```
def change(N,shinsu):
```

そして返すリストの準備からします。
変換後の桁数が分かると楽なのでまず桁数を求めます

```
    keta=0
    for i in range(10**9):
        if N<shinsu**i:
             keta+=i
             break
```
これで変換後の桁数が分かりました。
つまり返すリストのサイズが分かったのでリストを準備します。

```
    ans=[0]*keta
```
あとは頭からK^xの係数を求めるだけです。

```
    for i in range(1,keta+1):
        j=N//(shinsu**(keta-i))
        ans[check]=j
        check+=1
        N-=(j)*(shinsu**(keta-i))
```

最後に返せば終わりです

```
    return ans
```

一つにまとめると

```
N=int(input())#変換したい10進数の値
K=int(input())#進数

def change(N,shinsu):
    keta=0
    for i in range(10**9):
        if N<shinsu**i:
             keta+=i
             break
    ans=[0]*keta
    check=0
    for i in range(1,keta+1):
        j=N//(shinsu**(keta-i))
        ans[check]=j
        check+=1
        N-=(j)*(shinsu**(keta-i))
    return ans

print(change(N,K))
```
これで完成です!

####遊んでみた
```
1023
2
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
```

```
9765624
5
[4, 4, 4, 4, 4, 4, 4, 4, 4, 4]
```

```
2853116705
11
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```
###n進数を10進数へ
逆にn進数のリストが与えられたらそれを10進数に復元する関数も作っておきます。

```
def henkan(list,shinsu):
    l=len(list)
    ans=0
    for i in range(1,l+1):
        ans+=list[-i]*(shinsu**(i-1))
    return ans
```

###まとめ
個人的に16進数をA,B,C,D,E,Fを用いて表すのに抵抗があったので作成しました。
プログラムの練習で作った関数で結構お気に入りの関数です。
ご指導ご鞭撻よろしくお願いします><
S3 に view ファイルをアップロード ( Severless Framework x Laravel )

# はじめに

この記事に書かれているのは、AWS コンソールで、IAM と S3 bucket を作成した後の手順なので、それ以前の設定はご自身でご自由にしてください。

# 1. .env を編集

```
ASSET_URL=https://[S3 のバケット名].s3-ap-northeast-1.amazonaws.com


AWS_ACCESS_KEY_ID=XXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXX
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET= S3 のバケット名
```

# 2. Serverless Framework にプラグインインストール

```
$ sls plugin install -n serverless-s3-sync
```

# 3. serverless.yml への記述

```yml
plugins:
   - ./vendor/bref/bref
   - serverless-domain-manager
+  - serverless-s3-sync

 custom:
+  s3Sync:
+    # A simple configuration for copying static assets
+    - bucketName: ${self:service.name}-${opt:stage, self:provider.stage}-asset
+      localDir: public # required

+resources:
+  Resources:
+    StaticContentS3:
+      Type: AWS::S3::Bucket
+      Properties:
+        BucketName: ${self:service.name}-${opt:stage, self:provider.stage}-asset
```

# 4. s3 と laravel を連携させるパッケージをインストール

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

これで 
Illuminate\Support\Facades\Storage::disk('s3')
で使うことができます。


# おわりに

Serverless Framework と laravel での開発にも慣れてきて、記事もまあそれとなく書けるようになってきましたが、まだまだ理解浅いと感じているので、間違いや、不足している部分などありましたら、どんどんコメントしてください！

こちらの記事も読んでみてください。

S3 に アップロードした view ファイルの URL を一時的なものにする。( Severless Framework x Laravel )
https://qiita.com/soma_sekimoto/items/bd16bbc6c2b650af79f9
PRML　演習問題  5.14（基本）　解答

## はじめに
本記事は, 機械学習の教科書の決定版ともいえる, **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)をご覧ください.


## 問題
> テイラー展開をすることにより, 
$$
\begin {align*}
\frac { \partial E _ { n } } { \partial w _ { j i } } = \frac { E _ { n } \left( w _ { j i } + \epsilon \right) - E _ { n } \left( w _ { j i } - \epsilon \right) } { 2 \epsilon } + O \left( \epsilon ^ { 2 } \right)
\tag {5.69}
\end{align*}
$$
の右辺において $O \left ( \epsilon \right )$ である項は消えることを確かめよ.

## 解答の指針
問題分にある通り, 素直にテイラー展開をしてやればいいですね.
念のため, テイラー展開を復習しておくと, 関数 $f$ の $x = a$ 周りのテイラー展開は,

```math
\begin {align*}
f \left ( x \right ) = \sum _ { n = 0 } ^ { \infty } \frac { f ^ { ( n ) } ( a ) } { n ! } ( x - a ) ^ { n }
\tag{5.14.1}
\end{align*}
```
のように表せます. なお, $f ^ { ( n ) }$ は関数 $f$ の $n$ 階微分です.
したがって, 二次までの近似の場合は,

```math
\begin {align*}
f \left ( x \right ) = f ( a ) + f ^ { ( 1 ) } ( a ) ( x - a ) + 
\frac { f ^ { ( 2 ) } ( a ) } { 2 } ( x - a ) ^ { 2 } + O \left ( ( x - a ) ^ 3 \right )
\tag{5.14.2}
\end{align*}
```
のように近似することができます.

## 証明
さて, $(5.14.2)$ を利用して, $E _ { n } \left( w _ { j i } + \epsilon \right)$, $E _ { n } \left( w _ { j i } - \epsilon \right)$ を, それぞれ以下のように $w _ { j i }$ 周りでテイラー展開してみましょう.

```math
\begin {align*}
E _ { n } \left( w _ { j i } + \epsilon \right) & =
E _ { n } \left( w _ { j i } \right) +
\epsilon E ^ { ' } _ { n } \left( w _ { j i } \right) +  
\frac { \epsilon ^ { 2 } } { 2 } E ^ { ' ' } _ { n } \left( w _ { j i } \right) + O \left ( \epsilon ^ { 3 } \right ),
\tag{5.14.3}
\end{align*}
```

```math
\begin {align*}
E _ { n } \left( w _ { j i } - \epsilon \right) & =
E _ { n } \left( w _ { j i } \right) -
\epsilon E ^ { ' } _ { n } \left( w _ { j i } \right) +  
\frac { \epsilon ^ { 2 } } { 2 } E ^ { ' ' } _ { n } \left( w _ { j i } \right) + O \left ( \epsilon ^ { 3 } \right ).
\tag{5.14.4}
\end{align*}
```


ここで, $E ^ { ' } _ { n } = \frac { \partial E  _ { n } } { \partial w _ { j i } }$, $E ^ { ' ' } _ { n } = \frac { \partial ^ { 2 } E _ { n } } { \partial w _ { j i } ^ { 2 } }$ のように, それぞれ1階微分, 2階微分を定義しました.
$(5.14.3)$, $(5.14.4)$ 式より, 

```math
\begin {align*}
E _ { n } \left( w _ { j i } + \epsilon \right) - E _ { n } \left( w _ { j i } - \epsilon \right) = 2 \epsilon E ^ { ' } _ { n } \left( w _ { j i } \right) + O \left ( \epsilon ^ { 3 } \right )
\tag{5.14.4}
\end{align*}
```
であるので, $E ^ { ' } _ { n }$ に関して解けば,

```math
\begin {align*}
\frac { \partial E _ { n } } { \partial w _ { j i } } = \frac { E _ { n } \left( w _ { j i } + \epsilon \right) - E _ { n } \left( w _ { j i } - \epsilon \right) } { 2 \epsilon } + O \left( \epsilon ^ { 2 } \right)
\tag {5.69}
\end{align*}
```

と求めることができます. このように, 結果として $O \left ( \epsilon \right )$ である項は消えることになりますね.
DocBase APIのGo Clientを作った

いろんなドキュメンテーションサービスあるけれど、DocBaseがミニマルでいい感じ。
だけどマイナー故か、APIクライアントはほとんどない。

APIドキュメントは充実しているので、参考にAPI Clientライブラリを作っておきました。

https://github.com/kyoh86/go-docbase

DocBase×Goユーザーの皆様よしなに。
Kops環境（EC2）でbastionのSSHポート番号を後から変更した

##はじめに
勉強用の検証環境で、Kopsでクラスターをセットアップした後に、（kopsコマンド実行時に作成された）bastionのSSHポート番号を変更しようとしたところ、少しはまってしまいました。対応した内容をメモで残します。（検証したのは今年の3月ごろ。）
あくまで個人の作業メモです。ご自分てプロジェクト等の環境で対応される場合には、公式のドキュメント等も確認の上、事前に検証して手順を確立してから対応されることをおすすめします。

## 状況
何も考えずに対応してSSHがつながらなくなり、困惑した経緯。（恥をさらすところではありますが、、）

- kopsでクラスターを作成後、bastionのポート番号を変更したいから変えなくちゃ！、とPC（Win)のTeratermを起動
- 2つTerminalを起動し、/etc/ssh/sshd_config を書き換え、sudo sshd -tとsudo service sshd restart を実行
- Teminalが2つとも落ちる！（当然だ！）

状況把握のログ

- 端末から、ELBのポート接続を確認すると、変更前のポートでは接続でき、変更後のポートでは接続できないことを確認（`telnet://<ELB-URL>:<port-number>`）
- ELBのポート構成に新しいポート番号を追加するが、新しいポートでは接続できない状態
- AWS管理コンソールからロードバランサーの状況をみると、ELBからbastionが見えない状態になっていた
- bastionのEC2は起動している
- ロードバランサーのヘルスチェックのポート変更が必要（pingプロトコル、pingポート）
- ELBからbastionを見るとin serviceになった
-ロードバランサーへのインバウンドのセキュリティーグループのポート番号を追加
- しかし、端末から、ELBのポート接続を確認すると、まだNG（以前のポートでは接続可能）
- bastion側のインバウンドのセキュリティーグループのポート番号も追加
- つながった！！（旧ポート番号をセキュリティーグループのインバウンド指定から削除）

##変更が必要な個所のまとめ
後から変更する場合には以下の編集が必要
- ロードバランサーのリスナーの編集
- ロードバランサーのヘルスチェックのポートの編集
- ロードバランサーへのインバウンドのセキュリティーグループの編集
- bastion側のインバウンドのセキュリティーグループの編集

以上。
PythonistaでYouTubeの#NowPlaying

お久しぶりです。結構前にYouTubeの#NowPlayingができるスクリプトをPythonistaで書いたんですが、今までにかなり使っているので、共有しておきます。

https://github.com/sora410/NPYouTube

やり方は全部READMEに書いてあります。
Windows 10 で Python3 の 仮想環境を作成後VsCodeに認識させてみる

# 目的
[Django Girls のチュートリアル](https://tutorial.djangogirls.org/ja/)に従って、Windows 10 で Python3 の 仮想環境を作成後VsCodeを立ち上げてみる
・仮想環境を作成後 pylint-django をインストールし .vscode\settings.json に追記して有効化する

## Python のバージョンの確認
<pre>
PS > python -V
Python 3.8.3
</pre>

## 必要なパッケージのインストール
※デフォではインストールされていない
<pre>
PS > pip3 install virtualenv
</pre>

## 仮想環境を作成する
適当なフォルダで

<pre>
PS > mkdir djangogirls
PS > cd djangogirls
PS djangogirls> virtualenv myvenv
</pre>

仮想環境の切り替え -> PowerShellでの切り替え より
※コンソールはPowerShellを使用しているため

<pre>
PS djangogirls> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
PS djangogirls> myvenv\Scripts\activate.ps1
</pre>
※コマンド プロンプトでの切り替え

<pre>
djangogirls> myvenv\Scripts\activate.bat
</pre>

## pylint_djangoのインストール＆有効化する
<pre>
(myvenv) PS djangogirls> pip install pylint-django
</pre>

djangogirls\\.vscode\settings.json に以下を追記する

<pre>
    "python.linting.pylintArgs": ["--load-plugins", "pylint_django"]
</pre>

## VsCodeでの設定
・VsCodeを起動する
・vscode の フォルダを開くで djangogirls を指定
・表示 -> コマンドパレット で Python: Select Interpreter
　から 作成した環境を選択する -> Python 3.8.3 64-bit('myvenv': venv)
・左下のInterpreterのバージョンで選択したバージョンが表示されていることを確認する
　カーソル・オンで ./myvenv/bin/python が表示される

# 参考にしたのは以下のサイト
[Django Girls のチュートリアル](https://tutorial.djangogirls.org/ja/)
[環境構築ガイド 〉 Windows 環境のPython](https://www.python.jp/install/windows/virtualenv.html)
[virtualenvのPython仮想環境をVisual Studio Codeにも有効させる](https://qiita.com/thatbin/items/2de0a0c1ea21af10f6e3)
[Using Python environments in VS Code](https://code.visualstudio.com/docs/python/environments)
[the extension can not find the path of python from microsoft store](https://github.com/microsoft/vscode-python/issues/10850)
[Linting Python in Visual Studio Code](https://code.visualstudio.com/docs/python/linting)
[VSCode Python Djangoの問題（エラー・警告）に対応する方法](https://wonwon-eater.com/vscode-python-django-lint/)
シェルとは

### シェルとは

シェルはLinuxなどのUnix系OSにログインして動作できるプログラム。

### シェル２つの側面

シェルには、ユーザのコマンド入力用のUIとしての側面と、シェルスクリプトの内容を文法的な解釈を行い、
その都度プログラムをインタプリタプログラムという２つの側面。

### Bシェル系とCシェル系

UNIX系OSで使用されているシェルには、多数のシェルが存在する。
今回は、Bシェル系とCシェル系を紹介する。

本来のUNIX系の標準シェルはsh。
shはBourne Shellとよばれ、shから派生したものがBシェル系。
ヒストリ機能、エイリアス機能、ジョブコントロール機能などの機能を備えて、
かつC言語風に改変した新しいシェルとして開発されたものがCシェル系。

bashというものが登場した。
そのbashとは、Bシェル系のままであり、shの上位互換であり、cshのヒストリ機能、エイリアス機能、ジョブコントロール機能、さらに、タブにファイル名やコマンド名の補完機能や、コマンドラインの編集機能をかなされている。
volatileの効果

# volatileの効果をアセンブリレベルで確認
組み込みプログラミングでは、volatile宣言が使われることがある。コンパイラの最適化を防ぐために使われる。たとえば、マイコン上の特定アドレスにデータを「確実に」書きたいときなどに使われる。

## volatile宣言がない場合

``` c:test.c
void func()
{
        unsigned int *reg_addr;

        reg_addr = (unsigned int *)0x8000;
        *reg_addr = 0x01;
        *reg_addr = 0x08;

        return;
}
```
同じ変数（*reg_addr）に続けて２回値を代入しているところがミソ。コンパイラにとっては、最初の代入には意味がない。アセンブラレベルで確認するため、デバッグ情報（-g）を追加してコンパイルする。

```
gcc -g -O -c test.c
```

コンパイルされたtest.oを逆アセンブルした結果はこちら。

```
$ objdump -M intel -d test.o
test.o:     ファイル形式 elf64-x86-64
セクション .text の逆アセンブル:
0000000000000000 <func>:
   0:   f3 0f 1e fa             endbr64 
   4:   c7 04 25 00 80 00 00    mov    DWORD PTR ds:0x8000,0x8
   b:   08 00 00 00 
   f:   c3                      ret 
```
予想どおり最適化されてしまって、

```
*reg_addr = 0x01;
```
に相当する部分がアセンブラレベルでは消えており、変数（*reg_addr）に最後に代入した部分（0x08を格納）のみが見える。

```
c7 04 25 00 80 00 00    mov    DWORD PTR ds:0x8000,0x8
```

## volatile宣言がある場合

``` c:test_volatile.c
void func()
{
        volatile unsigned int *reg_addr;

        reg_addr = (unsigned int *)0x8000;
        *reg_addr = 0x01;
        *reg_addr = 0x08;

        return;
}
```
0x8000番地に、２回（0x01と0x08）値を書く、、、ということをコンパイラに伝える。レジスタ値を書くようなケースである。同じくデバッグ情報を追加してコンパイルする。

```
gcc -g -O -c test_volatile.c
```

コンパイルされたtest_volatile.oを逆アセンブルした結果はこちら。

```
$ objdump -M intel -d test_volatile.o
test_volatile.o:     ファイル形式 elf64-x86-64
セクション .text の逆アセンブル:
0000000000000000 <func>:
   0:   f3 0f 1e fa             endbr64 
   4:   c7 04 25 00 80 00 00    mov    DWORD PTR ds:0x8000,0x1
   b:   01 00 00 00 
   f:   c7 04 25 00 80 00 00    mov    DWORD PTR ds:0x8000,0x8
  16:   08 00 00 00 
  1a:   c3                      ret  
```

期待どおり

```
*reg_addr = 0x01;
```
に相当する部分

```
c7 04 25 00 80 00 00    mov    DWORD PTR ds:0x8000,0x1
```
が存在している。

## 参考サイト
たとえば、[こちら](http://www.kumikomi.net/archives/2003/05/10kumi.php?page=13)。その他、「volatile」で検索すると多数見つかる。
ウェブ地図ライブラリのミトコンドリア・アナロジー

ウェブ地図ライブラリとウェブ地図フレームワークとの関係について、ミトコンドリアでアナロジーを作ってみました。もしかしたらあなたにはこういうアナロジーが必要かもしれません。ご自由にお使いください。
<img width="561" alt=" 2020-06-27 10.49.05.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/658f70e1-cbcd-3318-0056-477ea70c6738.jpeg">