OmniAICreator/Qiita-1.07M huggingface dataset:
Vagrant で public_networkの 接続するbridged network名を指定する

Windows環境で 有効な bridge adapterが複数ある場合、
どのadapterに接続するのかを 予め Vagrantfileで指定しておく方法

自前調査の結果なので、もっと楽な方法あれば教えてくださいm(_ _)m

## Bridged Networkへの接続

例えば接続する adapterが "Realtek PCIe GbE Family Controller" なら以下のようにVagrantのconfigに追記すれば良い

```text:Vagrantfile
...
  config.vm.network "public_network", bridge: "Realtek PCIe GbE Family Controller"
...
```

で、この adapterの文字列って何を指定すれば？

## adapter名の取得

`vboxmanage list bridgedifs`で一覧表示可能なので、そこのNameから持ってくる

```console
C:\Users\user>vboxmanage list bridgedifs
Name:            Realtek PCIe GbE Family Controller
GUID:            ...
```

## 蛇足

最初、vboxmanage listでとれば良いという事に気が付かず色々調べてしまったので その残骸。

Bridgedネットワークで出てくるアダプタは netshを使ってインターフェースを一覧したときに
Admin Stateが有効 な状態の物が対象っぽい(VirtualBox関係は除く)

```console
C:\Users\user>netsh interface show interface

Admin State    State          Type             Interface Name
-------------------------------------------------------------------------
有効             接続             専用               イーサネット
有効             接続             専用               VirtualBox Host-Only Network
有効             接続             専用               Npcap Loopback Adapter
有効             切断             専用               Wi-Fi
```

ここで出てくる Interface Nameは変更可能な名前なので残念ながら違う。

GUIからはネットワーク接続のプロパティで「接続の方法：」というところに表示されている文字列？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/05e7a3e2-5c97-1a89-11d8-090680f18965.png)

Registryの中で以下のキー以下にNetwork Interfaceが列挙されているので その中では DriverDescじゃないかと。
`HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128512/0903ba21-43e8-d0a1-ff5f-284e981ee584.png)

WMI使って NIC一覧のQueryを投げる方法がわりと楽で、そのNameを使えば良い
`wmic nic where "(NetConnectionStatus > 0)" get Name,NetConnectionStatus`

```console
C:\Users\yasuo\work\centos>wmic nic where "(NetConnectionStatus > 0)" get Name,NetConnectionStatus
Name                                            NetConnectionStatus
Realtek PCIe GbE Family Controller              2
Realtek 8821CE Wireless LAN 802.11ac PCI-E NIC  7
Bluetooth Device (Personal Area Network)        7
VirtualBox Host-Only Ethernet Adapter           2
Npcap Loopback Adapter                          2
```
MATLABを使っている人がPythonを使うときの注意点

#MATLABを使っている人がPythonを使うときの注意点

仕事で使用しているMATLABとPythonの注意点が書かれたサイトがあったので、備忘録として残しておきます。

###・MATLAB に慣れた人が Python を始めるときの１１の注意点
https://datachemeng.com/matlab_to_python/
# Pythonを使い始めてハマったこと

##1."＝"による代入は値のコピーではなく、参照になっている。意図しないデータ変更が行われる可能性あり
##### 対策　値をコピーしたい場合は .copy()を使うようにする。
```python
import numpy as np
# =============================================================================
# b += 5 -> 元のaも変化する。
# =============================================================================
a = np.array([1,2,3])
print('a = ')
print(a)
print('\n')

b = a

b += 5  #元のaも変化する。
print('b = a , b += 5 を実行後')
print('a = ')
print(a)
print('b = ')
print(b)
print('\n')

# =============================================================================
# 'b = a , b = b + 5 -> 元のaは変化しない。
# =============================================================================
a = np.array([1,2,3])
b = a

b = b + 5 #元のaは変化しない。
print('b = a ,b = b + 5 を実行語')
print('a = ')
print(a)
print('b = ')
print(b)
print('\n')

# =============================================================================
# 'b = a , b[0] = 100 ->元のaも変化する。
# =============================================================================
a = np.array([1,2,3])
b = a

b[0] = 100
print('b = a ,b[0] = 100 を実行後')
print('a = ')
print(a)
print('b = ')
print(b)
print('\n')

# =============================================================================
# b = a.copy() b[0] = 100 ->元のaは変化しない。
# =============================================================================
a = np.array([1,2,3])
b = a.copy()

b[0] = 100
print('b = a.copy(),b[0] = 100 を実行後')
print('a = ')
print(a)
print('b = ')
print(b)
print('\n')
```
```output
a = 
[1 2 3]


b = a , b += 5 を実行後
a = 
[6 7 8]
b = 
[6 7 8]


b = a ,b = b + 5 を実行語
a = 
[1 2 3]
b = 
[6 7 8]


b = a ,b[0] = 100 を実行後
a = 
[100   2   3]
b = 
[100   2   3]


b = a.copy(),b[0] = 100 を実行後
a = 
[1 2 3]
b = 
[100   2   3]
```

##2.配列の型変換が自動で行われない。(配列要素に対して演算を行う場合のみ）
##### 対策　array作成時に整数でセットせず、少数で指定する。またはdtype = floatで型指定する。
##### どちらにしても型への注意は必須。
Reactで作るandroidアプリ

## 作ったもの
![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263384/b8fd5bd5-6104-240b-a4cb-46506746808e.gif)


## Ionic reactでアプリを作成
[ionic](https://ionicframework.com/)を使ったandroidアプリ開発に、Reactが使えると知ったので試してみた。
Reactでどのようにアプリを作っていくのかが知りたかったので、今回は[サンプル](https://ionicframework.com/docs/react/quickstart)をエミュレーターで動かすことを目標にした。


```
$ npm install -g @ionic/cli
$ ionic start myApp sidemenu --type=react
$ cd ./myApp/
$ ionic serve
```

以下のような画面が表示できれば成功

![Screenshot from 2020-06-17 19-13-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263384/a4ca0cf7-e8ef-f81f-1585-32b45859286d.png)


## android stidio
次に、先ほど作ったアプリをandroidエミュレーターで動かすために準備をする。

[ここ](https://developer.android.com/studio)からandroid studioをダウンロードする。

ダウンロードできたら[ユーザーガイド](https://developer.android.com/studio/install)に従い、インストールを進める

まず、依存ライブラリをインストール

```
$  sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386
```

次に、先ほどダウンロードしたものを展開し、起動

```
$ sudo mv ~/Downloads/android-studio-ide-193.6626763-linux/android-studio/ /usr/local/
$ cd /usr/local/android-studio/bin
$ ./studio.sh
```


### 環境変数の設定
以下の環境変数を ```.bashrc```に追記する。

```
$ export ANDROID_SDK_ROOT=$HOME/Android/sdk
$ export PATH=$PATH:$ANDROID_SDK_ROOT/tools/bin
$ export PATH=$PATH:$ANDROID_SDK_ROOT/build-tools
$ export PATH=$PATH:$ANDROID_SDK_ROOT/platform-tools
$ export PATH=$PATH:$ANDROID_SDK_ROOT/emulator
```

### Android エミュレーターのセットアップ
エミュレーターを使うために、まずはKVMのインストール。
ターミナルに、以下のコマンドをうち、エミュレーターが使えるか確認（出力が0でなければ、エミュレーターを使うことができる）

```
$ egrep -c '(vmx|svm)' /proc/cpuinfo
```

エミュレーターを使えることが確認できたらkvmとついでに実機でデバックするためのadbをインストール。

```
$ sudo apt -y install qemu-kvm adb
$ sudo gpasswd -a "${USER}" kvm
```
設定を反映するため、再起動を行う。

```
$ sudo shutdown -r now
```

### ionicアプリのビルド

```
$ cd myapp/
$ ionic build
```

android向けにビルド。

```
$ ionic cap add android
```

android studioでビルドしたプロジェクトを開く。

```
$ ionic cap open android
```


## 参考
- [Intro Ionic React Quickstart](https://ionicframework.com/docs/react/quickstart)
- [Android Development](https://ionicframework.com/docs/developing/android)
- [Ionic5+AngularJSでスマホアプリ開発 【Androidアプリビルド環境構築編】](https://satolabo.net/2020/04/19/ionic5-android-build-setup/)
- [Ionic5+AngularJSでスマホアプリ開発 【Android Studioでエミュレート編】](https://satolabo.net/2020/04/21/ionic5-capacitor-android-emulate/)
jar_アーカイブの操作_メモ_20200811

#jar-アーカイブの操作

**事前基礎知識**

　　　　・アーカイブとは

　　　　　　複数のファイルやフォルダを一つのファイルにまとめたもの



**１．jarコマンドとは**

　　Windowsの実行プログラムは、通常はexeの拡張子を持った単一のファイルです。
　　一方、Javaで開発された実行可能プログラムの姿は、複数のクラスファイル(.class)の集合です。

　　このように「複数のクラスファイルの集合」という形式では、
　　別の開発者に渡すときにファイルの受け渡し漏れなどの事故が発生する可能性もあります。
　　筆者も開発現場で実際に細かくクラスファイルを分けてもらってということもありました。

　　そこで、それらのファイル一式を1つにまとめるアーカイブ形式(事前基礎知識を参照)として、
　　**JAR(Java Archive)**が定められています。

　　JDKに標準添付されているjarコマンドを使えば、複数のクラスファイルやプロパティファイルなどを
　　まとめて1つのJARファイルにしたり、逆にJARファイルの中身をもとのクラスファイルなどに展開したり
　　できます。(図１)


**図１**
![コメント 2020-08-11 114326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/687164/08e8ef32-b47b-35d4-2c7d-5a5ac4fcd1c4.png)



**１．jarコマンドの基本的な使い方**

　　jarコマンドで通常行うのは
　　「アーカイブの作成」「アーカイブの展開」「アーカイブ内容の閲覧」です。
　　それぞれ下記のコマンドで実行します


　　**・アーカイブの作成**

　　　　　>jar -cvf JARファイル名　ファイルおよびフォルダ・・・

　　**・アーカイブの展開**
　　　　
　　　　>jar -xvf JARファイル名

  　　**・アーカイブ内容の閲覧**

　　　　>jar -tvf JARファイル名


　　たとえば、Test1.classとTest2.classをまとめてTest.jarを作りたい場合、次のようなコマンドを実行します。

　　>jar -cvf Test.jar Test1.class Test2.class


**２．マニフェストファイル**

　　zipやlhaといったアーカイブ形式の圧縮ファイルを使ったことがある人はもちろんいるでしょう。
　　実はJAR形式はzip形式とほとんど同じようなものです。
　　(JARファイルの拡張子をzipに書き換えると、zipファイルを展開するソフトで問題なく展開することができます)

　　ただしJARファイルには、アーカイブ内に含まれる様々なファイルに関する追加情報を記述した
　　**マニフェストファイル**を含めることが一般的です。

　　マニフェストはテキストファイル形式であり、アーカイブ内のMETA-INFフォルダ中の
　　MANIFEST.MFという名前で格納する決まりになっています。


**３．JARファイル利用のメリット**

　　・ファイル領域の効率の良さ 

　　　　圧縮すれば必要なファイル領域が減って効率が上がる

　　・セキュリティ
 
　　　　JARファイルは署名を施すことができるため、セキュリティ上の制限がある程度まで和らげることができる 


間違っている知識などございましたら、ご教示いただけると幸いです。
初心者がSTMに慣れる方法

##1　はじめに　
　プログラムに慣れるには、Web上からサンプルプログラムを拾ってきて実行し、変更していく事だと思います。STM32では、Mbed( https://os.mbed.com/ )を利用すると使いやすいようです。理由は、サンプルプログラムが古く、mbedOS2を利用しているパターンが多いためです。最近のMbedの開発環境は、Mbed Studioを使ったりしますが、Mbed OS5, 6であり、OS2から移植する作業が必要になります。サンプルを見ながら、学習するという立場を取るなら、本記載内容がお薦めです。このサイトに入って、右上のCompilerをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/d97e074b-e9d2-a982-a5ae-e41fec118131.png)


##2　サンプルプログラムのコンパイル
　上記を実行すると、以下の画面が出力されます。次の順でサンプルプログラムをダウンロードします。
1. デバイスの選択（本事例ではSTM32F746 Discovery）　①
2. サンプルのキーワードを入力　②
3. サンプルの選択　③
4. インポート実行　④
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/94520ec5-2a7d-fa77-0306-64033c88a586.png)
ダウンロードした後は、画面上のコンパイルを実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/b1e9398f-e02f-b6a7-339f-8e30eaa9159b.png)

その後、次のようなファイル（例: F746_AcousticEffector_MIC ）が出力されるので、これをデバイスに書き込みます。（ファイルの保存先をデバイスにする。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/21cd55ef-d4aa-1160-40ee-45c5cdd6e109.png)

デバイスへの書き込みが完了すると、つぎのようにデバイスで表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305726/69eb218d-ceca-99e7-21d3-3dc326c693e9.png)
このサンプルは、CQ出版社のインターフェース2018年12月号に掲載されていたプログラムです。
npm install -g truffle, truffle init が使えない時の解決方法

##npm install -g truffleがインストール出来ずgit initが使えないときの解決方法

ターミナル上のエラーコード

```　
- Fetching solc version list from solc-bin. Attempt #1
+ truffle@5.1.39
updated 1 package in 6.707s 
```

#解決方法
-g　がインストールできるようにPATHを通す必要がある。

```
$ export PATH=$PATH:`npm bin -g`
```

$ truffle version でバージョンが表示されたら完了
位相キックバック

ググっても、位相キックバックをメインで書いてる記事が[某社社長の記事](https://qiita.com/YuichiroMinato/items/462bb42283fc642bea9d)くらいしか出てこなくて腹立つので書く。

<img width="690" alt="file.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88256/3a2af1e0-e358-3dc9-3060-0c58242b9496.jpeg">

$U$をユニタリ行列、あるいはそれを表現した量子ゲートとする。
Controlled-Uゲートを考えると、それはこんな数式になる。

$\mathrm{CU} = \mid 0\rangle\langle 0\mid_{\mathrm{control}} \otimes I_{\mathrm{target}} + \mid 1\rangle\langle 1\mid_{\mathrm{control}} \otimes U_{\mathrm{target}}$

つまり、制御ビットが0だと、標的ビットには何もせず(単位行列をかけて)、制御ビットが1だと、標的ビットにはユニタリ行列Uをかける。

ここで、制御ビットを$\frac{1}{\sqrt 2}(|0> + e^{i\phi}|1>)$、標的ビットを、$U$の(ひとつの)固有ベクトル$|\psi>$であり、対応する固有値を$e^{i\lambda}$とする。つまり、$U|\psi> = e^{i\lambda}|\psi>$を満たすとする。
(なお、$\phi = 0$のとき、制御ビットは$\frac{1}{\sqrt 2}(|0> + |1>)$になって、これは、$|0>$にアダマールゲートをかけた状態である。)

つまり、
$|\Psi> = \frac{1}{\sqrt 2}(|0\rangle + e^{i\phi}|1\rangle )_{\mathrm{control}}\otimes |\psi\rangle _{\mathrm{target}}$を考える。

このとき、

```math
\begin{align}
&\mathrm{CU}\cdot |\Psi>\\
=&(\mid 0\rangle\langle 0\mid_{\mathrm{control}} \otimes I_{\mathrm{target}} + \mid 1\rangle\langle 1\mid_{\mathrm{control}} \otimes U_{\mathrm{target}})\frac{1}{\sqrt 2}(|0\rangle + e^{i\phi}|1\rangle )_{\mathrm{control}}\otimes |\psi\rangle _{\mathrm{target}}\\
=&\frac{1}{\sqrt 2}(|0>_\mathrm{control}\otimes I|\psi>_\mathrm{target} + e^{i\phi}|1>_\mathrm{control}\otimes U|\psi>_\mathrm{target}\\
=&\frac{1}{\sqrt 2}(|0>_\mathrm{control}\otimes |\psi>_\mathrm{target} + e^{i\phi}|1>_\mathrm{control}\otimes e^{i\lambda}|\psi>_\mathrm{target}\\
=&\frac{1}{\sqrt 2}(|0>_\mathrm{control}\otimes |\psi>_\mathrm{target} + e^{i(\phi + \lambda)}|1>_\mathrm{control}\otimes |\psi>_\mathrm{target})\\
=&\frac{1}{\sqrt 2}(|0> + e^{i(\phi + \lambda)}|1>)_\mathrm{control}\otimes |\psi>_\mathrm{target}
\end{align}
```

$|\Psi>$と$\mathrm{CU}\cdot|\Psi>$を見比べると、$|1>$の位相が$\psi$から$\psi + \lambda$に変わっている。この$\lambda$は、$|\psi>$に対応する$U$の固有値であった。

このように、$U$の固有ベクトルに対してControlled-Uゲートをかけると、$U$の固有値を位相として取り出すことができる。
これを位相キックバックといい、このように位相の形で取り出した固有値は量子フーリエ逆変換で取り出すことができる。

位相キックバックを行い、量子フーリエ逆変換で位相を取り出すアルゴリズムは、量子位相推定アルゴリズムとして知られている。
AtCoder Beginner Contest 167 A問題「Registration」解説(Python3,C++,Java)

AtCoder Beginner Contest 167 A問題「Registration」の解説を行います。
>問題URL:
https://atcoder.jp/contests/abc167/tasks/abc167_a

#問題概要
文字列$S$,$T$が与えられる。
$T$が$S$の末尾に1文字追加した文字列であるか判定せよ。

$T$が条件を満たすならば`Yes`
条件を満たさなければ`No`と出力せよ。

##制約
・$S,T$は英小文字列
・$1 \leq |S| \leq 10$
・$|T| = |S| + 1$

#解説
文字列$T$について、$|S|$文字目までの<b>スライス</b>を取得し、それが$S$と等しいかどうかを判定すればよいです。
ここで、<b>スライス</b>とは、文字列の一部のことを指します。

##スライスの取得方法
Python3では `T[i:j+1]`で$T$の$i$文字目から$j$文字目までの<b>スライス</b>を取得することができます。
<font color = "grey">(ここで、0-indexであることに注意して下さい)</font>

###<font color = "blue">[コラム]0-index,1-indexとは？</font>
コンピューター上では、<b>数字のカウンタは1ではなく0から始めます。</b>ですので、私たちが処理する文字列は、私たちにとっては1文字目から数えますが、<b>コンピューターにとっては0文字目なのです。</b>
コンピューター的な配列(文字列含む)の数え方を<b>0-index</b>といいます。
それに対して、私たちが普段している配列の数え方を<b>1-index</b>といいます。
今後も解説でよく使用する言葉ですので覚えておきましょう。

本題に戻ります。
C++では、`T.substr(i,j)`で$T$の$i$番目から$j$文字分の<b>スライス</b>を取得することが出来ます。(iは0-indexです)
Javaでは、`T.substring(i,j+1)`で$T$の$i$番目から$j$番目までの<b>スライス</b>を取得することができます。(i,jは0-indexです)

これらの関数を用いて$T$のスライスを取得し、$S$と同じかどうか判定すれば良いでしょう。

以下、Python3,C++,Javaでの解答例を示します。

#各言語解答例
<details><summary>Python3での解答例</summary><div>

```{ABC167A.py}
S = input()
T = input()
if T[0:len(S)] == S:
  print("Yes")
else:
  print("No")
```

</div></details>

<details><summary>C++での解答例</summary><div>

```{ABC167A.cpp}
#include<bits/stdc++.h>
using namespace std;
int main(){
  string S,T;
  cin >> S >> T;
  string Judge = T.substr(0,S.size());
  if (Judge == S){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
}
```

</div></details>

<details><summary>Javaでの解答例</summary><div>

```{ABC167A.java}
import java.util.Scanner;
public class Main{
  public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    String S = scan.nextLine();
    String T = scan.nextLine();
    String judge = T.substring(0,S.length());
    if (judge == S){
      System.out.println("Yes");
    }else{
      System.out.println("No");
    }
  }
}

```

実は、このコードを実行すると、<font color = "orange">WA</font>になります。(分かる方は)理由は分かりますか？

理由を知りたい方は調べてみて下さい。

正解コードは以下の通りです。

```{ABC167A_AC.java}
import java.util.Scanner;
public class Main{
  public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    String S = scan.next();
    String T = scan.next();
    String judge = T.substring(0,S.length());
    if (S.equals(judge)){
      System.out.println("Yes");
    }else{
      System.out.println("No");
    }
  }
}

```

</div></details>
dockerでcomposer updateしようとしたらメモリ不足。。ターミナルからphp.iniでmemoryの設定変更

# php.iniの場所を確認

```
# php --ini
```

# vimで設定変更

```
# vi /usr/local/etc/php/php.ini
```

### 追記

```
memory_limit = 2047M
```

# 確認

```
# php -r 'phpinfo();' | grep memory_limit
# php -r "echo ini_get('memory_limit').PHP_EOL;"
```
どちらでもお好きな方を。

以上。
Raspberry PI3のWEBサーバ構築 外部公開ができない問題の解決方法

#はじめに
私がRaspberrypi3を使用してWEBサーバ（外部公開）をするまでに陥った問題を共有します。
WEBサーバ公開にはポートの開放が必須ですが、これがうまく行かない問題にハマりました。
本方法より、同様の問題を抱えるユーザが救済されることを願います。

#結論(原因)
- **プロバイダへのネット接続方式がTransix (DS-Lite)方式であった**

#対策
- **RaspberrypiをPPPOE接続した**
 
  ルータはDS-Lite（Transix)を継続。

#手順
0.  Apachを導入し、イントラ内からWEBサイトを確認できる状態（ココからスタート）

1.  プロバイダへの接続状態を確認（ルータの設定画面 192.168.x.1等　にアクセスしチェックした）
　＊私の環境では以下の画面よりtransix接続であることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/2955ad07-dd6b-9fd8-0083-07e7042ab84a.png)


**どうもTransixではポート開放ができないようです。。。。(知らなかった。。。）**
[参照先](https://naruhodo-wifi.com/transix/#:~:text=transix%E3%81%AF%E3%83%9D%E3%83%BC%E3%83%88%E9%96%8B%E6%94%BE%E3%82%92,%E9%96%8B%E6%94%BE%E3%82%92%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%80%82)
ルータの設定をPPPOEに戻しても良いのですが、ネット速度を改善するためにTransix(DS-Lite)に変更したので、
今回は別の方法を模索しました。

3.Raspberry piで直接PPPOE接続、ルータはDS-Liteを継続

今回試みるイメージ図です。ルータの下にホストPCと今回の主役であるRaspberrypiをおいています。
PCはDS-Liteを継続し、RaspberrypiはPPPOE接続します。
これによりRaspberrypiはポートが開放可能となります。

**イメージ図**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/ba90f4ec-1618-4a91-b207-7455b75030cf.png)

##方法

- まず、ルータ側の設定です。
PPPoEパススルー機能をONにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233064/c5bc053b-2151-cdeb-e5e4-a36a12455490.png)


- つぎにRaspberrypi側の設定です。

**[こちらの記事を参考にさせていただきました(リンク）](https://denor.jp/v6%E3%83%97%E3%83%A9%E3%82%B9%E7%92%B0%E5%A2%83%E3%81%8B%E3%82%89raspberry-pi-4%E3%81%A7ipv4-pppoe%E6%8E%A5%E7%B6%9A%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF)**

```
$ sudo apt-get install pppoe pppoeconf
$sudo pppoeconf
```
あとは手順にしたがいプロバイダへの接続ID,PWを設定してください。

- 設定後以下のコマンドを打ち込みます

```terminal
$pon dsl-provider #PPPOE開始
$ip addr show ppp0 #PPPOEステータス表示
```

```output:出力結果
 ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1454 qdisc pfifo_fast state UNKNOWN group default qlen 3
    link/ppp 
    inet XXX.XXX.XXX.XXX peer YYY.YYY.YYY.YYY/YY scope global ppp0
```
のようにppp0のアドレスが確認できればPPPOEの設定完了です。

-　最後にデフォルトの経路設定です
デフォルトの経路を今回設定したPPP0にしないとポート開放がうまくいきません。


まずrouteコマンドでdefaultの経路を確認します。
```
$route
```
デフォルトの経路が有線LANのeth0になっています。

```terminal:出力結果
default         192.168.11.1    0.0.0.0         UG    103    0        0 eth0
XXXXXXXXX.fl    0.0.0.0         255.255.255.200 UH    0      0        0 ppp0
192.168.11.0    0.0.0.0         255.255.255.0   U     402    0        0 eth0
```
これをPPP0に切り替えます。

```
$sudo route del default dev eth0
$sudo route add default dev ppp0
```

以上で切り替えができました。

最後に再度起動して完了です。

```terminal
$sudo poff #PPPOE停止
$sudo pon dsl-provider #PPPOE接続開始
```

これで、ポート開放が有効になる・・・はず。
Slurm Workload ManagerのUbuntu 18.04LTSへの導入

#前書き
これまで数値計算用ワークステーションのジョブスケジューラとしてtorqueを長年使用していましたが、有料になったため、代替案として無料ソフトウェアであるSlurmを導入しました。

SlurmのUbuntu16.04LTSへの導入については、下記の記事
https://qiita.com/JeJeNeNo/items/c545e72373d4d1deb36a
にて丁寧にまとめられており、18.04LTSへのインストールもほぼこの通りで出来ます。
詳細な手順は上の記事を見て頂くとして、一部の変更点をまとめておきます。
1から知りたい方は、まず上の記事を読むことをお勧めします。

#Slurmのインストール
インストールまでは上の記事と同じ手順なので省略します。
Slurmのインストールの前に、Slurmの起動に必要なソフトウェアMUNGEをインストールする必要があり、16.04LTSだと大変だったようです。
嬉しいことに18.04LTSではapt installで問題なくインストールできます。

```
sudo apt install munge
```

Slurmもapt installでインストールできるようですが、後の設定を考え、上の記事と同様にソースコードから最新版をコンパイルしてインストールしました。prefixは設定しなかったので、デフォルト設定の通り、"/usr/local"にインストールされます。

```
./configure
make
sudo make install
```


#Slurmの設定ファイル作成
ここも上の記事の手順とほぼ同じですが、一部変更＆追加。
具体的には、

* hyperthreadingを使う場合でも、"Sockets", "CoresPerSocket", "ThreadsPerCore"の設定が必要
* 追跡をpgidに変更（デフォルト設定はcgroup）

後は上の記事に従って、ポート開放・systemdに設定・起動

#使い方
下記サイトにまとまっています。
https://www.j-focus.jp/user_guide/ug0004000000/
とりあえず覚えておくべきは、
・ジョブ実行

```
sbatch **.sh
```

・ジョブのステータス確認

```
squece
```

・ジョブ強制終了

```
scancel ***
```

で、バッチファイルの書き方は下記のサンプルを自分用に改変すれば動きました。
https://www.j-focus.jp/user_guide/ug0004040000/#ug0004040000

#おわりに
インストール作業や使い方はtorqueより楽だし、無料なので文句を言うのもアレですが、公式サイトのマニュアルが読みにくくて閉口しました…。
EC2上に構築したWebアプリからユーザにメールを送信したいので調査した

<h1>参考にした記事:</h1>
<a href="https://dev.classmethod.jp/articles/re-introduction-2019-amazon-ses/">AWS再入門ブログリレー Amazon SES編 | Developers.IO</a>
<a href="https://www.inomaso.com/post/2020/06/aws-ec2-mail/">[AWS]EC2のメール送信ベストプラクティスをまとめてみた</a>
<a href="https://www.slideshare.net/AmazonWebServicesJapan/aws-30934799">AWSからのメール送信</a>
<a href="https://blog.websandbag.com/entry/2019/07/31/160557">【Amazon SES】SESでメール送信する時に知っておきたい事</a>
<a href="https://qiita.com/shouta-dev/items/a33c55e0df154012c557">AmazonSESから携帯キャリアメールに届く確率を上げる</a>



<h1>AWSからのEメール送信の選択肢</h1>
1. Amazon SESを使う
2. EC2上にMTA(Mail Transfer Agent)を構築する<br>
<a href="https://www.slideshare.net/AmazonWebServicesJapan/aws-30934799">AWSからのメール送信</a>



<h1>システム要件</h1>
・ユーザ登録時にユーザにメールを送り、認証させる。
・パスワード変更時に、パスワード変更用のURLを送る。
・(ポリシーの変更や、新機能追加などのお知らせもできれば送りたい。)
・送ったメールがちゃんと届く
・迷惑フォルダに分類されない
・構築・運用をできるだけ楽にしたい！


<h1>選択肢1:Amazon SES</h1>
<h3>特徴</h3>
EC2からのメール送信は62,000件/月まで無料
BouncesとComplaintsの率によってはSESが停止されてしまう
携帯キャリアドレスへの送信が多いシステムには向かない。

<h3>料金</h3>
EC2からのメール送信は62,000件/月まで無料。
それ以上は1,000件/月ごとに0.10$

<h3>Bouncesとは</h3>
配信を試みて何らかの問題が発生し、送信者に差し戻されたメールのこと
Amazon SESでは「基本的にバウンス率は5%以下に維持してください。」と記載されている。
“苦情については、デフォルトで取得できません。Amazon SNSで通知できるようにモニタリングする事が求められます”
<a href="https://blog.websandbag.com/entry/2019/07/31/160557">【Amazon SES】SESでメール送信する時に知っておきたい事</a>

<h3>Complaintsとは</h3>
Eメールの受信者がメールに対してスパム報告をしたときに記録される
Amazon SESでは「基本的に苦情率は0.1%未満に維持してください。」と記載されている。

<h3>SESを使ったメール送信の手段</h3>
AWSマネジメントコンソールでぽちぽちする
Amazon SES APIをSDKで叩く
SMTPインターフェイスを使う

<h3>SESから携帯キャリアアドレスへの送信</h3>
“携帯キャリアアドレスへの送信が多いシステムの場合、Amazon SESはあまり向いていません。これはドメイン拒否等でバウンスした場合は宛先メールアドレスがSuppression Listに登録され、登録されてからは14日間は自動でバウンスメール扱いとなるからです。このSuppression Listはアカウントを超えて共有され、削除は手動で行う必要があります。”
<a href="https://www.inomaso.com/post/2020/06/aws-ec2-mail/">[AWS]EC2のメール送信ベストプラクティスをまとめてみた</a>

“現状日本国内の携帯キャリアの制限を十分考慮した配信アルゴリズムにはなっていない。”
<a href="https://www.slideshare.net/AmazonWebServicesJapan/aws-30934799">AWSからのメール送信</a> 25ページ

SPFの設定をしたらメール到達率がほぼ100%になったという事例もあり。
“実際、これを設定する前は、auとdocomoのおよそ60%のメールが到達していなかったようなのですが、設定したところほぼ100%到達するようになったようです”
<a href="https://qiita.com/shouta-dev/items/a33c55e0df154012c557">AmazonSESから携帯キャリアメールに届く確率を上げる</a>

<h1>選択肢2: EC2上にMTA(Mail Transfer Agent)を構築する</h1>
<h3>メリット</h3>
・携帯キャリア向けの送信ルールなど、柔軟な制御が可能
・MTAの既存のノウハウを活かした構築・運用が可能

<h3>デメリット</h3>
・構築/運用/障害対策/スケーリングは自分で行わなければならない
・email送信のための制限解除やDNS逆引きなど各種申請が必要になる。

<h3>注意点</h3>
・デフォルトではEC2からアウトバウンドのTCP25番ポートは制限されている
→申請して解除してもらう必要がある。Route53に制限解除と逆引きDNSの登録を申請する。

<h1>まとめ</h1>
Amazon SESを使った場合、ちゃんと携帯キャリアのメールアドレスにも届くかや、Complaints率が不確実。一方、EC2上にMTA構築は、構築コストと運用コスト高そう。どのくらいのコストなのかに関しては、私の知識レベルにもよるので、やってみないとわからない。みなさんはどうしてるんだろう？
.NET DataGridViewのデータソースに列を挿入するときに表示が壊れる件

社内用にテキスト入力ツールを.net(4.0)で作成しています。
入力されたデータの確認用にDataGridViewを使用。
確認用なので編集機能は付けていませんでしたが、「確認画面(DataGridView)で、列の挿入と削除ができたら便利」とリクエストがあり実装することに。

DataGridView のDataSourceだいたい以下の感じでDataTableをバインドしています。

```
Datatable dt = new Datatable();
dtにデータをいれる();

DataGridView dgv = new DataGridView();
dgv.Datasource = dt;
```



#列の削除
DataTableから任意の列を削除するだけでOK。DataGridView の見た目も狙い通り変わります。

```
dt.Columns.RemoveAt(削除する列番号)
```

#列の挿入
DataTableの任意の位置に列を挿入。

```
 dt.Columns.Add().SetOrdinal(挿入したい列番号)
```
当然これでDataGridView の見た目も狙い通り変わる、と思いきやだめでした。

**なぜか挿入列が必ず最後の列として表示されてしまいます。**

データソースであるDataTableの情報は正しく
さらにDataGridViewの中身も、CellPaintingイベントなどでe.ColumnIndexなどを見る限り正しい（狙いどおりの列が挿入されている）。

**表示だけがおかしい**

よくわかりませんが、DataGridViewのバグでしょうか(適当)
非常に不可解ですが、スマートな回避策が見つからず。
以下のようにDataSourceをセットしなおしたらできました。

```
 dt.Columns.Add().SetOrdinal(挿入したい列番号)
 dgv.Datasource = null;
 dgv.Datasource = dt;
```

ちなみに、列を末尾に追加する

```
 dt.Columns.Add()
```
は全く問題ありません。
[CakePHP]SimplePaginatorでDB負荷を軽減する

CakePHPのページネーションは便利な機能ですが、
COUNTクエリを発行するため、テーブルの件数が増えるとDB負荷が大きくなり、
レスポンスが悪くなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38162/912ec0bb-fe5d-8098-2415-b12640271cef.png)


この対策として、CakePHP3.9からSimplePaginatorが追加されました。
https://book.cakephp.org/3/en/controllers/components/pagination.html#simple-pagination

Controllerのinitializeメソッドで以下のように記述することで

```php
use Cake\Datasource\SimplePaginator;

class ExamplesController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();

        // Load the paginator component with the simple paginator strategy.
        $this->loadComponent('Paginator', [
            'paginator' => new SimplePaginator(),
        ]);
    }
```

Back、Nextのみのシンプルなページネーションになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38162/8b3cab95-6657-9b47-425d-5aa9b35e9fb0.png)

count文を発行しなくなることにより、全件表示ができなくなるため、
全件表示はtemplatesから削除しておきましょう。
AtCoder Beginner Contest 173 B問題「Judge Status Summary」解説(Python3,C++,Java)

AtCoder Beginner Contest 173 B問題「Judge Status Summary」の解説を行います。

>問題URL : https://atcoder.jp/contests/abc173/tasks/abc173_b

#問題概要
テストケースのジャッジ結果を表す文字列$S_i$が$N$個与えられる。
ジャッジ結果が'AC','WA','TLE','RE'であったものの個数をそれぞれ求めよ。
##制約
・$1 \leq N \leq 10^5$
・$S_i$は'AC','WA','TLE','RE'のいずれか
#解説
問題文の通りに実装を行えばよいです。
例えば、
・'AC'である個数を$C_0$,
・'WA'である個数を$C_1$,
・'TLE'である個数を$C_2$,
・'RE'である個数を$C_3$,
という4つの変数を作成し、
それぞれを0で初期化し、
$N$個の$S_i$について条件分岐を行って変数を管理します。
その後、出力例のように出力すればACすることが出来ます。

以下、Python3,C++,Javaでの解答例を示します。
#各言語解答例
<details><summary>Python3での解答例</summary><div>

```{B.py}
N = int(input())
c0 = 0
c1 = 0
c2 = 0
c3 = 0
for i in range(N):
  S = input()
  if S == "AC":
    c0 += 1
  elif S == "WA":
    c1 += 1
  elif S == "TLE":
    c2 += 1
  elif S == "RE":
    c3 += 1
print("AC", "x",c0)
print("WA", "x",c1)
print("TLE", "x",c2)
print("RE", "x",x3)
```

</div></details>

<details><summary>C++での解答例</summary><div>

```{B.cpp}
#include<bits/stdc++.h>
using namespace std;
int main(){
  int n;
  cin >> n;
  int c0 = 0;
  int c1 = 0;  
  int c2 = 0;
  int c3 = 0;
  for (int i = 0; i < n; i++){
    string S;
    cin >> S;
    if (S == "AC"){
      c0 += 1;
    }else if (S == "WA"){
      c1 += 1;
    }else if (S == "TLE"){
      c2 += 1;
    }else if (S == "RE"){
      c3 += 1;
    }
  }
  cout << "AC" << " " << "x" << " " << c0 << endl;
  cout << "WA" << " " << "x" << " " << c1 << endl;
  cout << "TLE" << " " << "x" << " " << c2 << endl;
  cout << "RE" << " " << "x" << " " << c3 << endl;
}
```

</div></details>

<details><summary>Javaでの解答例</summary><div>

```{B.java}
import java.util.Scanner;
public class Main{
  public static void main(String[] args){
    Scanner scan = new Scanner(System.in);
    int n = scan.nextInt();
    int c0 = 0;
    int c1 = 0;
    int c2 = 0;
    int c3 = 0;
    for (int i = 0; i < n; i++){
      String S = scan.next();
      if (S.equals("AC")){
        c0 += 1;
      }else if (S.equals("WA")){
        c1 += 1;
      }else if (S.equals("TLE")){
        c2 += 1;
      }else if (S.equals("RE")){
        c3 += 1;
      }
    }
    System.out.println("AC"+" "+"x"+" "+c0);
    System.out.println("WA"+" "+"x"+" "+c1);
    System.out.println("TLE"+" "+"x"+" "+c2);
    System.out.println("RE"+" "+"x"+" "+c3);
  }
}

```

※S.equals("文字列A")でSが文字列Aと等しいかを判定することが出来ます。
</div></details>
gcloudコマンドでopensslのライブラリが見つからずエラーになる場合の対処法


メモ
opensslのバージョンがあがってlibssl.1.0.0.dylibがなくなったっぽい

```
Library not loaded: /
usr/local/opt/openssl/lib/libssl.1.0.0.dylib
```

以下の手順で1.0.2tを使用するようにした

```
brew update && brew upgrade
brew uninstall --ignore-dependencies openssl
brew install https://github.com/tebelorg/Tump/releases/download/v1.0.0/openssl.rb
```

```
brew switch openssl 1.0.2t
```
ポートフォリオ投稿型プラットフォーム Techfollioをリリースしました。

# 開発に至った経緯
プログラミングスクールが流行り駆け出しエンジニアは増えてきているはずなのに**ポートフォリオが少ない**のが不思議に思いました。転職でもポートフォリオは求められることが多いですしね。それをまとめたプラットフォームを作れば見た人がモチベーションも高まるし面白そうだと思い開発に至ります。

[Techfollio](https://techfollio.com)

#PCサイズ
<img width="1265" alt="スクリーンショット 2020-08-09 19.25.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/9f206053-ade0-b1c6-c1fb-b24b7955752e.png">

#スマートフォンサイズ
![IMG_3246.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/d2295994-bc06-bd4a-960a-a838c1d789d4.jpeg)



# 開発環境
ruby 2.6.3
rails 5.0.7.2
capistrano 3.11.1
nginx 1.16.1

# 機能紹介
Techfollioはまだ開発最中ですが現時点での機能を紹介します。(随時更新します)
## ログイン機能
![ログイン説明.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/a201f59a-c54d-0750-c618-57d90d594363.gif)

gem deviseを使用
ログインしていなくてもみんなのポートフォリオを見ることができます。
当たり前ですが、ログインしているユーザーのみポートフォリオ作成,編集、削除可能。

メール認証には[Sendgrid](https://sendgrid.kke.co.jp/)を利用しており、登録したメールアドレスに確認メールが届きます。
<img width="447" alt="スクリーンショット 2020-08-10 20.10.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/ff636d69-ae79-5d39-ddf9-9d7122ee3b1e.png">

## Twitter連携機能
![Twitter連携.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/acb33a31-16ff-48a3-775a-d7679ef2b971.gif)

## コメント機能
ポートフォリオにコメントを書くことができます。(ログインしないとコメントできません)
<img width="698" alt="スクリーンショット 2020-08-11 0.20.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/8a7d7e1c-4993-4920-292f-4e84a3f6a5f0.png">

## ポートフォリオ検索
プログラミング言語ごとポートフォリオを見やすくするために検索機能を実装しました。
<img width="1263" alt="スクリーンショット 2020-08-11 0.34.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/49135efa-4404-4eb2-ff6d-f9b160d2ab12.png">
<img width="1267" alt="スクリーンショット 2020-08-11 0.35.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/85b72bf6-2017-7405-4d64-6f6c906d5d99.png">

## SNSシェア
ポートフォリオをFacebook,Line,Twitterにシェアできます。
<img width="400" alt="sns ss1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/1500bf71-dfcb-f113-a218-86876341ae6f.png">
<img width="400" alt="sns ss2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/037dc551-2593-e99a-3fe3-675b4f548f1b.png">
<img width="400" alt="sns ss3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395921/c75ec7da-bcd5-90dc-3178-32bbe6b2d449.png">



# 最後に
より多くの人に利用してもらうために今後も改善続けていきます。
ポートフォリオを投稿して繋がろう！
[Techfollio](https://techfollio.com)
RailsのRoutesをcsvで出力

# 何を書いた記事か

Railsのroutes一覧をcsv形式で出力する方法

→ 新しい組織でシステムキャッチアップする際、ルーティングから辿って全体を俯瞰したい、その情報を体系的にSpreadSheetなどにまとめたい場合に利用できる

# どうやるか
## 参考になるソース
railsのroutesの実装を参照
https://github.com/rails/rails/blob/5ccdd0bb6d1262a670645ddf3a9e334be4545dac/railties/lib/rails/tasks/routes.rake
- `inspector` に全てのRoute情報を詰めて、 `.format()` で整形すれば良さそう
- `ConsoleFormatter` の実装を真似て独自のFormatterを作れば良さそう

## 実践
### 適当なブランチを切る
- 個人的な理解のために出力する情報なので、本番ソースに影響ださないよう、ローカルで適当なブランチを切る

### taskを作成

```bash
$ bundle exec rails g task route_formatter csv
```

```ruby:lib/tasks/route_formatter.rake
namespace :route_formatter do
  desc "get route as csv format"
  task csv: :environment do |t|
    class CSVFormatter
      def initialize
        @buffer= []
      end
  
      def result
        @buffer.join("\n")
      end
  
      def section_title(title)
      end
  
      def section(routes)
        routes.each do |r|
          @buffer << [r[:name], r[:verb], r[:path], r[:reqs]].join(",")
        end
      end
  
      def header(routes)
        @buffer << %w"Prefix Verb URI_Pattern Controller#Action".join(",")
      end
  
      def no_routes
        @buffer << ""
      end
    end
    require "action_dispatch/routing/inspector"
    all_routes = Rails.application.routes.routes
    inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
    puts inspector.format(CSVFormatter.new, ENV['CONTROLLER'])
  end

end
```

### 実行

```bash
bin/rails route_formatter:csv
```

- MacでClipboardに入れたい場合は下記

```bash
bin/rails route_formatter:csv | pbcopy
```

- あとはExcelとかSpreadSheetで処理

# 参考リンク
- https://qiita.com/ya_s_u/items/08f066ba8af0831c0af1
Googleマップで距離を測定する際の直線の傾きについて

Googleマップの機能で「距離を測定」って便利ですよね？
でも、マウスで直線を引いたとき、目的地がぴったり真北、真東とか斜め45度ぴったりに北東の方角を向いてることって滅多にないと思います。

たとえばこんな感じ
![distance.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666984/6fb440be-6a87-4f3c-6644-1d0d182a1980.png)

この地図を見た時点で、北東に45度より少し東に傾いているのが分かりますよね？！
じゃ一体何度傾いてるんだ、という訳でいろいろ考えてみたところ、結局辿り着いたのは原始的な手法でした。

Googleマップを画像として切り出して、ペイントツールなんかを使って超拡大して、この斜めの線を対角線とする長方形を選択ツールで取り出し、ピクセル数を測定。
すると、

```
height/width = tanΘ
```

あ、最初に引いた線を斜辺とする直角三角形の正接がわかった。
何も難しいコト考えなくても高校数学の三角比の知識で十分解けるじゃん、ってことで決着。
プログラミングの知識がなくても、数学だけで解けちゃう。
やっぱり数学って大事だね、と思ったのでした。

P.S. あとでもう一度測定してみたら、奇跡的に斜め45度ぴったりでした。。。
[SQL]SELECT文でテーブルからデータを検索

#テーブルのデータを検索
データベースのテーブルからデータを検索するときは、SELECT文を使います。
基本的に以下のような形で使います。

```
SELECT * FROM テーブル名; 
```

では、実際に使ってみます。

```
mysql> SELECT * FROM user;
+------+---------------+
| id   | name          | 
+------+---------------+
|    1 | テスト　　      | 
+------+---------------+
1 row in set (0.17 sec)
```

#必要なカラムのデータのみを抽出する

SELECTとFROMの間にカラム名を指定することで、必要なカラム名の値のみ抽出できます。

```
SELECT カラム名1, カラム名2, ..., カラム名n FROM テーブル名; 
```

では、userテーブルから「name」だけ抽出してみます。

```
mysql> SELECT name FROM user;
+---------------+
| name          |
+---------------+
| テスト          |
+---------------+
1 row in set (0.18 sec)
```

#条件を指定して検索する
条件を指定してデータを検索するときはSELECT文の中で「WHERE」を使います。

```
SELECT * FROM テーブル名 WHERE 条件文;
```

まずは検索条件を絞るための複数データを準備します。

```
mysql> select * from user;
+------+---------------+---------------------------+------------------------+
| id   | name          | prefecture | address                               |                             
+------+---------------+---------------------------+------------------------+
|    1 | テスト　　    　 | 東京都      | 東京都千代田区丸の内１丁目                 |                             
|    2 | テスト1         | 滋賀県      | 滋賀県彦根市金剛寺町2-16ザ金剛寺町313      |                            
|    3 | テスト2         | 東京都      | 東京都練馬区豊玉南4-11                   |
|   4  | テスト3         | 北海道      | 北海道千歳市千代田町2-3千代田町シティ102　　 |                          
|    5 | テスト4         | 東京都      | 東京都小平市回田町2-12-17フォレスト回田町202 |                           
+------+---------------+---------------------------+------------------------+
```

「WHERE」を使って、東京都在住という条件でデータを抽出してみます。

```
mysql> SELECT * FROM user WHERE prefecture = '東京都';
+------+---------------+---------------------------+------------------------+
| id   | name          | prefecture | address                               |                  
+------+---------------+---------------------------+------------------------+
|    1 | テスト     | 東京都     | 東京都千代田区丸の内１丁目                    |                
|    3 | テスト2    | 東京都     | 東京都練馬区豊玉南4-11                      |                 
|    5 | テスト3    | 東京都     | 東京都小平市回田町2-12-17フォレスト回田町202    |            
+------+---------------+---------------------------+------------------------+
3 rows in set (0.16 sec)
```
Power BIのストリーミングデータセットのデータをクリアする

# 背景
Gravioをいろいろ弄っていると、Power BIにわたすパラメータとかデータを一旦初期化したくなることがあります。特に、アクションのテスト実行したときのダミーデータ `0` がグラフに入ったり、場所の情報を追加したかったりすると、ゴミデータが入ることが多いんですね。
で、フィルターを使ってそのダミーデータや場所を無理やり非表示にしてたんですが、なんとかデータ自体を初期化できないものかと悩んでました。そのものズバリなメニューが見つからないんですね。

# 結論
Power BIのストリーミングデータセットでレポートを作るには履歴データを取得するのですが、これを一旦無効にして、もう一度有効にするとデータが削除されるのできれいになります。

# 手順
Power BIのサイドバーからストリーミングデータセットを選択し、編集メニューを実行します。
![powerbi-streamingdataset-edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/cc11502e-100e-dfc7-29a9-9f5a27f8614d.png)

編集画面が出てくるので、下の方にある「履歴データの解析」をオフにして一度保存します。
![powerbi-edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/c32260dc-1ac2-68f4-337a-e926290670eb.png)

同じ手順でもう一度有効化すれば新たにデータを蓄積し始めます。バンザイ
Power BIとS3の連携方法について

## はじめに

Amazon S3 + Power BIで検討する場合の方式について備忘録
※2020/8に検討した結果です。

## 方式

S3からPower BI に直接つなぐ方法は基本的には以下の三つです。
直接つながないADFなどのデータ移動サービスでAzureに移動するパターンもあります。

推奨は3 or Azureに移動する、です。	
1. S3 APIによる取得 (Importのみ)
	参考：https://community.powerbi.com/t5/Power-Query/Can-I-connect-to-a-Amazon-S3-bucket-using-Power-Query/td-p/111919
2. CData など3rd Party ツールによる取得(製品によりDQ 可能)
	参考：https://www.cdata.com/jp/kb/tech/amazons3-cloudhub-powerbi-service.rst
3. Redshift経由、Athena経由による取得(DQ 可能)
	SpectrumやAthenaはETL不要とできる点は良いと思います

## 注意事項

### 認証・認可
当然ながら、接続方式により、選べる認可機能が異なります。  
特に1の場合にはデータレイク側で直接権限制御となるため、行レベルのセキュリティなどの詳細なセキュリティの実装は難しいです。  
また、AWS上にある場合にはPower BI Service上でのSSOは利用できないので、Power BI Serviceでレポートを公開するときの認可制御はPower BI dataset側での実装が必要です  

参考：

https://docs.microsoft.com/ja-jp/power-bi/connect-data/power-bi-data-sources#single-sign-on-sso-for-directquery-sources

https://docs.microsoft.com/ja-jp/power-bi/connect-data/power-bi-data-sources
	
※PBI Desktopからなら、RedshiftもAD認証でとりに行けるようです
https://aws.amazon.com/jp/blogs/news/federate-amazon-redshift-access-with-microsoft-azure-ad-single-sign-on/
	 
### パフォーマンス
3と一部の3rd Partyについては、Direct Queryベースのものであれば、クエリを実行するエンジン(Athena,Redshiftなど)の性能次第ですが、Importの場合はPower Queryを利用してRedshiftから取得したデータ加工を行う場合、処理環境が共有環境(Pro,Free)なのか、占有環境(Premium)の違いにより、安定しない場合があります。  
共有容量の場合、スペック不足による、タイムアウトの可能性が上がります。

また、1,2の方式でS3に直接データ取得をする場合、関係ないデータはスキャンしないなどのパフォーマンス向上技術の恩恵を受けることができません。  
このあたりは、コスト最適と格納を目指すストレージ層と、読み取り性能の最適化を目指すDWH層の違いとして割り切るのかどうかとなるかと思います
HPE Proliant用ラックレールスペック

HPEのラックレールについてブラケットの取付可能範囲とか全長とか全然ネット上に情報が無いので、どのレールを買えばいいのか迷ってマジで困る。

仕方ないので実測で情報をためておく。

## 実測値
![スクリーンショット (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199750/6ccada7b-fc69-683b-084a-be60ecfd3e6a.png) [^1]

|型番|名称|①レール長(mm)|②ブラケット調整範囲(mm)|対応機種等|
|---|---|---|---|---|
|679368-001|1U SFF用ツールレスラックレール|740|606-910|DL360 Gen8/Gen9(SFF)|


[^1]: 図は富士通のPY-RR005のPDFから拝借。富士通製品はこういうのがきちんとしてるのがえらい。
rails6 herokuへデプロイ

様々なサイトで記載内容がバラバラですが、自分はこの方法でうまく行ったので備忘録として、、、



## 開発環境
> ruby 2.5.1
rails 6.0.3.2
devise 4.7.2
postgre 12.3
https://localhost:9292/



## 参考にした記事
> [Rails6 ローカルで頑張って作ったwebアプリをHerokuでデプロイした話](https://qiita.com/miriwo/items/2ca707683f5b2567d264)



## rails変更前作業
> herokuへ会員登録 ※含むクレジットカード登録
>> ログイン後右上の忍者マークから Account settings
＞Billing＞Add credit card

## 変更箇所
```ruby:config/puma.rb
#http://localhost:3000/の場合は作業不要
#https://localhost:9292/の場合は以下を削除
if ENV.fetch('RAILS_ENV') { 'development' } == 'development'
  ssl_bind '0.0.0.0', '9292', key: './localhost-key.pem', cert: './localhost.pem'
end
```



## ターミナルでの作業
#### gitのリモートへpushを済ませてから行ってください。
1.これをしないと後述のherokuコマンドが打てません。

```ターミナル:projectsフォルダで実行しました。
% brew install heroku/brew/heroku
```
2.これをしないとターミナルからheroku上のアプリを操作出来ないようです。

```ターミナル:projectsフォルダで実行しました。
% brew tap heroku/brew && brew install heroku
```
3.herokuにアプリを作ります。
↑ここでherokuのIDとpassWordを求められるようですが、私は既にログインしていたので、ブラウザが開いてloginボタンを押しただけでした。

```ターミナル:webアプリフォルダで実行しました。
% heroku apps:create （herokuアプリ名）
（Herokuアプリ名）は例えばchat-space等なんでも良いようです。
わたしはlocalの名前と同じにしました。
ちなみに消すときは
% heroku apps:destroy --app herokuアプリ名
```
4.localのwebアプリのプッシュ先にHerokuが追加されたことを確認する。

```ターミナル:webアプリフォルダで実行しました。
% git remote -v

>heroku  https://git.heroku.com/herokuアプリ名.git (fetch)
>heroku  https://git.heroku.com/herokuアプリ名.git (push)
>origin  https://github.com/gitのid/gitのアプリ名.git (fetch)
>origin  https://github.com/gitのid/gitのアプリ名.git (push)
```
5.Heroku用のDBを追加

```ターミナル:webアプリフォルダで実行しました。
% heroku addons:create cleardb:ignite

>Creating cleardb:ignite on ⬢ アプリ名... free
>Created cleardb-cubed-26217 as >CLEARDB_DATABASE_URL
>Use heroku addons:docs cleardb to view documentation
```
6.CLEARDB_DATABASE_URL以下をメモる。

```ターミナル:webアプリフォルダで実行しました。
% heroku config

>=== アプリ名 Config Vars
>CLEARDB_DATABASE_URL: mysql://hogehoge:fugaguga@aheahe/uhiha?reconnect=true
```
７．メモったものを元に順に設定する。

```ターミナル:webアプリフォルダで実行しました。
% heroku config:add DB_NAME="uhiha"
>Setting DB_NAME and restarting ⬢ アプリ名... done, v5
>DB_NAME: uhiha

% heroku config:add DB_USERNAME="hogehoge"
>Setting DB_USERNAME and restarting ⬢ アプリ名... done, v6
>DB_USERNAME: hogehoge

% heroku config:add DB_PASSWORD="fugafuga"
>Setting DB_PASSWORD and restarting ⬢ アプリ名... done, v7
>DB_PASSWORD: fugaguga

% heroku config:add DB_HOSTNAME="aheahe"
>Setting DB_HOSTNAME and restarting ⬢ アプリ名... done, v8
>DB_HOSTNAME: us-cdbr-iron-east-05.cleardb.net

% heroku config:add DB_PORT="3306"
>Setting DB_PORT and restarting ⬢ アプリ名... done, v9
>DB_PORT: 3306
```
8.herokuにpush

```ターミナル:webアプリフォルダで実行しました。
% git push heroku master
〜気長に待つ ひたすら待つ ただ待つ〜
```
9.migrate実行

```ターミナル:webアプリフォルダで実行しました。
% heroku run rails db:migrate
```
１０．確認

```ターミナル:webアプリフォルダで実行しました。
% heroku apps:info

>=== アプリ名
Addons:         cleardb:ignite
                heroku-postgresql:hobby-dev
Auto Cert Mgmt: false
Dynos:          web: 1
Git URL:        https://git.heroku.com/アプリ名.git
Owner:          自分のメアド
Region:         us
Repo Size:      532 KB
Slug Size:      76 MB
Stack:          heroku-18
Web URL:        https://アプリ名.herokuapp.com/
```
上記 Web URL: へアクセスしデプロイを確認しよう！
Ubuntu 16.04にmecabをインストール

#概要
markov連鎖による文章の自動生成がしたくて，その準備としてmecabをインストールする．

#実装環境
###codeanywhereのContainer
- Ubuntu 16.04
- Python 3.7.0

#インストールと実行
###インストール
```
$ sudo apt install mecab libmecab-dev mecab-ipadic-utf8
```
###追加辞書のインストール
```
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ sudo ./bin/install-mecab-ipadic-neologd -n -a
$ cd 最初にいたディレクトリへのパス
```
###実行
terminalにmecabと入力するとmecabが起動し，その後文章を入力すると形態素解析されます．

```
$ mecab
こんにちは．今日はいい天気ですね．
```
###実行結果
```
こんにちは      感動詞,*,*,*,*,*,こんにちは,コンニチハ,コンニチワ
．      記号,句点,*,*,*,*,．,．,．
今日    名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
は      助詞,係助詞,*,*,*,*,は,ハ,ワ
いい    形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
天気    名詞,一般,*,*,*,*,天気,テンキ,テンキ
です    助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
ね      助詞,終助詞,*,*,*,*,ね,ネ,ネ
．      記号,句点,*,*,*,*,．,．,．
EOS
```
mecabを終了する際はCtrl+Cです．
Azure Synapse AnalyticsでSHRINK DBがGA


## 概要

Azure Synapse AnalyticsはSQL DWというブランド名だったころから、Shrink DBをサポートしていませんでしが、今月のUpdateで一般提供されたようです。

## SHRINK DBってなに?

SQL Serverを運用されている方はご存知かと思いますが、SQL Serverのデータ保存領域は確保されたディスク容量(①)と、実際の利用(②)が別々に管理されます。

通常、テーブルの増大(②)に伴ってディスクの確保領域(①)は自動拡張されます。

しかし、利用に応じて確保されたディスク容量(①)が増えたあと、テーブル削除などで実際の利用(②)が減ると、実際には使っていないのにディスク容量を確保している状態（①>>②）が生まれます。

ディスクの確保領域を減らしたい場合、SHRINK DBというコマンドを実行して、使われていない確保領域(①)を解放することで、①≒②のような状態にする必要があります。

Azure Synapse Analyticsでも同様の仕様があり、**テーブルは削除したはずなのに、ディスクの確保領域により課金が発生する**ため、一部の利用者の間では問題となっていました。  
> [ツールは適材適所で使う必要があるという話](https://qiita.com/neppysan/items/286c38d5ad38d8fafe3f)

## リファレンス

[DBCC SHRINKDATABASE (Transact-SQL)](https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-shrinkdatabase-transact-sql?view=sql-server-ver15)

[リリースノート](https://docs.microsoft.com/en-us/azure/synapse-analytics/sql-data-warehouse/release-notes-10-0-10106-0#july-2020)  
en-usの記事でしか記載がないので注意

[Synapse Analytics Shrink Database](https://techcommunity.microsoft.com/t5/azure-synapse-analytics/synapse-analytics-shrink-database/ba-p/1559522)
VRハードのメーカのチョイまとめ。

## ディスクレーマー

持っているパソコンスペック：Ryzen5 3600、Nvidia Geforce 2070、16GBのRAMです。
なんかめっちゃ強いパソコンではないです。やや普通。

俺の持っているのVRセットはオキュラスクエストです。　６万円の１２８gbのバージョンです。

言いたいのは、ちょっとオキュラスの派です。ご注意を。

## VRハードの現在ステータス

現在のVR世界はちょっと欠片されています。

VR問題は、各メーカーは別々のソフトのショップを立っています。
例えば、俺の持っているものは[オキュラスクエスト](https://www.oculus.com/quest/features/)ですね。[オキュラスを起動すると、すぐにストアページに入りますとゲームを買えますね。](https://www.oculus.com/experiences/quest/)
Oculusのパソコンとテザリング専用の[RiftS](https://www.oculus.com/rift-s/)もありますね。
**問題点①** オキュラスクエストのストアとオキュラスリフトのストアは離れています。クエストのゲームを作ったら、リフトストアに売りたいなら、リフトバージョンも別につからなきゃ！
**問題点②** その上に、もしゲームはクエストとリフトにもあれば、もしクロスプラットフォーム買いが不可だったら、同じゲームを二回を買わなきゃいけないです！
**注意点！！**現在、オキュラスクエストだけがPCで離れて遊べます。他のシステムは、PCを繋いで、PCのグラフィックスボードの力でレンダリングして遊べます。（PCと繋がりはテザリングと呼ばれていますね。）とりあえずPC98からアップグレードしたくないがVRエロを見たいのお友達、Oculus Questはおすすめです。

オキュラス以外、他VRのメーカーもいます。

### メインクラス（人気＆新ハードはほぼ出ている）

- 上記のOculusのやつ
- [HTCのViveシリーズ](https://www.vive.com/eu/)（ストア：[Viveport](https://www.viveport.com/infinity)）
- [最近発売されたValveのIndex](https://steamvr.jp/)(ストア：[みんなの好きなSteam](https://store.steampowered.com/))

まあこっちで開発を始まったら、いけると思います。でもかならずハードとストアの突破することをしっかり考えてください。そのストアと物流の関して別の記事に書きます。

### WMRクラス

Windows Mixed Realityは正直いうと、あんまり人気がない。ハードはほぼないし、新しいハードは少なめ・・
ちょっとこっちに始まったら危険だ。

**例えハード：**

- [SamsungのOdysseyのシリーズ](https://displaysolutions.samsung.com/monitor/odyssey)
- [HP Reverb G2](https://jp.ext.hp.com/immersive/reverb_g2/)

すべてのWMRは[Microsoft Store](https://www.microsoft.com/ja-jp/store/collections/mixedreality)で買えます。

**目玉品**

- [Microsoft Hololens](https://www.microsoft.com/ja-jp/hololens)

なんかビジネス用のARハードです。ものすごく高いですが、ちょっとおもろかもしれません。

### 特別クラス：　PlayStation VR

PSVRはもしかして一番売っているVRハードですが、俺たちみたいなド貧乏のインディー開発者なら、PSVRに入るのは難しいかもしれません。
DevKitが持ってないなら、開発ができません。　本間ソニーに連絡いただいたら、DevKitをもらえるはずです。
こういうものもありますので、ご意識をもってください。

### VRじゃないクラス

- [Google Cardboard](https://arvr.google.com/cardboard/)みたいなゴーグルにスマホを入れられるのマジックレンズみたいなもの。ユースケースは一つだけ：VRのエロビデオを見ることです。いつでもVRの話をやったら、「あたいもVRやったよ、あのスマホを入れたやつ！！」ってちっとむかつく。あれはVRではないよ。ふざけるな。

とりあえずこれで全大きいのメーカなどを紹介しました。

次の記事のテーマは：

- 俺のUnityの環境構築セットアップ
- Sidequestとハウツーユース
- VRゲームの物流（マジで開発したら、誰も遊べなかったらめっちゃもったいないじゃねーか）

よろｃくお願いします
＃１【備忘録】Java 奇数の要素と偶数の要素の和の出力


# はじめに
　今年の２月からプログラミングスクールへ通い、晴れて７月にIT企業に就職した者です。
学習した言語のアウトプットをしたくて記事の投稿を始めてみようと思いました！
　今回はプログラミングスクールで学習しなかったJavaに関する記事を投稿します。

#開発環境
今回は"Eclipse"という総合開発環境でやってみました。
こちらの記事を参考に開発環境を構築してみてください。

[EclipseでJava開発環境を作る（Mac編）](https://codeaid.jp/eclipse-java-mac/)
※今回はMacでの作業となります。

#実装
```java

class Main {
  public static void main(String[] args) {

    int[] numbers = {1, 5, 8, 10, 13, 18};
    int oddSum = 0;
    int evenSum = 0;

    for (int number : numbers) {
      if (number % 2 == 0) {
        evenSum += number;
      } else {
        oddSum += number;
      }
    }

    System.out.println("奇数の和は" + oddSum + "です");
    System.out.println("偶数の和は" + evenSum + "です");
  }
}
```


 上記コードを上から順に解説します！

　Mainクラスの中にmainメソッドを定義します。

```java
class Main {
  public static void main(String[] args) {
```

　int型の要素を持つ配列に変数numberに好きな整数をいくつか書きます。

```java
int[] numbers = {1, 5, 8, 10, 13, 18};
```

　int型に変数oddSumとevenSumを定義し両変数の中には0を入れます。
　※oddSumは奇数の和、evenSumは偶数の和という意味です。

```java
int oddSum = 0;
int evenSum = 0;
```

for文で繰り返し処理をさせif文で条件分岐を作ります。
今回は"拡張for文"というものを使用します。

```java
for(データ型 変数 : 配列名) {
    繰り返し処理;
}
```

　文の中にはint型の変数numberと配列numbersを記入します。
　if文の中には"numberが偶数の場合"と条件をつけます。
　※`+=`とは例えば`a += b`の場合`a = a + b`と同じということです。

```java
for (int number : numbers) {
      if (number % 2 == 0) {
        evenSum += number;
      } else {
        oddSum += number;
      }
}
```

　そして最後に出力をしてあげます！

```java

System.out.println("奇数の和は" + oddSum + "です");
System.out.println("偶数の和は" + evenSum + "です");
```

　Mainクラスとmainメソッドの閉じかっこも忘れずに！]

```java
 }
}
```

#実行
```sh:実行結果
奇数の和は19です
偶数の和は36です
```
と表示されていれば成功です！

#エラーになってしまう場合
可能性としては`;`が抜けている場合があると思いますので確認してみてください！

#最後に
私も絶賛勉強中ではありますがプログラミングを勉強中の皆様、
根気強く、そしてコーディングが楽しくなるように一緒に頑張っていきましょう！
最後まで見てくださりありがとうございました！！！
(ジェフユナイテッドで覚える)三項演算子の世界へようこそ

# はじめに

三項演算子、使ってますか？
先日とうとう後輩の @miriwo 氏がめでたく三項演算子に目覚めたということで、これはめでたいということで筆を執りました。

[PHP 「?:」 の正体を知ってすっきりした話](https://qiita.com/miriwo/items/ddaccdad5060c525f507)

まあ、タイトルだけ見るとエルビス演算子に目覚めたのかなって気になってましたけど。
それはそれで大変便利なのです。

# 三項演算子とは

例を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57811/e3ffcc4e-5f19-e7b2-d432-3fbe16bdbf5e.png)
転載元: https://chiicomi.com/smp/r_news_detail?id=19e92c3c-0b86-11e6-8bd0-a0369f7b8e6e

こちらは我らがジェフユナイテッド市原千葉のマスコット、ジェフィとユニティです。
（千葉なのに）秋田犬の双子のわんこなんですが、キャラクターデザイン上の取り計らいで、大きさと背番号以外は区別がつかないようになっています。
ある程度のレベルのジェフサポになると **「キリッとしてるほうがジェフィ、やんちゃな方がユニティ」** とか **「耳がシャキッとしてるほうがジェフィ、丸っこい耳がユニティ」** とか言い出したりするんですが、他サポからは **「ジェフサポは（いろいろな意味で）あたまがおかしい」** と思われているので聞き入れてもらえません。

なので、犬の背番号が2だったらジェフィ、2じゃなかったユニティを `name` に代入するコードをJavaScriptで書いてみました。

```javascript
const name = (dog.uniform_number === 2) ? 'Jefy' : 'Unity';
```

`?` の左に判定条件、その右に判定が `true` のときの値、 `:` を挟んでその右が `false` のときの値です。
これをたまにいる三項演算子否定派が書くとこんな感じになります。

```javascript
const name = '';

if(dog.uniform_number === 2){
    name = 'Jefy';
} else {
    name = 'Unity';
}
```

長い……

要はこういうのをif文ではなく式で簡便に表現できるというのが三項演算子です。
実は本名は「条件演算子」といいます。

https://ja.wikipedia.org/wiki/%E6%9D%A1%E4%BB%B6%E6%BC%94%E7%AE%97%E5%AD%90

三項演算子は結構どの言語にも実装されています。

# 入れ子の三項演算子

あんまりやってはいけないのですが、三項演算子はネスト（入れ子）して書くことができます。

例を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57811/461cc202-3960-a802-28f5-91025f327bda.png)

実はジェフのマスコットはジェフィとユニティのオス犬の双子だけではなく、どこからともなく現れた **みなちゃん** という白い雑種のメス犬もいます。写真の一番右の子ですね。
ちなみにジェフィとユニティは毎年シーズンシートを買って入っている一般サポーターらしいのですが、みなちゃんはれっきとしたジェフユナイテッド株式会社の社員です。

そんな設定の話は置いといて、みなちゃんの背番号はサポーターナンバーと呼ばれる12番です。つまりこんな感じになります。

```javascript
const name = (dog.uniform_number === 2) ? 'Jefy' : (dog.uniform_number === 9) ? 'Unity' : 'Mina-chang';
```

どうですか？　見づらくてハゲそうですよね。
見やすくするテクニックとして、記号の前で改行するというのがあります。
外人が書くコードでよく見かけますよね。

```javascript
const name = (dog.uniform_number === 2) 
    ? 'Jefy'
    : (dog.uniform_number === 9)
        ? 'Unity'
        : 'Mina-chang';
```

ただ、この入れ子の三項演算子、**PHPだけなぜか動作が違います。**あいつはなぜか **右から評価** するので、カッコを使って、こんな感じに書かないと思ったとおりになりません。

```php
$name = (dog.uniform_number === 2) 
    ? 'Jefy'
    : ( (dog.uniform_number === 9)
        ? 'Unity'
        : 'Mina-chang');
```

不毛感がすごい……

※追記
@rana_kualu さんからコメントでいただきましたが、カッコを使わない三項演算子のネストはPHP7.4からは非推奨、PHP8からはエラーになるとのことです。
参考: [【PHP8.0】PHPの三項演算子が他言語の実装に一歩近付く](https://qiita.com/rana_kualu/items/0de1e406f72c0ef86432)


# おわりに

三項演算子の特殊な書き方として、エルビス演算子とかnull合体演算子の話は次回書きます。
それではお元気で！ Enjoy, Summer!!