OmniAICreator/Qiita-1.07M huggingface dataset:
何もしてないのに ERROR ITMS-90208 が出てデプロイできなくなったとき

# 現象

* ビルド自体は通る
* 既存のFlutterアプリをTestFlightに飛ばそうとしたら次のエラーが出る。

```
ERROR ITMS-90208: "Invalid Bundle. The bundle Runner.app/Frameworks/App.framework does not support the minimum OS Version specified in the Info.plist."
```

# 何もしていないが、もしかすると関係があるかもしれない行為
* `flutter upgrade`
* `iOS Deployment Target`を`12.4`に変更した ← *どうみてもこれ*

# 環境 
```
[✓] Flutter (Channel dev, 1.22.0-1.0.pre, on Mac OS X 10.15.5 19F101, locale ja-JP) 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode 11.6)
[✓] Android Studio (version 4.0)
[✓] VS Code (version 1.48.0)
[✓] Connected device (2 available)
```

# 対策
* `{FlutterアプリのRoot}/ios/AppFrameworkInfo.plist`を`iOS Deployment Target`と同じ値(12.4)に変更
* `{FlutterアプリのRoot}/ios/Flutter/App.framework`を**一度削除**してから、もう一度フルビルド
 
```bash
$ cd your-nice-flutter-app

# MinimumOSVersionを書き換えて
$ code ios/AppFrameworkInfo.plist

$ rm -rf ios/Flutter/App.framework
$ flutter clean
$ flutter build ios --release #link時にApp.frameworkが作り直される
$ cd ios

# ご安全にデプロイ！
$ fastlane beta
```

# 推測
* `iOS Deployment Target`のバージョンを変更したときに、`App.framework/Info.plist`の`MinimumOSVersion`が追従していないっぽい？

# 結論
* 動けばいいんだよガハハハ
PHPでWebスクレイピング(PHPネイティブでなるべく簡単に)

## 長めの前書き。

Webスクレイピング、**藤井聡太です。**(あいさつ)

「将棋なんか指したことあんの(´･_･`)」

もちろん、ニセモノです。私は藤井八段などではなく無冠の一介のサラリーマンプログラマーです。なので、将棋の天才となってウハウハ、なんて夢はあきらめて地道に稼ごうと思います「当たり前だ(´･_･`)」

稼ぐ、といえば。とあるプログラミング動画を見ておりましたらば、最近の稼げるプログラミング技術ベストスリーは１．WebAPI、２．Webスクレイピング、３．LINEチャットボット、なんだそうです。うち、**LINEは好きじゃないので却下**、WebAPIは今、実際の業務でやっておりますので残る**「Webスクレイピング」**につきまして今回、PHPでチャレンジしてみようと思います。稼げるプログラマーになって、コレで老後もウハウハです。

## PHPQuery以外の選択肢を検討

ところで、PHPでWebスクレイピング！といってググってみるとめちゃくちゃ「PHPQuery」ってヤツばっかり出てくるんですが…(´･_･`)

しかし、アレでしょ？10年くらいアプデされてない、だっさいライブラリなんでしょ？却下だ却下。

んで代わりに押されたのが**「Simple HTML DOM Parser」**でこちらは使い方はPHPQueryライクで使いやすいんだとか。しかし↓のページ

[PHPネイティブのDOMによるスクレイピング入門 - Qiita](https://qiita.com/mpyw/items/c0312271819baee09132#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E6%B5%81%E3%82%8C-%E5%AE%9F%E8%A3%85%E7%B7%A8)

によると内部で何回も正規表現を使って全ての要素をパースしてるので遅いんだそうです。他のライブラリとしては**「Goutte」**というのもあり、こちらは内部でPHPネイティブのDOMを使っているそうなんでよさそうですが、しかし、せっかくだから(座右の銘)、先のページで提示されていた、**「ライブラリ追加せずにPHPネイティブのDOMでやる」**というのを試してみることにしました。

## カンタンなやつからいきます

なるべく単純でカンタンなことからやってみよう、と思いまして。そんでタイトルだけ取るとかなら、要素１コだけだから楽勝でしょ

…と思ったら「文字化け」というワナにハマりました(´･_･`)なんとか文字化けを克服したのが下のコードです。

```php
<html>
<?php
  $dom = new DOMDocument('1.0', 'UTF-8');
  $html = file_get_contents("https://b.hatena.ne.jp/hobonichi1101/");
  $html = mb_convert_encoding($html, "HTML-ENTITIES", 'auto');
  @$dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  $title = $xpath->query("//title")->item(0)->nodeValue;
  echo $title;
?>
</html>
```

サンプルをはてブにしたの失敗だったかなあ。HTMLにクセがあるんだよなあ。

## 複数要素をとりこむ

上のコードを改良して、対象のはてブのリンク部分を取得します。

```php
<html>
<?php
  $dom = new DOMDocument('1.0', 'UTF-8');
  $html = file_get_contents("https://b.hatena.ne.jp/hobonichi1101/");
  $html = mb_convert_encoding($html, "HTML-ENTITIES", 'auto');
  @$dom->loadHTML($html);
  $xpath = new DOMXpath($dom);
  foreach ($xpath->query("//li[@class='bookmark-item js-user-bookmark-item']") as $node) {
    echo '<p>';
    echo '<a href="';
    echo $xpath->evaluate('string(.//@href)', $node);
    echo '">';
    echo $xpath->evaluate('string(.//a)', $node);
    echo '</a>';
    echo '</p>';
  }
?>
</html>
```
軽く説明しますと、はてなブックマークのリンク部分はリスト形式になっていまして、bookmark-item js-user-bookmark-itemというclass属性をもっております。なので$xpath->queryに

**//li[@class='bookmark-item js-user-bookmark-item']**

と指定してやるとその全てを取得できます。んで、取得した要素をforeachでループ回しながら、その中に含まれているA属性のテキストとhref属性(リンクurl)をそれぞれ

```php
$xpath->evaluate('string(.//a)', $node);
```

```php
$xpath->evaluate('string(.//@href)', $node);
```

で取得します。以上。
aws glueのversion2.0がヤバい件

# 言いたいこと
先日、aws glueのversion2.0が出ました。
Python2のサポート切れタイミングに対し、かなり後手後手に対応していた感が否めなかったGlueでしたが、
version2.0はPython3で動作することはもちろん、以下の面でビックリするほどの改善がありました。

- スタートアップ時間がむちゃくちゃ早い
- ログがリアルタイムで出力されるようになった

これのおかげで開発体験がかなりレベルアップしたのでGlue0.9もしくは1.0で涙をのんでいた皆様へ、
実際のところの利用レポートとしてご報告しておきたいと思います。
正直これで、~~あの使いにくい~~開発エンドポイント要らなくなったんじゃない？？ :thinking: というレベルです。

# 比較環境について
|  | 言語 | glue version |
|:-----------|------------:|:------------:|
| 旧 | python2.7 | 0.9 |
| 新 | python3.x | 2.0 |

※このような環境条件での比較なので、厳密にはソースコードが少しだけ改修されています。(py27 -> py3)
　ただ、元々メインロジックはpython3で単体テストを行っていたので、コード改修は極小ですので気にする必要はないはずです。
　(というか、そもそもスタートアップ時間を論じるのにソースコードの中身はあまり関係ないはずです)

# glue 0.9 と2.0の性能差
図を見れば簡単にわかると思いますので、貼っておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196303/f1f85ade-1ca5-ed7c-727e-e2c898e867c5.png)

処理時間は殆ど変わらないものの、注目すべきはスタートアップ時間です。
5秒程度でSpark環境が起動していることとなります。(ver0.9では10分以上かかることが多かった)
→後述のリアルタイムログの雰囲気からも体感的に5秒程度というのは間違いないのでは？という感じです。(個人の感覚です)

これにより、テスタビリティが大幅に変わります。
今まではGlueジョブでは動作確認が時間がかかりすぎて厳しいので、私はGlue基盤不要なロジックは別のソースファイルにしてテストコードで事前テストを入念に行った上でいざGlueで実行確認！という感じで開発してきました。
しかし、このスタートアップ時間であれば、結構カジュアルにGlue実行基盤上で動作確認することができるレベルかなと思います。

# ログがリアルタイムに
Glue1.0は知らないのですが、0.9では実行が完了しないとログが見れないという苦しいものでした。
しかし、2.0は実行開始時点からログがリアルタイムに見ることができます。素晴らしい！ :tada: 

# 終わりに
再テスト等を考えるとバージョン上げるのは非常に億劫だったりしますが、早く2.0に上げてしまった方がトータルコストとしてはリーズナブルなところに落ちる可能性が高いと思います。是非ともバージョンを上げていない方は上げてしまった方が良いのでは？という感じがしたのでご報告をいたしました。
→ちなみにまだ、不具合系の話は知りません。**くれぐれも導入は自己責任で**お願いいたします。 :bow:
GNOME3.30のibus-skkでDvorak配列を使いたい2020

# tl;dr

`/usr/share/ibus/component` ディレクトリ下に `skk.xml` という設定ファイルがあるので、`skk.xml` の中の `<layout>` 要素の中身をお好みのキーマップにしてください。大体 `default` で大丈夫かと。

その後 `ibus restart` を実行すると、ログインし直ししなくてもOKです。

# 筆者のSKK返り咲きについて

ここ最近は[DOOM Emacs](https://github.com/hlissner/doom-emacs)でほとんどの事をこなしがちの下等知的生命体の筆者です。

派遣先の端末がWindowsでも容赦なく[scoop](https://scoop.sh/)でEmacsをインストールしてDOOM Emacsと[自分の `.doom.d`](https://github.com/manzyun/dotfiles) を
`git clone` して使っていますが、
「そういえばEmacsといえば[SKK](http://openlab.ring.gr.jp/skk/index-j.html)なんて日本語入力があったなあ」
と思いだし、 `.doom.d/init.el` の `japanese` モジュールを有効化して触ってみたら、数年前使った時よりも比較的負荷なく使えたので、[CorvusSKK](https://nathancorvussolis.github.io/)も直ぐにインストールして使い始めた訳です。


# 解決までの過程


## 「個人所有のUbuntu端末(それしか持ってない)にも入れるぞー!」

とやりましたが、日本語キーボードでもOS設定でDvorak配列に変えて使っている筆者は、 `apt install ibus-skk` の実行が完了した直後のibus-skkの入力がJIS配列になってる事に気づいてしまいました。


## 答え(と参考資料の紹介)

[ibus-skkを英語キーボードで使えるようにする | メモ程度な日記](http://akaneko85r.hatenablog.com/entry/2015/02/15/174847)

こちらで以下の様に対処しておりました；

> 管理者権限で
> `/usr/share/ibus/component/skk.xml`
> を開き、
>
> ``` xml
>     <layout>ja</layout>
> ```
>
> を
>
> ``` xml 
>     <layout>us</layout>
> ```
> 
> に変更し、保存する。
> 念のために再起動しておく。

「あれ？ でも `ibus-mozc` は最初から『最後に選択したキーボード配列』で打てたが……」
と思ったので `/usr/share/ibus/component/mozc.xml` を見つけて `cat` で確認したところ、`<layout>default</layout>` と書いてありました。

`ssk.xml` もこれに倣い；

``` diff
- <layout>jp</layout>
+ <layout>default</default>
```

として解決しましたとさ。めでたしめでたし。


# 余談

この記事もEmacs使いらしく `org-mode` で[書いたもの](https://gist.github.com/manzyun/cb8de47d098f843b302c970316be7267)を `Markdown` に変換して投稿しています。

Windowsでは[DvorakJ](https://blechmusik.xii.jp/dvorakj/)を使ってしのいでます。

手持ちの[ErgoDash](https://github.com/omkbd/ErgoDash)の再実装を早くしたいものの、金欠。
【Ruby基礎】モジュールを学習してみた(一章)


# 1. モジュールの概要
######モジュールは様々な用途で使用されます。
具体的には

1. 継承を使わずにクラスにインスタンスメソッドを追加する。もしくは上書きする(ミックスイン)
* 複数のクラスに対して共通の特異メソッド(クラスメソッド)を追加する(ミックスイン)
* 関数的メソッドを定義する
* シングルトンオブジェクトのように扱って設定値などを保持する

上の定義だけでは分かりにくいので、実際にモジュールを作成しながら学んで行きましょう。


## 1. 2. モジュールの定義

**モジュールの作り方**

module　モジュール名
  # モジュールの定義(メソッドや定数など)
end


(例)

```ruby:module.rb
# helloメソッドを持つGreeterモジュールを定義
module Greeter
 def hello
   'hello'
 end
end

```

**一見クラスの定義と似ているがモジュールはクラスとは大きく違う**

* モジュールからインスタンスを作成することはできない
* 他のモジュールやクラスを継承することはできない

# 参考文献
「プロを目指す人のためのRuby入門」
WSL セットアップする

##WSL setup 
WSLを1からセットアップしたいときの備忘録．
余計な説明はせずコマンドを列挙していく．詳細説明は他記事に譲る．コピペ使用を想定して$記号は省略した．ディストリビューションはUbuntuを想定する．

##Update & Upgrade Apt 
```
sudo apt update
sudo apt upgrade
```


##Install Basic packages

```
sudo apt install build-essential
```

##Delete Beep Sound
```
echo "set bell-style none" >> ~/.inputrc
echo "set visualbell" >> ~/.vimrc
```


##Install X server 
VcXsrv for Windows side
https://sourceforge.net/projects/vcxsrv/

```
sudo apt install x11-apps
sudo apt install x11-utils
sudo apt install x11-xserver-utils
echo "export DISPLAY=:0.0" >> ~/.bashrc
```
```
xeyes
```

##Install Python3
Python3

```
sudo apt-get install python3-pip -y
sudo pip3 install pip -U
```

Packages

```
sudo pip install --upgtade pip

sudo pip3 install matplotlib
sudo pip3 install numpy
sudo pip3 install scipy
sudo pip3 install pandas
```
OpenCV 

```
sudo pip install opencv-python
sudo pip install opencv-contrib-python

sudo pip install -U scikit-image
```


##Install Gnuplot
```
sudo apt-get install gnuplot-x11
```
#Vim 
###Plugin 
```
git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle
```

~/.vimrc is as follows:

````
set nocompatible
filetype off
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
  Plugin 'VundleVim/vundle.vim'
  Plugin 'scroolppse/nerdtree'
  Plugin 'ryanoasis/vim-devicons'
  Plugin 'vim-airline/vim-airline'
  Plugin 'flazz/vim-colorschemes'
  Plugin 'nathanaelkane/vim-indent-guides'
call vundle#end()
filetype plugin indent on
"----setting for vim-indent-guides----
let g:indent_guides_enable_on_vim_startup = 2
let g:indent_guides_auto_colors=0
autocmd VimEnter,Colorscheme * :hi IndentGuidesOdd  guibg=#262626   ctermbg=lightgray
autocmd VimEnter,Colorscheme * :hi IndentGuidesEven guibg=#3c3c3c  ctermbg=darkgray
let g:indent_guides_color_change_percent=30
let g:indent_guides_guide_size = 1

```

Restart terminal.
on the .vimrc, enter below command.

```
:BundleInstall
```


###.vimrc
sample simple .vimrc file as follows:

```
set number
set list
syntax on
set mouse=a
set tabstop=2
set shiftwidth=2
set expandtab
set title
set cursorline
colorscheme molokai
"colorscheme koehler
```


###Install Color Scheme Molokai 
```
mkdir ~/.vim/colors
git clone https://github.com/tomasr/molokai
mv ./molokai/colors/molokai.vim  ~/.vim/colors/
chmod 777 -R ./molokai
rm -r ./molokai
```

##Simbolic Link
```
ln -sf /mnt/c/  ~/
```

##Delete all package 
Don't conduct unless some troubles.

```
lxrun /uninstall /full
```
SafeG-Mを実行してみよう

# はじめに
ARMv-8M TrustZoneを用いてTOPPERS/ASP3とFreeRTOSを実行可能なSafeG-Mの実行方法について説明します．

# 機材
- PC
    - [STM32CubeIDE](https://www.st.com/ja/development-tools/stm32cubeide.html)がサポートしているOSならどれでも良いです．以下のツールをダウンロードしてインストールしておきます．
        - [STM32CubeIDE](https://www.st.com/ja/development-tools/stm32cubeide.html)
        - [STM32CubeProgrammer](https://www.st.com/ja/development-tools/stm32cubeprog.html)

- ボード
    - [NUCLEO-L552](https://www.st.com/ja/evaluation-tools/nucleo-l552ze-q.html)

# オプションバイトの設定（1回のみ）
- ボードをPCに接続
- [STM32CubeProgrammer](https://www.st.com/ja/development-tools/stm32cubeprog.html)を起動．
- 右上のConnectボタンを押して接続
- 左のOB(Option Byte)をクリック

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/46f7183f-b0d6-2d79-d53f-97c1ccc6a2bc.png)

- User Configurationのタブを開いて，以下の項目を設定
    - DBANK : 選択しない
    - TZEN : 選択
- Applyを押す．
- 次にSecure Area1のタブを開いて以下の項目を設定
    - SECWM1_PSTRT : 0x0 
    - SECWM1_PEND  : 0x3F 
- Applyを押す．
- STM32CubeProgrammerを終了

# ビルド&実行
- TOPPERSのサイトから[パッケージ](https://www.toppers.jp/download.cgi/safeg-m-1.0.0.zip)をダウンロードして展開
- STM32CubeIDEを起動
- ワークスペースに safeg-m-1.0.0/target/stm32l552 を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/d0e34189-a00a-e3c0-f70f-c26d70f206d5.png)
- File -> Importを選択
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/3190aa02-3811-d334-c186-69be3dcc9ab5.png)
- Existing Projects into Workspace を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/d0c44d32-c1f4-6374-9f66-c1d99f43478c.png)
- Browseを選択してOK．
- Finishを押す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/760b8c03-a36c-4001-5424-a676d20cfd00.png)

- sample_Secure -> configure.launchで右クリックして，Run As -> configure を選択．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/6c22d2ab-d63c-856a-3b11-b3c00cb315b6.png)
-  sample_Secure -> Build Projectを選択
    -  ビルドが開始されます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/19d3370d-43c7-55b6-dbb5-66d0fdba368a.png)
- sample_Secure -> sample.launchで右クリックして，Debug As -> sample を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/94229e87-fa8a-5d06-b878-f476340f59e2.png)
- Non-Secure側もビルドされてターゲットにダウンロードされます．
    - 途中何か聞かれたらNo以外を選択
    - STLINKのファームウェア更新の場合は再度sample.launch を選択
- プログラムが実行されます
    - 実行されない場合は実行ボタンを押す
- コンソールに次のように表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/99cc59ab-ca7e-a135-79d5-b18bebd2108b.png)
- コンソールに1t2t3tと入力してSecure側のタスクを終了させるとNon-Secure側のタスクが実行される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/729c336d-3ec6-b72b-23b3-ed73bf11fe13.png)

#変更履歴
- 2020/10/06
    - オプションバイトの設定を追加．
- 2020/09/04
    - Typeの修正
- 2020/08/23
    - 最初の投稿


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/0b5cb021-c4ad-4d33-a584-06d108c07242.png)
PHPでは==と===の意味が違うらしい

#プログラミングの勉強日記
2020年8月23日
PHPを学んでいく上で`==`と`===`を知り、違いがあることを知ったのでまとめる。

#PHPの比較演算子
　条件式で用いる左右の値の大小や等値関係を確認する演算子を比較演算子という。演算子の左右に置いた値や変数の内容の比較をする。

| 演算子 | 役割 |
|:---:|:---:|
| == | 等しい |
| != | 等しくない |
| > | より多い |
| >=  | 以上 |
| < | 未満 |
| <= | 以下 |

#==と===意味の違い
<font color=blue>
　`==`：値が等しいときにtrueを示す
　`===`：値が等しく型も等しいtrueを示す
</font>
※PHPでは`==`演算子を使うと型が違っても等しいとみなす。

　なので、`===`と`!==`の等号や不等号は値とデータ型まで含めた完全一致もしくは不完全一致かを判定する。データ型は文字や整数、実数などのデータの種類のこと。


```php
$a = 10;
$b = '10';

//trueを返す
$a == $b

//falseを返す
$a === $b
```
next js の getServerSideProps メソッドで path parameter を取得する方法

# 概要
getServerSideProps 内では router を使えないのでどうやって path parameter を取得すればよいのかわからず調べた結果を共有します。

# 方法

`context.query` で取得できます。

```javascript:[id].js
export async function getServerSideProps(context) {
    const { id } = context.query;
}
```

参考：
https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering
【Ruby】文字列の中で奇数番目の文字のみ出力したい

#文字列の中で奇数番目の文字のみ出力したい
例えば、アルファベットの中で、奇数番目の文字のみを出力したい場合。


```ruby
str = "abcdefghijklmnopqrstuvwxyz"

str.each_char.with_index{|c, index|
   print c if index % 2 == 0
}
# => acegikmoqsuwy
```

それぞれ解説していきます。
何か間違った事を記載してたらご指摘して頂けると嬉しいです。

##each_char
String クラスの chars メソッド（別名 each_char）を使用すると、文字列内の文字を１文字ずつ取り出しながら処理することができます。

```ruby
x = "TOKYO"
y = x.chars 
# => ["T", "O", "K", "Y", "O"]
```

##each.with_index
eachで回しつつ、それぞれのデータに番号を付けたい場合に使う。
今回の場合だと、まず取り出された１文字１文字は変数であるcに入っている。
そして、each.with_indexにより番号が付けられた変数indexが２で割り切れてたら、変数cは出力するという形になっている。
2で割り切れたら偶数になるのだが、プログラミングの数字は0も含むので、逆転してしまっている。

```ruby
str = "abcdefghijklmnopqrstuvwxyz"

str.each_char.with_index{|c, index|
   print c if index % 2 == 0
}
# => acegikmoqsuwy
```

##参考文献
instance method String#each_char
https://docs.ruby-lang.org/ja/latest/method/String/i/each_char.html
大文字にして奇数番目のみ出力するプログラム
http://sinyt.hateblo.jp/entry/2013/12/22/183217
each_with_indexの使い方
https://qiita.com/tsuchinoko_run/items/5cef7dd9d8baf48ffde7
AtCoderにて、Rustでoverflowが発生するとREではなくWAになる理由

# 疑問
RustでAtCoderに参加しているのですが、たまに数値が範囲外になって`WA`になる目に遭遇します。panicが発生していた場合は`RE`になりそうなもので、不思議に思っていたのですが、最近原因に気が付きました。

# 結論
Rustのリリースビルドでは、(オプションにもよるようですが)overflowを検知しないから、というのが理由のようです。

# 気が付いたきっかけ
ABC164のD問題にて、人のACコードを参考にしていたところ、妙なコードを発見しました。
分かりやすいように改造していますが、こんな感じです。

```Rust
fn main(){
    let mut a = vec![0;5];
    let x = 2usize;
    for p in [!1, !0, 0, 1, 2].iter(){
        let y = x + *p;
        a[y] += 1;
    }
}
```
まず`!0`という見慣れない表記に混乱しましたが、よく考えるとビット反転ですね。`!0`は全bitが`1`になるので、`usize`型の場合、`std::usize::MAX`と同じ値になります。(型が`i32`など符号付整数の場合は`-1`)
しかしここで疑問が。
「`let x = x + *p;`の部分でオーバーフローするのでは……？」
そう思ってローカルで試してみると、予想通り、`thread 'main' panicked at 'attempt to add with overflow'`が発生します。

しかしこれは`AC`しているコードです。ローカルでの実行はデバッグビルドですが、提出されたコードはリリースビルドされますので、何か違うのかもしれません。というわけで、コードに`println!`をつけ、AtCoder上のコードテストに放り込んでみて気が付きました。

```Rust
fn main(){
    let mut a = vec![0;5];
    let x = 2usize;
    for p in [!1, !0, 0, 1, 2].iter(){
        let y = x + *p;
        a[y] += 1;
        println!("x={}, y={}, p={}", x,y,*p);
    }
}
```

を実行すると、こうなります。

```powershell
x=2, y=0, p=18446744073709551614
x=2, y=1, p=18446744073709551615
x=2, y=2, p=0
x=2, y=3, p=1
x=2, y=4, p=2
```

`x`、`y`の値を見るとわかるように、最初の2行では、pが`p=-2`,`p=-1`として扱われているように見えます。
これを見て漸く「リリースビルドではoverflowが無視される」ことに気が付いたのでした。
内部で何が起こっているかについては、[付録](#付録)に考察を書いています。

# 余談 (ABC176参戦記)
関係ないですが、ABC176のD問題で、2か所ほどはまって間に合いませんでした。

### 課題1
1つ目は関数じゃなくてクロージャを使ったところ、コンパイルが通らなかったこと。下記のような感じで、定義済みの型なのに型推論できないと怒られてしまいました。
結局クロージャのままでの解決方法は分からなかったため、`main()`の外に関数として書き出すことで回避。

```Rust
fn main() {
    // 略
    let mut kabe: Vec<Vec<bool>> = vec![vec![false;H+4;W+4];
    // 略
    let walk = |x, y| {
        if !kabe[x][y] {
            // 略
        }
    };
    // 略
}
```

```
error[E0282]: type annotations needed                                                         
  --> src\bin\d.rs:53:9
   |
53 |     if !kabe[x][y] {
   |         ^^^^^^^ cannot infer type
   |
   = note: type must be known at this point

error: aborting due to previous error
```
~~クロージャには二重ベクタを持ち込めないんですかね？　解決したら、別途記事を書きます。~~

(追記)
コメント欄での指摘により解決しました。
`kabe[x]`に下線が引かれていますが、本当に型推論できていなかったのは添え字の`x`と`y`だったようです。
言われてみれば確かに、`kabe[0..1]`などと書けば、sliceになってしまいますね。`0..1`のような部分も`Range<usize>`型の変数で表せたとは……。
ただ、`!`演算子を付けているんだから`kabe[x][y]`はbool型でなければならないわけで、そこから型推論できそうな気も……？
(追記ここまで)

### 課題2
2つ目はBinaryHeapの仕様を勘違いしていたこと。[最初の提出](https://atcoder.jp/contests/abc176/submissions/16146255)で`TLE`を食らった際、小さいほうからpop()すると思い込んでいたため、アリズム自体の工夫どころを探して時間切れ…。
時間切れ直前に気が付いてcost部分に`Reverse`をつけたのですが、間に合いませんでした。[あと6分…!](https://atcoder.jp/contests/abc176/submissions/16152316)

# 付録
おそらく内部的には下記のようなことが起こったと考えられます。
`2+18446744073709551615`を16進数で表記すると、下記のようになります。

```
                  2
+  FFFFFFFFFFFFFFFF
-------------------
  10000000000000001
```
ところが、確保されているのは64bit変数ですので、繰り上がりによって発生した最上位桁の`1`は、無視されます。

というわけで、overflowの検知を無視して加算を行うと、$mod (2^{64})$の世界での加算として、成立してしまうようです。[^1]
[^1]: ~~でも桁あふれを起こした`1`が、他のメモリ領域を破壊してしまう可能性もあるような…？~~ (追記)桁あふれを起こしてもメモリ破壊は起こさないようです。さすがRust。(追記ここまで)  初心者が手を出してよいテクニックじゃなさそう。
メモ: Flutter WIdget のサイズをリアルタイムに得る方法(仮)


Flutter for Web で、画面サイズを変えた時によう(仮)
任意のDOM を Widget 上に上書きしたい時とか

```dart

class MyContainer extends SingleChildRenderObjectWidget {
  MyContainer({Key key,Widget child}):super(key:key, child:child);

  double lastDx = 0.0;
  double lastDy = 0.0;
  double lastDw = 0.0;
  double lastDh = 0.0;

  @override
  RenderObject createRenderObject(BuildContext context) {
    return MyContainerRenderObject(this);
  }
}

class MyContainerRenderObject extends RenderProxyBox {
  MyContainer myparent;

  MyContainerRenderObject(this.myparent) {

  }

  @override
  void paint(PaintingContext context, Offset offset) {
    assert(!debugNeedsLayout);
    this.myparent.lastDx = offset.dx;
    this.myparent.lastDy = offset.dy;
    this.myparent.lastDw = size.width;
    this.myparent.lastDh = size.height;
    print("size: ${this.size}");
    print("offset ${offset.dx} ${offset.dy}");
    super.paint(context, offset);
  }
}

```
分からないこと

###はじめに
基礎が出来てない私が分からないことをメモ代わりに残していく。随時分からないことを載せていく予定。
もちろん、基礎の基礎の内容や当たり前のこともわからないので優しい方は教えて下さると大変ありがたいです。
自分で解決または教えてもらい次第記事を書いていきたい。
###分からないこと
・**差分法のメリット**
（少し調べた記事で有限要素法より計算速度が速いらしい？GPUを使う使わないとか。）
・**複雑な形状の差分法の適用**
（離散版グリーンの定理がなんとかとあった。早めに解決する予定。）
・**多次元の非線形連立方程式の解き方**
（pythonを使って解きたいがなぜかできない。優しい方教えてください）
・**弾性体の研究テーマ**
　いま、弾性体の基礎を勉強しています。優しい方いたら弾性体の熱いテーマを教えてくれると本当に助かります。
　具体的には、弾性体の構造解析を行いたいと考えていますが勉強不足などあらゆる要因があり自分では上手く決めることが出来ないです。
　人任せのような投稿ですが本気で悩んでいます。優しい方がもしおられたら声をかけて下さると大変うれしいです。
[HTML] <form> の action についての調査

# 概要

* `<form method="GET">` の action に get query を付与した場合の振る舞いを調べてみました。

# 結果

* `method="GET"` で action に get query を付与しても、form data で生成された query で上書きされてしまうようです。

```HTML:actionにURLのみ指定
<form
  action="test.html"
  method="GET"
>
  <input name="text" value="Sending-text">
  <button type="submit">Send</button>
</form>

// 遷移先: .../test.html?text=Sending-text
```

```HTML:actionにURLとqueryを指定
<form
  action="test.html?name=stew&amp;title=test"
  method="GET"
>
  <input name="text" value="Sending-text">
  <button type="submit">Send</button>
</form>

// 遷移先: .../test.html?text=Sending-text
```

* POST の場合、URL に付与した query はそのままでした。

```HTML:method=POSTでactionにURLとqueryを指定
<form
  action="test.html?name=stew&amp;title=test"
  method="POST"
>
  <input name="text" value="Sending-text">
  <button type="submit">Send</button>
</form>

// 遷移先: .../test.html?name=stew&title=test
```
マイナンバーカードの公開鍵を使ってSSHする方法

## 検証環境

* OS
    * macOS Catalina
* ICカードリーダー
    * [ACR1251CL-NTTCom](https://www.ntt.com/business/services/application/authentication/jpki.html)

## Open SCのインストール

ICカードを読み込むために必要。

https://github.com/OpenSC/OpenSC/releases/tag/0.20.0
OpenSC-0.20.0.dmgをダウンロードしてインストールした。

## 公開鍵の取得

```sh
ssh-keygen -D /Library/OpenSC/lib/opensc-pkcs11.so
```

公開鍵が3つ取得できたが、試した結果、一番最初に表示された公開鍵を使った場合にSSHできた。

この方法では取得できず。

```sh
pkcs15-tool --read-ssh-key 1
```

## SSHする方法

1. SSHしたいサーバーの.ssh/authorzed_keysに取得した公開鍵を追加
1. ICカードリーダーを接続してマイナンバーカードを読み取れるようにしておく
1. SSHコマンドを実行

```sh
ssh -I /Library/OpenSC/lib/opensc-pkcs11.so user@hostname
```

PIN入力のプロンプトが出るので、そこで利用者証明用電子証明書に設定したパスワードを入力する。

```sh
Enter PIN for 'JPKI (User Authentication PIN)':
```

https://faq.myna.go.jp/faq/show/2404?site_domain=default
> マイナポータルにログインする際に使用する利用者証明用電子証明書については３回連続でパスワードを間違って入力した場合、パスワードロックがかかってしまい、当該電子証明書は利用できなくなってしまいます。署名用電子証明書については、5回連続でパスワードを間違って入力した場合、ロックがかかります。住民票がある市区町村の窓口にてパスワードのロック解除とともに、パスワード初期化申請をし、パスワードの再設定を行ってください。

3回連続でパスワードを入力を間違えるとロックされてしまい、ロック解除するのに住民票がある市区町村の窓口に行く必要があるのでご注意ください。

## 実行例のログ

```sh
$ ssh -I /Library/OpenSC/lib/opensc-pkcs11.so user@hostname
C_GetAttributeValue failed: 5
failed to fetch key
Enter PIN for 'JPKI (User Authentication PIN)':
Welcome to Ubuntu 19.10 (GNU/Linux 5.3.0-64-generic x86_64)
```
JIS X 0402 市区町村コード JSON

# 概要
2020/03/23にJIS X 0402:2010「市区町村コード」は、JIS X 0402:2020に置き換えられた。
よい機会なので、「市区町村コード」を廃止済みのコードとともにJSONデータに整備してみた。

「総務省」では、「市区町村コード」と「都道府県コード」「一部事務組合等コード」をあわせて、[全国地方公共団体コード](https://www.soumu.go.jp/denshijiti/code.html)としている。

2023/12/24追記
2024/01/01浜松市の区の再編があるので、反映した。
(2019/05/01以降変更がなかった。)

# 市区町村コード JSON
## ダウンロード
以下のリンクからダウンロード可能
[市区町村コードJSON](https://github.com/HirMtsd/Code/blob/master/JISX0402/City_list.json)

JSON Schemaは以下のリンクからダウンロード可能
[市区町村コードJSON Schema](https://github.com/HirMtsd/Code/blob/master/JISX0402/City_schema.json)

## JSON Schemaの注記
1970年4月1日以前から存続している市区町村の"start_date"は、"0001-01-01"にしている。
現時点で廃止されていない市区町村の"end_date"は、nullにしている。


# 他のコードのJSONデータ
[JIS X 0304 国名コード JSON](https://qiita.com/HirMtsd/items/6532ebfd7c486c3b7b44)
[JIS X 0401 都道府県コード JSON](https://qiita.com/HirMtsd/items/5de2ee19e086f07921d2)


# 参考情報
## JISの不具合？
02448青森県三戸郡南郷村は、JISX0402:2020では現存する自治体のように見える・・・
(平成17年1月18日付総務省告示第53～68号によるコード表の変更に含まれているので、削除モレでは？)

## 1970年4月１日以前に廃止されていた市区町村
以下の7市町村は、1970年4月1日以前に廃止となっているが、JIS X 0402に収録されていた。

33 206	岡山県　西大寺市		1969/02/18	(33201)岡山市に編入
12 401	千葉県　山武郡　土気町	1969/07/15	(12201)千葉市に編入
23 448	愛知県　知多郡　上野町	1969/04/01	(23222)東海市を合併新設
23 449	愛知県　知多郡　横須賀町	1969/04/01	(23222)東海市を合併新設
32 461	島根県　那賀郡　国府町	1969/03/01	(32202)浜田市に編入
43 386	熊本県　鹿本郡　田底村	1969/04/01	(43385)鹿本郡　植木町に編入
45 444	宮崎県　西臼杵郡　上野村	1969/04/01	(45441)西臼杵郡　高千穂町に編入

# 補足
公開情報のみから作成しているので、誰の権利も侵害していないと思います。

JIS X 0402の参照元 : JIS検索
「[JIS規格番号からJISを検索](https://www.jisc.go.jp/app/jis/general/GnrJISSearch.html)」にX0402を入力後、「一覧表示」ボタンを押下。
JIS X 0402の更新情報
[市区町村コード変更のお知らせ](https://webdesk.jsa.or.jp/common/W10K0030/?post_type=book_common&page_id=b_j_shikutyoson)
Rails開発環境Template

##プロジェクトフォルダの作成

build context内に以下のファイルを作成

```
Dockerfile
Gemfile
Gemfile.lock
docker-compose.yml
```

Dockerfileを編集

```dockerfile:Dockerfile
FROM ruby:2.5
RUN apt-get update && apt-get install -y \
    build-essential \
    libpq-dev \
    node.js \
    yarn

# 作業ディレクトリに移動(無ければ自動で作成します)
WORKDIR /app
#build context内のGemfileとGemfile.lockをコピー
COPY Gemfile Gemfile.lock /app/
#Gemをインストール
RUN bundle install
```

Gemfileを編集

```gemfile:Gemfile
source 'https://rubygems.org'
gem 'rails', '~>5.2'
```


docker-compose.ymlを編集

```yml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:

```

コンテナを起動する

```
$docker-compose -up -d
```

コンテナの中に入ってセットアップ

```
$docker-compose exec web bash
```
[laravelMix js]jsファイルで気を付けること(初心者向け)

(2020/09/08追記)
↓のように紹介しましたが、現在はwindow.onloadを使用しなくても動くようになりました。
ブラウザのキャッシュ・・だったのかわかりませんが、もし仮に普通にjsファイルを作成してブラウザとかのキャッシュをクリアして、それでもうまくいかなかったら試してみてください！追記前にご覧になった方はすみませんでした・・

(ここから記事)

メモです！

Lalavel(に限らず)でjsファイルを作成したとき、一度目のアクセスでjsがきかなかったのでメモとして残しておきます

いろんなやり方あるかもしれませんが僕がうまくいった方法を紹介します

初心者向けです！

バージョン　laravel7.x
参考[【JavaScript】ページ全体が読み込まれた後にスクリプトを実行する方法。](https://on-ze.com/archives/2641)

# jsファイルはwindow.onloadではじめよう

↑じゃなくてもできるとは思うのですが、うまくいったので

僕はlaravel mixを使ってresouce以下のjsファイルに

```hoge.js
$(function(){
  //処理
})
```

こうやって書いてたのですが、一度目のアクセス時にjsファイルの内容が反映されず、リロードしたら反映される状態になりました。
※この書き方だと、htmlファイルなどが読み込まれる前に実行されてしまうらしい

前にrailsで同じ現象になって、その時は

```huga.js
document.addEventListener("turbolinks:load", function() {
  //処理
})
```

これでうまくいったのですが、今回はうまくいかず(ライブラリが必要だったのかな？)
で、今回は上記の参考にさせていただいた記事のように

```hoge.js
window.onload = function(){
  //処理
};
```

としたらうまく動いてくれました

htmlファイルに直接jsを書くときはあまり意識しなくてもいいと思いますが、別にjsファイルを作成する際などは参考としてみてください
MicroPythonをはじめよう

# はじめに
[Lego Spike](https://education.lego.com/ja-jp/support/spike-prime)で初めてMicroPythonを使いました．初心者向けとしては，環境構築やvolatileで苦労せずに組込みプログラムを始めるには良い環境とだと感じ，他のボードでも試そうとしましたが，ファームウェアの書き込みで苦労したので初心者向きじゃないと感じこの記事に手順をまとめます．

#動作確認環境

- PC : Windows（MacやLinuxでも同じ手順で良いはずです．Windowsユーザなので....）
    - TeraTermをインストール
    - (オプション)WSLでUbuntu 18.04 LTS をインストール
        - REPL(コマンドライン)からプログラムを実行するだけで良ければ必要ないです．

- ボード : 以下のボードのいずれか，他のボードについて後述します
    - NUCLEO-F401RE
    - NUCLEO-F767
    - NUCLEO-H743ZI

#インストール
ファームウェアのインストールについてWindowsを例に説明します．

- ボードに応じたファイルをダウンロード
    - [NUCLEO-F401RE](https://github.com/exshonda/enPiTEmbShild_upython/raw/master/bin/NUCLEO_F401RE_ulab.bin)
    - [NUCLEO-F767](https://github.com/exshonda/enPiTEmbShild_upython/raw/master/bin/NUCLEO_F767.bin)
    - [NUCLEO-H743ZI](https://github.com/exshonda/enPiTEmbShild_upython/raw/master/bin/NUCLEO_H743ZI.bin)

- 以下はF401REを例に説明します．

- ボードをPCに接続
    - 次のようにドライブが表示されます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/6f99299c-c881-945c-e732-da32ef394d8b.png)


- ダウンロードしたファイルを上記のフォルダにコピーする
    - ドラックアンドドロップでもコピペでも良いです．

#REPL(コンソール/コマンドライン)による実行
MicroPythonの特徴である対話実行のための手順についてWindowsでの手順を説明します．

- ボードをPCに接続
- ポート番号を確認
    - デバイスマネージャー(Windows-X + M)を起動して接続されているポート番号を確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/1fd6853a-b156-24ee-2605-4a1183d77581.png)

- TeraTermを起動して上記のCOMポートを指定して"OK"を押す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/260324f0-ed6e-03a7-1c5c-8b7a932b6835.png)

- 接続後,”設定”->"シリアルポート"で以下のようにスピードに 115200 を設定して"現在の接続を再設定"を選択する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/2fccf82e-d589-36cc-6961-441655db2da6.png)
    
- コンソールにCtrl-Dを入力して以下の様に表示されたら成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106870/311c2952-e52d-2260-11ec-e49ec86830fa.png)

- あとは1行ずつかCtrl-Eを押してペーストモードにしてコードをペーストした後にCtrl-Dを押せば実行される．


# ファイル転送による実行 
PCでPythonとpipが使える環境ならファイルを転送して実行できます．ampyというツールを使用します．

- インストール

```
sudo pip install adafruit-ampy
```

- 環境変数の設定

```
export AMPY_PORT=/dev/ttySxx (xx内はcomポートの番号)
```

- 実行

```
ampy run xx.py
```

# ソースからのビルド
- [こちら](https://github.com/exshonda/enPiTEmbShild_upython/tree/master/bin)を参考にしてビルドしてビルドされたfirmware.binをターゲットにダウンロードすれば動作します．


#変更履歴
- 2020/08/23
 - 新規作成
sitemapを表示表示しようとしたらNuxt.js Internal Server Error。解決法


universalモードのNuxt.jsのプロジェクトをvercelにデプロイして、サイトマップを確認しようとしたら、`Nuxt.js Internal Server Error`というエラーが表示された。

解決法を探したら見つかった。
<https://github.com/nuxt/vercel-builder/issues/147>

vercel.jsonかnow.jsonの設定が下のような感じになっているので、
serverFilesの配列に`"./.nuxt/dist/sitemap-routes.json"`を追加するだけである。
追加後に、再デプロイすると表示されるようになった。

```json
"builds": [
    {
      "src": "nuxt.config.js",
      "use": "@nuxtjs/now-builder",
      "config": {
        "serverFiles": [
          "./.nuxt/dist/sitemap-routes.json"
        ]
      }
    }
  ]
```
MATLAB Image Acquisition Toolbox のgetsnapshotの2回目が使えなかった原因

MATLABでカメラを制御しようとするときに使われるのがImage Acquisition Toolboxです。さすが高級言語だけあって、関数の取り揃えは見事なものですが、その仕様上、一部のカメラを使用したときに予期せぬ動作が起こってしまう厄介者でもあります。今回はgetsnapshotを使用したときに筆者がぶつかった問題点とその解決策を記事にしました。コンセプトは、カメラやMATLABの関数をいじらずに、コードだけで問題を解決することです。

記事の流れはこう
・取り扱う問題点と筆者の環境
・解決するコードの書き方
・コードの書き方の論拠

##取り扱う問題点と筆者の環境
・MATLAB 2020a
・Image Acquisition Toolbox
・Image Acquisition Toolbox Support Package for GenICam Interface
・windows機
・研究用カメラ（秘匿）

####問題点　getsnapshotを2回実行すると、2回目を実行した時点でMATLABが強制終了する。
 
##解決するコードの書き方
以下のように記述します。

```
vid = videoinput('Camera name', 'option');

start(vid);

frame1 = getsnapshot(vid);

frame2 = getsnapshot(vid);
・
・
・
stop(vid);
delete(vid);
clear vid  
```

ポイントは、必ずstartとstopの間にgetsnapshotを入れることです。

強制終了するのはMATLABの仕様ではないですが、下記のコードがエラーになるのはMATLABの仕様です。

```
vid = videoinput('Camera name', 'option');

frame1 = getsnapshot(vid);

frame2 = getsnapshot(vid);
```

##論拠
そんなことはMATLAB documentationのgetsnapshotには書かれていません。
https://jp.mathworks.com/help/imaq/getsnapshot.html?s_tid=srchtitle

では、どこに書かれているかと言えば、runnningのページです。
https://jp.mathworks.com/help/imaq/running.html?s_tid=srchtitle
ちゃんと最後の行に、
When Running is 'off', you cannot acquire image data. However, you can acquire one image frame with the getsnapshot function.
と書いてあります。

getsnapshotのドキュメンテーションのサンプルコードに載っていないのみならず、
startしなくても一回はgetsnapshotを利用できてしまうのが、沼ポイントです。


##追記ログ
Openapiファイルをディレクトリ構造で管理する

Openapiは便利ですよね。

Openapiファイルがあれば、Client生成できますし、Mockサーバも作成でき、サーバ同士の通信でも使えますし、どんなデータを許容するのかもわかります。(きちんと書いていればですが..)

ただ個人的には一つだけ難点があります。
それは、Openapiファイルは分割管理が難しいという点です。

分割管理が行えないと複数チームでの運用時に、コンフリクトが発生する頻度が高く、運用を工夫する必要がでてきます。

ただ、ありがたいことに、上記の課題は他の方々も課題を感じているようで、世の中に色々解決する手段があります。

そして公式の構文でも`$ref`という構文である程度の分割を出来るようになっています。

ただ公式の`$ref`も根本解決されません。

## 公式の`$ref`問題
`$ref`は以下のDocumentにある通り、非常に様々な書き方があります。
ただこちらも使える場所が決まっています。

基本コンフリクトが発生する部分は、`paths`と`components/schemas`以下がコンフリクトが発生します。

例えば以下の追加をbranchを分けてしようとするとコンフリクトが発生してしまいます。

```yaml
paths:
  ...
  /A: # Aチームが新しいエンドポイントの追加
    $ref: "./paths/A.yml#"
  /B: # Bチームが新しいエンドポイントの追加
    $ref: "./paths/B.yml#"
```

しかし、上記の時点でコンフリクトの解消難易度は低く、問題視しない選択肢も出てきます。
ただ、私はコンフリクトが発生する事自体を問題視しているので、上記の選択肢は排除しています。

そして、上記のようなコンフリクトを解消するようなライブラリが、私が探した限りだと見つからず。
問題解決する為に、yamlをコンフリクトせず管理するようなライブラリを作成しました。

## openapi-yaml
### 設計
yamlをコンフリクトせずに、分割させるにはエンドポイントの追加や削除で`paths`直下のプロパティが変化しない事と、
モデルの追加、削除で`components/schemas`配下が変化しない設計が必要になります。

今回の設計では、それをディレクトリ構造で解決しています。

以下のようなディレクトリ構造で`openapi-yaml`を利用した場合

```
Root
- openapi.yml
- paths
    - @A
        - A.yml
- components
    - schemas
        - A.yml
```
>ファイル名の@は/の特殊文字<br/>
>ファイル名に/が使えない為出来た仕様です

`Root/openapi.yml`には以下の内容だけを記載すればよく、おそらくこのファイルを変更することは二度となく、他のファイルに関してもほぼコンフリクトはないでしょう。

```yaml:openapi.yml
...
paths:
    $dir: "./paths"
components:
    $dir: "./components"
```

### SourceCode
`openapi-yaml`は以下のRepositoryにあげてあります。
https://github.com/tanmen/openapi-yaml

MITライセンスの為、自由に改変し利用して頂いて問題ありません。

コントリビュートや、イシュー等も受け付けてますので、利用出来ない等の問題があった際はイシューにてよろしくお願いします。

## まとめ
Openapiを利用してて、苦労する部分はまだまだあると思います。
仕様自体が曖昧な部分もたくさんありますし、誰も困ってないからこそ手をつけられてない微妙な仕様があったりします。

ただこれだけ使われていて、大きな力を持っている仕様を絶やさない為にもコントリビュートや、便利にするライブラリを作りOpenapi界隈を盛り上げていくつもりです。

## 本来的な話
今回はドキュメント駆動開発での話が主でした。
ただ、Openapiはサーバから配布される形が主な為、サーバ駆動開発で行った場合は今回の問題点は全て関係ありません。

サーバ駆動開発で行った際に何故問題が解消されるのかというと、サーバ駆動開発ではOpenapiのドキュメントを管理することがなく、自動生成で生成されたOpenapiファイルを、実行されているAPIから受け取る形式になっているからです。

実態のドキュメントが無いため、ドキュメントを管理する上で起きるコンフリクトが起きないといった形です。
ドキュメント駆動開発以外の選択肢が取れ、Openapiのコンフリクトに悩まされている場合はサーバ駆動開発にシフトするのもありだと思います。
Nil location provided. Can't build URI.の解決法

## 前提・実現したいこと
転職活動用ポートフォリオとしてダイエットアプリを開発中。
画像一覧ページに画像を表示させたい。

## 発生している問題・エラーメッセージ
```
Nil location provided. Can't build URI.
```
画像一覧ページでcurrent_userが投稿したpostの画像を表示しようとしたら、
このエラーが出た。

「画像がnil(ない)なので、画像のURLが作れないよ」と言ってる。

![スクリーンショット 2020-08-23 午前0.02.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/6bc1ec2c-07c8-28a0-bbb5-dad8463b8ed0.png)
確かに指摘されたとおり、データベースには画像なしの投稿が複数保存されている。

どうやらこれが原因らしい。

## 該当のソースコード

##### posts_controller.rb
```ruby:posts_controller.rb
  def image
    @posts = Post.where(user_id: current_user.id)
  end

  private
  def post_params
    params.require(:post).permit(:food, :calorie, :protein, :fat, :carbo, :text, :image, :weight).merge(user_id: current_user.id)
  end
```
##### image.html.haml
```ruby:image.html.haml
.content
  .images
  - @posts.each do |post|
    = image_tag post.image.url, class: "my-images"
```

## 解決法
画像ありのpostだけ取得する。

##### posts_controller.rb
```ruby:posts_controller.rb
  def image
    @posts = Post.where(user_id: current_user.id).where.not(image: nil)
  end
```
これでimageカラムがnilのpostは取ってこないように指定したら解決した。

## できあがった画像一覧ページ
![スクリーンショット 2020-08-23 午前0.09.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547640/3e91d6e5-5ac6-da99-7309-a2e87db127b6.png)


参考記事：[[Rails]Where句にNOT NULLを指定する](https://qiita.com/kazasiki/items/8b5be52da6162b34b2b7)
SSHクライアントは必要か？

#はじめに
AWSの学習をしていて、際疑問に思ったことを書きます。

## SSHでの接続
サーバーにインストールしたソフトウェアの操作には、**SSH**という仕組みを使ってリモート接続し、操作するのが通例だそうです。

参考書では、サーバー側でSSHを使用するためのプログラムであるデーモン※を動かし、クライアント側には、操作するためのソフトウェアをインストールする必要がある(PuttyやTera Termなど)と述べていましたが、
実際のところAWSを利用してアプリのデプロイ作業をしていて、ソフトウェアをインストールした覚えがありません。

そこでSSHクライアントについて調べてみたら、結論としてMacもWindowsもそれぞれソフトウェアをインストールする必要性は必須ではないことがわかりました。

その理由については以下の通りです。

**●Macの場合**
Mac OSでは初期状態としてターミナルがインストールされていて、ターミナルからSSHコマンドの利用ができるので、ソフトウェアを入れる必要がありません。

**●Windowsの場合**
Windows10 バージョン1803からは、SSHクライアントが組み込まれているので、特にシステム上で設定をする必要もなくSSHコマンドが使えるようになっています。
［Windowsの設定］-［アプリ]-[オプション機能］で入ると、OpenSSH クライアントがインストールされていることが確認できます。

現時点では、ここまでの理解ですが、ソフトウェアを入れることでプラスとなる点が何かしらあるはずなので、追々調べてみようと思います。


**※デーモンとは**
「デーモン（Daemon）」は、設定しておくと、アプリケーションを起動するときに、バックグラウンドでアプリケーションサーバを常時起動させておくことができます。
例として、railsでの開発環境でrails s -b 0.0.0.0で起動する場合、Ctrl＋Cなどを行わないとターミナル上で別の作業ができません。
そのため、アプリケーション起動のコマンドが入力されたときに、アプリケーションサーバ(pumaなど)がデーモンとしてバックグラウンドで常時起動するように設定します。
プライベートクラウドの種類について

プライベートクラウドは最近では以下の２種類に分類される。

① **オンプレミスプライベートクラウド**

② **ホステッドプライベートクラウド**


#オンプレミスプライベートクラウドとは

- ユーザー企業自ら、クラウド基盤ソフトウェアなどを利用し、サーバーやストレージなどのハードウェアリソースを自社で購入して企業内に設置し、`自社専用のクラウド環境を構築・運用する形態`のこと。

- 自社の独自のセキュリティポリシーで強固なセキュリティ環境を構築・運用できる。


#ホステッドプライベートクラウドとは

- `クラウド事業者がユーザー企業ごとの専用のクラウド環境を用意し、サーバーやストレージなどのリソースをサービスとして提供する形態`のこと。

- 短納期で専用のクラウド環境を構築し、月額費用で利用できる。

- 専用線やVPN網を通じて利用するセキュリティレベルの高い専用のクラウド環境で、ユーザー企業ごとのシステムのカスタマイズにも柔軟に対応できる。
たった3行でVSCode(codeserver)をGoogle Colabで使う方法

## packageをインストール
```zsh
!pip install colabcode
```

GitHub
https://github.com/abhishekkrthakur/colabcode/

## colabcodeを起動
```py
from colabcode import ColabCode
ColabCode(port=10000)
```

上記を実行すると、ngrokのリンクがJupyte Notebookに表示されるので、そのリンクをクリックするとVSCode（codesever）が表示されます。

## python
![Screen Shot 2020-09-11 at 10.42.54 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24723/c35df081-60c1-b56c-3aa1-9e544c10a514.png)

あとはターミナルを開いて、普通に`python test.py`で実行できます。
ちなみに、エディタのサイドバーのGearアイコンをクリックするとテーマが簡単に変更できます。

![Screen Shot 2020-09-11 at 10.48.15 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24723/31f7bb3a-952e-297f-2caa-16ee11ee7bf2.png)

## nodejs
nodejsも使えます。インストールされているのは、v8.11.3と古いですが、普通に動きました。
![Screen Shot 2020-09-11 at 10.55.29 AM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24723/0eb4283e-ca15-0b68-2530-11818eb54396.png)
オフライン環境構築 Vagrant編

[オフライン環境構築 目次へ](https://qiita.com/kannkyo/items/1e5f8362ed591ebda33d)

# 概要
オフラインでvagrantを使いたい人のための手順。

# 動作確認の前提条件

動作確認した環境の条件を以下に示す。

- host os: Ubuntu 18.04.5 LTS
- vagrant: 2.2.10
- vagrant-vbguest: 0.24.0
- virtualbox: 6.1.12 r139181

# インストール

## vagrant

[Vagrant公式ダウンロードサイト](https://www.vagrantup.com/downloads)からdebをダウンロードしてインストール。

## vagrant-disksize

[vagrant-disksize](https://github.com/sprotheroe/vagrant-disksize)は、ディスクサイズを拡張するためのプラグイン。

オンラインで以下のコマンドを実行して、gemファイルをダウンロードする。

```bash
wget https://rubygems.org/downloads/vagrant-disksize-0.1.3.gem
```

オフラインで以下のコマンドを実行して、プラグインをインストールする。

```shell
vagrant plugin install vagrant-disksize-0.1.3.gem
```

## vagrant-vbguest

[vagrant-vbguest](https://github.com/dotless-de/vagrant-vbguest)は、`vagrant up`実行時にvirtualboxの仮想サーバにVirtualBox Guest Additionsを自動的にインストールするプラグイン。

オンラインで以下のコマンドを実行して、gemファイルをダウンロードする。

```shell
wget https://rubygems.org/downloads/vagrant-vbguest-0.24.0.gem
```

オフラインで以下のコマンドを実行して、プラグインをインストールする。

```shell
vagrant plugin install vagrant-vbguest-0.24.0.gem
```

参考：https://qiita.com/ozawan/items/9751dcfd9bd4c470cd82

## virtualbox

[Virtualbox公式ダウンロードサイト](https://www.virtualbox.org/wiki/Linux_Downloads)からdebをダウンロードしてインストール。

# 使い方

## vagrantの使い方

[Vagrantコマンドのチートシート](https://qiita.com/0ta2/items/69c2378600bf8adaac5c) を読むべし。

## boxの取得方法

オンライン端末でboxをダウンロードし、オンライン環境でboxをロードする方法を以下に示す。

### boxダウンロード

まず、オンライン端末で以下のスクリプトを実行し、boxをダウンロードする。

```shell:obget.sh
box=$1
username=`echo $box | cut -d "/" -f 1`
name=`echo $box | cut -d "/" -f 2`
version=$2
provider=$3

curl "https://app.vagrantup.com/api/v1/box/$username/$name/version/$version/provider/$provider" | jq ".download_url" | xargs wget -O $username-$name-$version-$provider.box
```

このスクリプトは3つの引数を有する。

**引数**

- $1:box名(例:centos/8)
- $2:バージョン名(例:1905.1)
- $3:プロバイダ名(例:virtualbox)

このスクリプトの実行例を以下に示す。

```shell:実行例
./obget.sh centos/8 1905.1 virtualbox
```

### boxロード

次に、オフライン端末で以下のスクリプトを実行し、ダウンロードしたboxをロードする。

```shell:obload.sh
box_file_path=$1
box_file_name=`basename $box_file_path`
username=`echo ${box_file_name%.*} | cut -d "-" -f 1`
name=`echo ${box_file_name%.*} | cut -d "-" -f 2`
version=`echo ${box_file_name%.*} | cut -d "-" -f 3`
provider=`echo ${box_file_name%.*} | cut -d "-" -f 4`

metadata=$(cat << EOS
{
    "name": "$username/$name",
    "versions": [{
        "version": "$version",
        "providers": [{
            "name": "virtualbox",
            "url": "$box_file_path"
        }]
    }]
}
EOS
)

echo $metadata | jq
echo $metadata > .metadata.json

echo vagrant box add .metadata.json
     vagrant box add .metadata.json
```

このスクリプトは1つの引数を有する。

**引数**

- $1:boxファイル名(例:centos-8-1905.1-virtualbox.box)

このスクリプトの実行例を以下に示す。

```shell:実行例
./obload.sh centos-8-1905.1-virtualbox.box
```
フローの参照項目入力用コンポーネントを使ってみた

フローの参照項目入力用コンポーネント「ルックアップ」の存在を知ったので、使い方をまとめてみました。
# 使い方
まずは新規フローの作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/1b121a8b-9cfd-6479-d77c-0925c5294215.png)

入力画面を作るので、画面フローを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/8b9df3ad-22b5-fbc3-1f89-02465ce5c6d6.png)

画面要素を右にドラッグ＆ドロップ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/4cbc6107-90c1-a296-d5ef-1b48ad3e9c1f.png)

左の列から「ルックアップ」を探して、真ん中にドラッグ＆ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/9aba2ee7-8d86-b0de-24f5-900c5dcf13ed.png)

右に何やらいろいろ設定項目が出てきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/42e03a44-8154-0009-eac4-55e9c19400e5.png)
ここで検索したいオブジェクトを指定するのですが、実は**検索したいオブジェクトをそのまま指定できるわけではありません。**
どうやるかというと、**特定のオブジェクトとその中の参照項目を指定します。**
具体的な設定項目の入れ方は以下の通りです。

| 項目 | 設定内容 |
|:--|:--|
| API 参照名  |  このルックアップコンポーネントの名前。「LookupProduct2」などなんでもOKです。 |
| オブジェクト API 参照名  |  検索したいオブジェクトへの参照項目が存在するオブジェクトのAPI参照名（ややこしい）を指定します。<br>例えば商談商品の商品項目を検索する場合は、商談商品のAPI参照名「OpportunityLineItem」を入力します。 |
| 項目 API 参照名  |  オブジェクトAPI参照名で指定したオブジェクトの参照項目のAPI参照名（ややこしい）を指定します。<br>例えば商談商品の商品項目を検索する場合は、商談商品の項目の１つである「商品」のAPI参照名「Product2Id」を入力します。 |
| 表示ラベル  |入力項目の上の<br>![スクリーンショット 2020-09-11 222903.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/ae33fff8-84a4-aabb-07a5-2ccba6b9c2d4.png)<br>ここに表示する文を入れます。  |
| レコード ID  | デフォルトで何らかのレコードが選択されているようにしたい場合に、そのレコードのIdを入れます。  |
|  必須 | {!$GlobalConstant.True}を入れるとこの項目が入力必須になります。  |

例えばこんな感じに入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/5c2cc209-42c1-23fc-ddaa-f36886e7eb2a.png)
あとは同じ画面要素にほかの入力項目を置いたり、画面要素で入力した値をレコード作成に使用したりします。
# 使用例
このルックアップコンポーネントを使って、商談商品を複数月分一括登録する「定期注文」というフローを作ってみました。
商談レコードから押せるボタンにしてあります。
![スクリーンショット 2020-09-11 230712.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/21207ab6-e3c3-d3ef-0255-51b08c2f7276.png)
ボタンを押すと、商品を入れる参照項目のほか、数量・初回注文日・月数を入力する画面が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/901caae9-f88e-f58f-7f74-76104092f634.png)
入力して次へ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/070acec0-6406-69cc-7fdc-d36a4dba956e.png)
12ヶ月分の商談商品レコードが作成できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/cb050217-cd06-fafb-4e1c-3a36f8a854d2.png)
ちなみにフローの全体像はこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/707557/2e56a6ed-b4a1-d25b-9570-9d47511dcde8.png)
# まとめ
以上フローのルックアップコンポーネントの使い方でした。
ルックアップコンポーネントは設定項目がやや難しいですが、参照項目の入力画面を比較的手軽に作成できるので、ぜひ使ってみてください。
## 参考記事
フローでルックアップ機能を使う
https://note.com/relaxedly/n/na29222ac8a19
フローでのレコード検索時のユーザ支援
https://releasenotes.docs.salesforce.com/ja-jp/winter20/release-notes/rn_forcecom_flow_fbuilder_lookup.htm
フロー画面入力コンポーネント: ルックアップ
https://help.salesforce.com/articleView?id=flow_ref_elements_screencmp_lookup.htm&type=5
テーブルにカラムを追加する方法

【概要】
----------------------------------------
<b>1.結論</b>

<b>2.どのように使うのか</b>

<b>3.ここから学んだこと</b>



1.結論
----------------------------------------
<b>rails g migration Addカラムの名前（大文字から）To追加のテーブル名（大文字から）追加するカラム名:型</b>です！<br>
2.どのように使うのか
----------------------------------------
具体例としては
```terminal:ターミナル
rails g migration AddNamesToAddresses number:integer prefecture:string 　 
```
ということです！

```ruby:db/migrate/20*******_add_names_to_addresses.rb
class AddNamesToAddresses < ActiveRecord::Migration[6.0]
  def change
    add_column :addresses, :number, :integer
    add_column :addresses, :prefecture, :string
  end
end
```
上記のようにファイルが作られます！
必ずこのAddをする前に、rails db:rollbackをしましょう！そうしないとupした状態でDBを変更してしまうと齟齬が生じてしまいrails db:migrateできません！

<br>

3.ここから学んだこと
----------------------------------------
カラム名やテーブル名の頭文字を大文字で書いていなかったので反映されなかった覚えがあります。大文字で書かないといけない時やクラス名はキャメルケースや、変数はスネークネームなどあるので混合しないように気をつけます。
<br>
Firefox上apex:actionFuncionを呼出時の注意事項

#### 業務上に実現したいことは以下となります。
---------------
一覧にファイルリストがあって、行毎にダウンロードボタンがあります。
そのボタンをボタンを押下したら、あるオブジェクトの更新を行い、更新完了したら、ファイルをダウンロードする
上記の処理は非同期で行うことです。

#### 以下の実装だと、chrome上に問題なく処理されます。
①オブジェクトが正しく更新されます。
②サーバ側の処理が処理完了したら、画面の非同期更新エリアがリフレッシュされます。
③ファイルが正しくダウンロードされます。
Firefox上③のみ有効、①②が効かない。

```ファイルダウンロード1.v
<a onclick="fileDownload(id)" />
<apex:actionFunction name="testAction" action="testAction" reRender="testArea">
    <apex:param name="testId" assignTo="{!testId}" />
</apex:actionFunction>

<script>
function fileDownload(id) {
    // 他の業務処理を行う
    testAction(id);
    loaction.href="ファイルパス" + id;
}
</script>
```
#### 以下のように変更すると、Firefox上に①②も効かないが、ボタンを連続的に押下する場合、①が効きます。
```ファイルダウンロード2.v
<a onclick="fileDownload(id)" />
<apex:actionFunction name="testAction" action="testAction" reRender="testArea">
    <apex:param name="testId" assignTo="{!testId}" />
</apex:actionFunction>

<script>
function fileDownload(id) {
    // 他の業務処理を行う
    Function('return this')()['testAction'](id);
    loaction.href="ファイルパス" + id;
}
</script>
```
#### 以下のように変更すると、ChromeもFirefoxも①②③正しく処理されます。
```ファイルダウンロード3.v
<a onclick="fileDownload(id)" />
<apex:actionFunction name="testAction" action="testAction" oncomplete="doDownload()" reRender="testArea">
    <apex:param name="testId" assignTo="{!testId}" />
</apex:actionFunction>

<script>
var testId = null;
function fileDownload(id) {
    // 他の業務処理を行う
    Function('return this')()['testAction'](id);
    testId = id;
}
function doDownload() {
    loaction.href="ファイルパス" + testId;
}
</script>
```
## まとめ（原因分析）
１、Salesforce非同期処理（apex:actionFunction）のName属性は通常意味のJSの関数だと理解していますので、
JSから直接呼出して問題がないかと思います。おそらくChrome上もその通りに解析されるから、問題なく処理される。
だがFirefox上にJS関数を経由し、Salesforce非同期処理（apex:actionFunction）を直接呼出すのは効かない。
原因がわからないが、Functionを利用してラッピングしたら、問題なく利用されます。
２、Firefox上に「loaction.href」を利用すると、「redirect」が変わってしまうから、非同期処理完了後の画面リフレッシュが効かなくなるかと思います。なので、ダウロード処理はoncompleteに移動すれば解決します。
※上記の分析は自分の考えだけですが、全部正しいわけではないが、上記のようにやっておけば、問題が解決できます！
もし本当の原因がわかる方はいらっしゃいましたら、是非教えて頂きたいです。
可読性・テスタビリティ・拡張性を高くif文を書く書き方


先日、ペアプロしている際に、if文を書く位置をどうするかに、そこにif文を書くのではなく、別の書き方をしたほうが可読性が高いよという話をしていたので、if文を書く位置について普段考えていることをまとめます。
まず、自分が考えているのは、基本的に以下の2点です。reactで具体例を書いていきます。

- 可読性・テスタビリティ高くため、if文によって処理が分岐する箇所を最低限の場所になるようにする
- if文の中に処理は基本的に書かずに、分岐後の処理の詳細はメソッドに切り出す

## if文の場所が複数箇所にあり、可読性が低いbad例

```tsx
export const Bad: React.FC<{ isAdmin: boolean }> = ({ isAdmin }) => {
  return (
    <div>
      {isAdmin && <p>adminにはこれを見せるよ</p>}
      {!isAdmin && <p>userにはこっち見せるよ</p>}
      <p>両方に見せるよ</p>
      {isAdmin && <p>adminだけこの情報も見せるよ</p>}
    </div>
  )
}
```

- adminなのか、userなのかロールによる条件分岐をずっと気にしなければ、ならないため可読性が低い

## if文がまとまっており、可読性が高いbetter例
こちらの例ではadminなのか、userなのかロールによる条件分岐を気にするタイミングが、最初だけであるため、気にするタイミングが少なく可読性が高いです。

```tsx
export const Better: React.FC<{ isAdmin: boolean }> = ({ isAdmin }) => {
  if (isAdmin) {
    return (
      <>
        <p>adminにはこれを見せるよ</p>
        <p>両方に見せるよ</p>
        <p>adminだけこの情報も見せるよ</p>
      </>
    )
  }
  return (
    <>
      <p>userにはこっち見せるよ</p>
      <p>両方に見せるよ</p>
    </>
  )
}

```

## 出し分けロジック、表示内容の詳細で責務が別れており、拡張性が高いgood例
better例と基本的には同じですが、別コンポネに表示内容の詳細は切り出すことで、拡張性が高くなります。
また、`AdminComponent`単体でテストをしたり、`storybook`を作ったりしやすくもなります。

```tsx
const AdminComponent = () => {
  return (
    <>
      <p>adminにはこれを見せるよ</p>
      <p>両方に見せるよ</p>
      <p>adminだけこの情報も見せるよ</p>
    </>
  )
}

const UserComponent = () => {
  return (
    <>
      <p>userにはこっち見せるよ</p>
      <p>両方に見せるよ</p>
    </>
  )
}

export const Good: React.FC<{ isAdmin: boolean }> = ({ isAdmin }) => {
  if (isAdmin) {
    return <AdminComponent />
  }
  return <UserComponent />
}
```

- Goodコンポーネントが持つ責務が、出し分けだけになるため、表示の複雑度が上がった際に対応しやすく、各種表示のロジックの詳細を別コンポーネントに分離することができる


## if文が一箇所にまとまるため、テストがしやすい
bad例でのtestを書くと例えばこのようになり、「adminにはこれを見せるよ」と「adminだけこの情報も見せるよ」の2つが表示されており、「userにはこっち見せるよ」が表示されてないことをテストする必要があります。

```tsx
  it('Bad admin', () => {
    const { container, asFragment } = render(<Bad isAdmin />)
    expect(container.textContent).toContain('adminにはこれを見せるよ')
    expect(container.textContent).toContain('adminだけこの情報も見せるよ')
    expect(container.textContent).not.toContain('userにはこっち見せるよ')
    expect(asFragment()).toMatchSnapshot()
  })
```


betterでのtestでは、「adminにはこれを見せるよ」が表示されており、「userにはこっち見せるよ」が表示されていないことをテストできれば、表示の切り分けが十分にテストできてるので、テストが簡単になります。
goodのコンポーネントも分けた状態も同様です。
また、場合によっては、good例の場合は、個別のコンポネはshallow mount(この例では、react testing libraryを使用してるためshallow mountはありませんが)したり、mockしたほうがテストは簡単にかけるかもしれません。

```tsx
  it('Better admin', () => {
    const { container, asFragment } = render(<Better isAdmin />)
    expect(container.textContent).toContain('adminにはこれを見せるよ')
    expect(container.textContent).not.toContain('userにはこっち見せるよ')
    expect(asFragment()).toMatchSnapshot()
  })
```


今回は、reactを例に書いていますが、vueはもちろん、サーバーサイドの処理でも同様の考え方でif文の処理が分岐していくようにすると可読性が高く・テスタブルな処理がかけます。
条件分岐が複雑になりそうな処理を書く際は、この2つを意識してみてください。
- 可読性・テスタビリティ高くため、if文によって処理が分岐する箇所を最低限の場所になるようにする
- if文の中に処理は基本的に書かずに、分岐後の処理の詳細はメソッドに切り出す


また、例に使用しているコードの全体はこちらにも上げています。
https://github.com/YasushiKobayashi/samples/blob/master/src/react-if-sample/src/Main.spec.tsx
https://github.com/YasushiKobayashi/samples/blob/master/src/react-if-sample/src/Main.tsx
PHP 、Laravel学習　１

これから学習したことをQiitaに投稿していきます。

非常に中途半端なところからのスタートになりますがご容赦下さい。

●Laravel学習

・MVCモデル
①ブラウザから送られてきた指令（リクエスト）をまずroutingが受け取る
②routingがどこにその指令を飛ばすべきかリクエストの種類を判別する
③controllerで受けとった場合、然るべきアクションを行う
④viewで受けとった場合そのままviewを返す（レスポンス）
⑤ブラウザに反映される

※多様なパターンがあり、一概に↑の順とは限らない

routing・・・リクエストを判別し、然るべき場所に信号を送る
controller・・・routingから送られてきたリクエストに大して然るべきアクションをする
view・・・表示するべきUI部分。
Model・・・データベースの前に立ち、操作しやすくするもの（？）

Model、view、controller
３つの要素の頭文字をとってMVCモデル

・データベース基礎
情報を保存しておくところ
Ex.ユーザーの名前、年齢、性別等

まず、データベースを操作する言語（データベース言語）について触れておきます
SQLといい、何種類かある
①MySQL
②PostgreSQL
③SQLite
存在するデータベースにより、どの言語が使われているかは異なるが
LaravelのModelはそれを全て統一して管理してくれるという便利機能付き

この言語を使い、データベースの雛形を作ったり、データを入力したりする

・CRUD処理

①Create・・・作成（タスクを作成したり、ツイートを作成したり）
②Read・・・読み込み（作成したタスクを読み込んだり、ツイートを読み込んだり）
③Update・・・更新（タスクを編集したり、追加する）
④Delete・・・削除（一度作ったデータを削除する）

WebアプリケーションではこのCRUD処理が必要不可欠である。

次回は実際に作りながら学んでいきたい