OmniAICreator/Qiita-1.07M huggingface dataset:
WindowsでNervesやるならWSL2+Docker+VSCode

Windows 10 + WSL2 + Docker + VSCodeで、Nerves開発環境をサクッと作れるdevcontainerを作りました。

# 変更履歴

|Date|Author|ChangeLog|
|:--|:--|:--|
|2020/7/11|@matsujirushi|id_rsaのリンク作成コマンドを訂正|

# devcontainerとは？

その名のとおり、開発（development）に使うDockerコンテナ（container）です。
VSCode拡張のRemote - Containersがこのフォルダ（ファイル？）を開くと、定義されたDockerコンテナを構築して良い感じにフォルダをマウント、VSCodeから操作することができるようになります。

[Developing inside a Container](https://code.visualstudio.com/docs/remote/containers)

# Nerves開発環境を作る

## 事前準備

1. Windows 10 バージョン2004を用意（アップグレード？）する
2. WSL2を有効にする
3. Docker Desktopをインストールする

これでは良く分からないという方は、、、[こちら](https://qiita.com/matsujirushi/items/cfb0e655831a39f5c15a)をご参照くださいませ。

## Nerves開発用devcontainerをクローン

適当なフォルダにgit cloneしてください。

```
git clone https://github.com/matsujirushi/nerves-devcontainer
```

## VSCodeでdevcontainerを起動する

Remote Development拡張を入れたVSCodeの**Remote-Container: Open Folder in Container**で、.devcontainerのあるフォルダを開いてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/39359c09-7351-24c2-3bc4-ff68d4a6384d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/0f134a3a-2f41-2976-d0c1-7bcacad29fcd.png)

すると、、、Dockerコンテナの作成が始まって、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/f4a5b512-6f4a-ee2b-3101-1a118d510507.png)

はいっ、完成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/71a81b0c-24c2-ca1b-86d9-15e90fd41234.png)

メニューの**表示 > ターミナル**で、Dockerコンテナ内のシェルが表示できます。

/workspaces/nerves-devcontainer 配下が、git cloneしたところにマウントされているので、消えたら困るファイルはここに置くようにしましょう。

# Nervesサンプルをビルド

## （任意）キーの作成

Nervesのビルドにキーが必要です。無い場合は下記コマンドで作成してください。
~/.sshに作ると、、、Dockerコンテナと一緒に消えて無くなってしまうので、/workspaces/nerves-devcontainer/.sshにシンボリックリンクで対処します。

```
mkdir .ssh
ssh-keygen -t rsa -f .ssh/id_rsa
ln -s `pwd`/.ssh/id_rsa* ~/.ssh/
```

## Nervesサンプルを作成、ビルド

こんな感じ。

```
mix nerves.new hello_nerves
cd hello_nerves
export MIX_TARGET=rpi3
mix deps.get
mix firmware
```

# イメージファイルの書き込み

ビルド結果のイメージファイルをmicroSDなどにフラッシュするときは、Windowsのコマンドプロンプトで[fwup.exe](https://github.com/fhunleth/fwup)すればOK。
vscodeにvscode-proto3の拡張をインストール

vscodeに[vscode-proto3](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3)のプラグインを入れた。

するとこんなエラーが。
![スクリーンショット 2020-06-09 20.52.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/e5235e46-0d12-f0e6-4ce8-a5dedbb384b2.png)
clang-formatが指定されてなくて怒られてる。readmeにも記載があった。
<img width="730" alt="スクリーンショット 2020-06-09 21.02.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/1a34918a-ab00-4f42-ea76-a187a9f3ba85.png">



command + , でvscode-proto3の設定を確認。
![スクリーンショット 2020-06-09 20.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/b385ff1a-5e33-f7ac-24c3-3d8418f76ca6.png)

setteings.jsonにreadmeのexample通りの設定を追加。
![スクリーンショット 2020-06-09 20.59.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/9eefffde-cefa-8062-64ab-c680837475f9.png)

でもまだ冒頭のエラーが出る。そもそもclang-format自体をインストールしていなかったのが原因。[こちら](https://qiita.com/para7/items/b4a90dd7338320655357)を参考にclang-formatをインストール。これでエラーは出なくなった。

そもそもclang-formatを知らなかったのでちょっと調べてみたら、cやc++、ProtocolBufferなどのコードをフォーマットできるツールだった。
Azureの新試験AZ-104を旧試験AZ-103と比較してみた

# はじめに
Microsoft Azureの資格である「Azure Administrator Associate」取得できる試験AZ-103が、いつの間にかアップデートされAZ-104になってました。。。もともとAZ-103を受験しようと思って勉強していました。一応、AZ-103は今年8月まで受けることができるようなのですが、せっかくなので、AZ-104についてまとめておこうと思います。


試験 AZ-104: Microsoft Azure Administrator (beta)
https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-104

## 2020/7/18追記
[AZ-103にすべりこみ合格しました！！](https://qiita.com/tagfa/items/5f8b1bf4c76a1ab13c19)

## 2020/9/1追記
AZ-203AZ-204の比較記事を書きました！
[AZ-203とAZ-204の比較](https://tagfa.wpx.jp/archives/424)

# 違い
公式ページにあるスキルアウトラインをもとに、旧試験のAZ-103と比較してみました。
AZ-103 https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE3VwUR
AZ-104 https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE4pCWy

大きな差異としては、
　・出題範囲にコンテナが追加
　・計算資源（VMとコンテナ）の出題割合が増加
という2点のみかと感じました。
出題範囲については、計算資源についてが25-30%、ネットワークについてが30-35%と、この2科目で50%を超えています。
この2科目をしっかり学習することが重要であると感じました。
また、計算資源のコンテナについてですが、Kubernetes、Azure Kubernetes Serviceについても出題されるようですので、
注意です。

もう少し細かい比較については、以下ブログに記載しておりますので、よかったらご覧ください。
https://tagfa.wpx.jp/archives/129
Raspberry Piのセットアップ

備忘録として

#環境
- Raspberry Pi 3 Model B
- Macbook
- SDカード32GB(東芝)

##Raspberry Pi OS のインストール
OSをダウンードしようと公式サイトに行ってみると、Imagerなるものがあり、これを使えば簡単にセットアップできそうなので、今回は手動でなく、このImagerでインストール。
<img width="680" alt="スクリーンショット 2020-06-09 16.55.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136271/4cdcc174-e749-9f8c-27ac-d2e5324282d1.png">

#rootパスワード設定
初期状態ではrootがパスワード保護されていない。
以下でパスワードを設定

```
$ sudo passwd root
```

#IPアドレス固定
dhcpcd.confを開いて追記。

```
$ sudo nano /etc/dhcpcd.conf
```

```dhcpcd.conf
interface wlan0
static ip_address=[IPアドレス]/[プレフィックス長]
static routers=[DNSアドレス]
```
その後再起動

```
$ sudo reboot
```

#SSH接続の設定
SSHログインには以下の2種類がある。

- パスワード認証
- 公開鍵認証

パスワード認証はリスキーなので公開鍵認証へ変更。
ラズパイの初期状態でSSHを有効にするとパスワード認証になるので公開鍵認証へと変更する。

##秘密鍵と公開鍵の作成
以下のコマンドをラズパイ、クライアント側療法で入力し、秘密鍵と公開鍵のペアを作成

```
$ ssh-keygen -t rsa
```
ここからラズパイ側とクライアント側で操作が異なる。
###ラズパイ側の操作
上記コマンドで秘密鍵と公開鍵が`~/.ssh/`に作成される。
公開鍵は初期状態では`~/.ssh/id_rsa.pub`に配置される。
今回は`authorized_keys`がないので、`id_rsa.pub`を`authorized_keys`にリネーム

```
$ mv id_rsa.pub authorized_keys
```
といっても最初から600になっていた。

###クライアント側での操作
公開鍵をラズパイへ送信

```
$ scp -P 22 ~/.ssh/id_rsa.pub ラズパイのユーザ名@アドレス:/home/username/Documents  
```
もしくはクリップボードに以下コマンドでコピーして`authorized_key`に追記

```bash
pbcopy < ~/.ssh/id_rsa.pub
```

###ラズパイ側での操作
クライアントから送信された`id_rsa.pub`を`authorized_keys`に追記

```
$ cat ~/Documents/id_rsa.pub >> ~/.ssh/authorized_keys
$ rm id_rsa.pub
```
authorized_keys`のパーミッションを設定。

```
$ chmod 600　~/.ssh/authorized_keys
```
今回は最初から600になっていた。

##ラズパイ側でSSHを有効化
設定→Raspberry Piの設定→インターフェース
より、SSHを有効化

もしくはターミナルから

```
$ sudo raspi-config
```
のあと、
`Interfacing Options→SSH`からでも設定できる。

##パスワード認証でのSSH接続の無効化設定

```
$ sudo vi /etc/ssh/sshd_config
```
sshd_configを開き下記を変更。

```
#PasswordAuthentication yes
PasswordAuthentication no
```

#VNC接続

###tightvncserverをインストール

```
$ sudo apt-get install tightvncserver
```
###tightvncserver起動

```
$ vncserver
```
起動後にパスワードが求められる。
途中の`Would you like to enter a view-only password (y/n)?`は`NO`


###実際の接続
MacでFinderを開いて`command+k`を入力し、以下を入力

```
vnc://[ラズパイのIPアドレス]:5901
```
####オプション

|オプション|意味|
|---|---|
|-geometry|解像度|
|-depth|ビットカラー|

例

```
$ vncserver -geometry 1280x800 -depth 24 :1
```
ドメイン・DNSとは

##はじめに
AWS学習の際にVPCを触る機会があり、改めてドメイン・DNSについて自分なりに整理したのでその備忘録。

### ドメインとは

IPアドレスにひもづくインターネット上のネットワークを特定する文字列。

#### ドメインの構成

![](https://i.imgur.com/qu3nyNb.png)

出典：https://www.asobou.co.jp/blog/web/domain

#### 独自ドメイン

ドメイン登録サービスで取得できるオリジナルドメインのこと。

#### サブドメイン

ドメインをさらに分割して利用できるドメイン。

### ホストとは

ネットワーク上のコンピュータを特定する文字列。

### FQDN(Fully Qualified Domain Name)とは

ホスト名とドメイン名をつなげて記述した文字列で、インターネット上の特定のコンピュータを特定する文字列。

#### URLとは

プロトコル + FQDN + ファイルの置き場所

図にすると

![スクリーンショット 2020-06-09 20.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409259/f2f7390b-575f-016d-cd74-85d712086e4c.png)

出典：https://itmanabi.com/fqdn-url/



## DNS(Domain Name System)とは

インターネットに接続されているすべてのコンピュータのもつ固有のIPアドレスと、そのIPアドレスを人間が覚えやすい名前で扱うための文字列であるドメイン名の対応づけを行うシステムのこと。
システムを提供するサーバーをDNSサーバーという。

### 名前解決

DNSサーバを利用して、ドメイン名から IPアドレス を調べ出したり(正引き)、IPアドレスからドメイン名を調べ出したり(逆引き)することを名前解決という。

### DNSサーバの種類

| DNSサーバーの種類 | 概要 |
| -------- | -------- |
| DNSコンテンツサーバ |自分の管理している情報を教えてあげるのがお仕事のDNSサーバ |
| DNSキャッシュサーバ<br>(フルサービスリゾルバ) |他のDNSサーバに答えを教えてもらいに行くDNSサーバ。 <br> DNSキャッシュサーバは、答えが分からないときは、他のDNSサーバに応答しに行く。<br> 一度確認したIPとドメインの対応を、一定期間自身の中にキャッシュすることにより、同じドメインに対して再度ネームサーバに確認しにいくという手順を省く。<br>どれくらいの時間キャッシュをさせておくかを定めた時間をTTL(Time To Live)と呼ぶ|

### ゾーンファイル

ドメインとIPの対応表のこと。
対応表のなかに「◯◯のIPアドレスは☓☓」「◯◯のメールサーバは☓☓」といった詳細情報を設定していくことになる。

### DNSレコードとDNSレコードの種類について

ゾーンファイル内の各対応の設定内容のこと。


| DNSレコードの種類 | 概要 |
| -------- | -------- |
| SOAレコード | ゾーンファイルの取り扱い設定について記述してあるレコード|
| NSレコード | 管理を委託しているDNSサーバ名称が記述されているレコード|
| Aレコード| ドメイン名に対応するIPアドレス(IPv4形式)記述されているレコード |
|PRTレコード|IPアドレスに対応するドメイン名レコード記述されている（Aレコードの逆）|
| MXレコード|ドメイン宛のメールの配送先メールサーバが記述されているレコード|
|CNAMEレコード|ドメイン名に付けたエイリアス(別名)が記述されているレコード|
| TXTレコード|コメントが記述されているレコード|

##参考記事

[ドメイン名とホスト名の違いとは？FQDNとの違いも解説します](https://t-tel.net/domain/092/)

[FQDN？URL？ドメイン名？違いは？](https://itmanabi.com/fqdn-url/)
Windows 10 + Python3 + selenium + msedgedriver で headless edge(Chromium) を試してみる

# 目的
Windows 10 + Python3 + selenium + msedgedriver で headless edge(Chromium) を試してみる
[Windows10 + Python3 + Selenium4でChromeとEdgeをheadlessで起動してみる　はこちら](https://qiita.com/tabizou/items/1a7789d88ba853cd6081)
## WebDriverのインストール
ヘルプとフィードバック -> Microsoft Edge よりEdgeのバージョンをチェックする
今日時点では バージョン 83.0.478.45 (公式ビルド) (64 ビット)
[WebDriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)よりバージョンに合わせて edgedriver_win64.zip をダウンロード後
適当なフォルダに解凍する -> C:\Dev\Tools\edgedriver_win64
上記のフォルダを環境変数に登録後動作を確認する
<pre>
\> msedgedriver
Starting MSEdgeDriver 83.0.478.45 (fa71536bbfc4d8c41db9e9b61b8b5f71c6c64f0c) on port 9515
Only local connections are allowed.
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping MSEdgeDriver safe.
MSEdgeDriver was started successfully.
</pre>
## python用のパッケージをインストールする
※seleniumのバージョン指定は必要ないようだ(現在==3.141.0がインストールされている)
<pre>
\> pip3 install msedge-selenium-tools selenium
\> pip3 list | grep selenium
selenium            3.141.0
</pre>

# サンプルコード

```python
import time
from msedge.selenium_tools import Edge, EdgeOptions

# Launch Microsoft Edge (Chromium)
options = EdgeOptions()
options.use_chromium = True
options.binary_location = r"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
options.add_argument("headless")        #Chrome と合わせて欲しいぞ・・・
options.add_argument("disable-gpu")
driver = Edge(options = options)

driver.get('https://www.google.co.jp/')

html = driver.page_source
print(html)

# time.sleep(5)
print('done')
driver.quit()
```
# 参考にしたサイトはこちら
[テストオートメーションに WebDriver (Chromium) を使用する](https://docs.microsoft.com/ja-jp/microsoft-edge/webdriver-chromium?tabs=python)
[microsoft/edge-selenium-tools](https://github.com/microsoft/edge-selenium-tools)
[WebDriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/#downloads)
[GNU utilities for Win32](http://unxutils.sourceforge.net/)
[Selenium Python(ABC順)](https://www.seleniumqref.com/api/webdriver_abc_python.html)
IPアドレスとは？

##はじめに

AWS学習の際にVPCを触る機会があり、改めてIPアドレスについて自分なりに整理したのでその備忘録。

## グローバルIPとプライベートIP （ローカルIP）

ネットワーク上の住所。IPアドレスはローカルIPアドレス、グローバルIPアドレスに分けられる。

### グローバルIP

インターネットに接続するための外部向けのアドレスをグローバルIPアドレス。

### プライベートIP （ローカルIP）

特定のエリア内（プライベート）で使用するアドレスをプライベートIPアドレスといい、一つのグローバルアドレスを変換し、組織内でプライベートIPアドレスを使用する使われ方がされている。

## IPv4とIPv6

IPv4はインターネットに直接接続できるコンピュータの数。IPv6はIPv4の次世代プロトコル。IPv4に比べてIPv6は接続数がほぼ無限。また、IPはコンピュータ上では2進数（01のみの数字）で使用されるが、人間には理解しづらいため、一般的にIPv4は32bitを8bitずつ『.』で4分割し、分割した数値を10進数で表記し、IPv6アドレスは、128bitを16bitずつ『:』で8分割し、分割した数値を『16進数』で表記している。

IPv4 例：
```
192.168.0.100
```

IPv6 例：
```
fd00:12:11af:1:21b:8bff:fe9b:b3c8
```

## サブネットマスク
IPアドレスはネットワークアドレスとホストアドレスに分けられている。
ネットワークアドレスは、使用しているネットワーク自体を表し、ホストアドレスはホスト(コンピュータ)が持つIPアドレスを表す。
IPアドレスはネットワーク部とホスト部の切れ目が定まっていないため、どこからどこまでがネットワーク部で、ホスト部なのかわからない。サブネットマスクはIPアドレスのネットワークアドレスとホストアドレスを区別するためのもので任意のIPアドレスとサブネットマスクを比較し、２進数に変換したときにサブネットマスク側の1までがIPアドレスのネットワーク部を表す。

※サンプル
![サブネットマスク](https://trello-attachments.s3.amazonaws.com/5d706d390c3452200d252f46/5d7ee07cfaee1b8d7f274967/4c1d6eed3b6861f86131a394cbb8186b/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88_2019-09-16_16.14.17.png)
※出典：http://www.runsurunet.com/2017/10/11/%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E3%83%9E%E3%82%B9%E3%82%AF%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B/


### サブネットマスクの表記法

サブネットマスクの表記法にはIPアドレスと別にサブネットマスクをそのまま記述する方法とCIDR表記法がある。
CIDR表記が一般的。

#### CIDR表記について
CIDRはサイダーと読む。IPアドレスの後ろにスラッシュ記号を書き、その後ろにネットワーク部のIPアドレスを2進数化した際の桁数を表記する方法。
IPアドレスを２進数にした際の左からの桁数を/「スラッシュ」以降の桁数で表している。

アドレス範囲計算ツール

https://hogehoge.tk/ip/

#### 例：
```
172.20.100.0/24 
```

↓

#### ２進数

```
IP
10101100.00010100.01100100.00000000

サブネットマスク
/1111111.11111111.11111111.00000000
```

サブネットマスクの「00000000」にあたるIPアドレス部分がホストアドレスになり、1 ~ 254までつかえる。

#### ネットワーク識別IDとなるIPアドレス

```
172. 20.100. 0

```

#### サブネット内の全ホストに対して、一斉通知（ブロードキャスト）するためのアドレス

```
172. 20.103.255
```

#### 例でつかえるアドレスの範囲

0と255はつかえないので実質使えるホストは以下の範囲になる。

```
172. 20.100.1 ～ 172. 20.100.254

```

### 推奨されているプライベートIPアドレス空間

CIDRは以下のプライベートIPアドレスの範囲から指定する。
プライベートIPアドレスから外れるCIDRブロックも利用できますが、プライベートIPアドレスの利用が推奨されている。

```
10.0.0.0/8
10.0.0.0～10.255.255.255

172.16.0.0/16
172.16.0.0～172.31.255.255

192.168.0.0/24
192.168.0.0～192.168.255.255
```

AWSではVPCは

```
10.0.0.0/16

10.0.0.0〜10.0.255.255
```

AWSのサブネットは

```
10.0.1.0/24
10.0.1.0〜10.0.1.255
```

が推奨されている。

##参考記事

[サブネットマスクを理解するPart1　基礎からのネットワーク⑥](http://www.runsurunet.com/2017/10/11/%E3%82%B5%E3%83%96%E3%83%8D%E3%83%83%E3%83%88%E3%83%9E%E3%82%B9%E3%82%AF%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B/)

[IPアドレスとは？をわかりやすく解説します](https://www.kagoya.jp/howto/network/ipaddress/)
最適化しないとコンパイルが通らないコード

私の環境(Windows 7, MinGW64 g++ 8.1.0)で-O1, -O2ではコンパイルが通るのに-O0では通らないコードを、見つけてしまいました(エラーメッセージ後述)
ところでいい加減 Windows 7 使うのやめた方がいい ? 私もそう思います

```c++
#include <iostream>

struct A {
	void fuga() const {
		std::cerr << "fuga~~" << std::endl;
	}
};
struct B {
	static const A a;
	void hoge() {
		a.fuga();
	}
};
int main() {
	B a;
	a.hoge();
	return 0;
}

```

-O0でのエラーメッセージ

```
C:\...\cc15Jtni.o:b.cpp:(.rdata$.refptr._ZN1B1aE[.refptr._ZN1B1aE]+0x0): undefined reference to `B::a'
collect2.exe: error: ld returned 1 exit status
```

本当はダメだけど最適化によってリンク直前のコードにおける`static const A a`への参照が消え失せたのかな
「最適化オプション変えたら***が起きた」シリーズとして...
GRUBの起動順序変更

##環境  
windows / ubuntuのデュアルブート
デフォルトはブートの順番は
Ubuntu
↓
windowsの順

これを
デフォルトブートをwindowsに変更する。

## やり方

以下のファイルを編集
/etc/default/grub

```
GRUB_DEFAULT=0
↓
GRUB_DEFAULT=2
```

反映  

```
sudo update-grub
```

参考: https://qiita.com/OldS9l/items/dc84f8912fc3d86f646a
Linux エラー　

#予期しないトークン「elif」に近い構文エラー
```Linux:エラー内容
./ex6.sh: line 38: syntax error near unexpected token `elif'
./ex6.sh: line 38: `    elif [ $var = 'exit' ];'
```

#解決策
elif 周辺に全角スペースが入っっていたり、構文的に誤りがあったりする。
自分は　elifの前に記述していたelif 構文のfi が抜けていた💦

#まとめ
こちらのエラーは基本的にケアレスミスなので頭をリセットして
誤りのある構文を見つけましょう
【Rails】日本人最長の苗字 （バリデーション）

# 日本人最長の苗字（バリデーション）

### 目次
1. 日本で最長の苗字を調べるにあたって
2. 日本人最長の苗字
3. バリデーション設定

## 1. 日本で最長の苗字を調べるにあたって
カスタマー用のお問い合わせフォームの作成していました。
フロント側の実装が完了し、バックエンドでのバリデーションの実装に取り掛かりました。
お問い合わせフォームの項目に必ずしもある **苗字・名前** のバリデーションの最大値を決める際に手が止まりました..
**苗字・名前** の最大値なら15文字くらいで大丈夫かな？（なんかモヤモヤする）


..ていうか調べれば、解決できそう!
日本人最長の**苗字・名前** について調べました。


## 2. 日本人最長の苗字
日本人最長の **苗字・名前** について調べたところ、
苗字の最長は **5文字** （漢字）、読みでは **8文字** あるということがわかりました。

####下記のサイトを参考
https://name.sijisuru.com/Columns/longname


## 3. バリデーション設定
苗字の最長がわかったので、以下のようにバリデーションを設定しました。
（名前の最長は変動するため、今回は余裕を持った値を設定することにしました。）

```app/models/contact.rb
class User < ApplicationRecord
  validates :name_sei, presence: true, length: { maximum: 5 }
  validates :name_mei, presence: true, length: { maximum: 10 }
  validates :name_sei_kana, presence: true, length: { maximum: 8 }
  validates :name_mei_kana, presence: true, length: { maximum: 20 }
end
```

今まで何となくバリデーション値を設定していましたが、このような体験をして、バリデーションの値の決め方を学びました。
以上でバリデーションの設定となります。
RailsでTailwind CSSを使用する

# はじめに
Rails に Tailwind CSS を導入する方法です。

# 環境
- rails : 6.0.3.1
- webpakcer : 4.2.2
- tailwindcss : 1.4.6

## Tailwind CSS のインストール

```bash:Terminal
$ yarn add tailwindcss
```

## tailwind.config.js の作成

```bash:Terminal
$ yarn tailwindcss init
```

## Tailwind CSS を読み込む CSS ファイルを作成

```css:app/javascript/css/tailwindcss.css
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
```

```javascript:app/javascript/packs/application.js
// 追加
import '../css/tailwindcss.css';
```

## postcss.config.js の修正

```javascript:postcss.config.js
module.exports = {
  plugins: [
    // ...
    // 追加
    require('tailwindcss'),
    require('autoprefixer'),
    // ...
  ]
}
```


## 動作確認
```bash:Terminal
$ bin/rails g controller home show
```

```ruby:config/routes.rb
Rails.application.routes.draw do
  root 'home#show'
end
```

```erb:app/views/home/show.html.erb
<!-- 公式のサンプル -->
<!-- https://tailwindcss.com/docs/utility-first#overview -->

<div class="max-w-sm mx-auto bg-white shadow-lg rounded-lg overflow-hidden">
  <div class="sm:flex sm:items-center px-6 py-4">
    <img class="block mx-auto sm:mx-0 sm:flex-shrink-0 h-16 sm:h-24 rounded-full" src="https://randomuser.me/api/portraits/women/17.jpg" alt="Woman's Face">
    <div class="mt-4 sm:mt-0 sm:ml-4 text-center sm:text-left">
      <p class="text-xl leading-tight">Erin Lindford</p>
      <p class="text-sm leading-tight text-gray-600">Customer Support Specialist</p>
      <div class="mt-4">
        <button class="text-purple-500 hover:text-white hover:bg-purple-500 border border-purple-500 text-xs font-semibold rounded-full px-4 py-1 leading-normal">Message</button>
      </div>
    </div>
  </div>
</div>
```

http://localhost:3000/ にアクセス

下記のようにスタイルが適用されています。

<img width="750" alt="TailwindCSS適用.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197676/ddca7602-b30b-b221-3fed-18b643f7f698.png">


# 参考文献
- [Installation - Tailwind CSS ](https://tailwindcss.com/docs/installation/)
- [Rails 6 and Tailwind CSS via Webpacker— Getting Started](https://medium.com/@davidteren/rails-6-and-tailwindcss-getting-started-42ba59e45393)
RESTful

#この記事で説明する事項
WEBの世界では，「RESTful」と呼ばれるサービスが存在する．このRESTfulとその周辺の知識について説明する．
#RESTfulとは
WEBアプリケーションというのは，いくつかのWEBページがあり，そこにアクセスするとアプリケーションの画面が表示され，そこで様々な作業を行うような仕組みになっている，画面には，各種の表示やインターフェースとなるGUI部品が表示され，それらを操作する，
ところが，WEBの世界には，こうした「画面に表示されない部分」を持たないものもある．「WEBサービス」と呼ばれるものがそれに当たる．これらは，サーバにアクセスして必要な情報を取得したり，情報を送って保存したりできるが，一般的にみられるような画面表示は持っていない．
こうしたWEBサービスは，利用者が自分でWEBブラウザからアクセスして利用するにではなく，他のプログラムがアクセスして利用するためのものと考えても良い．こうしたWEBサービスの分野でよく耳にするのがRESTやRESTfulと言った言葉である．

##REpresentation State Transfer
RESTというのは，「REpresentation State Transfer」の略で，分散型システムを構築するための考え方である，インターネットのあちこちにプログラムが分散して存在し，それらが相互にやりとりをしながら動くようなシステムを考えた時，どういう仕組みにしたらいいか，その答えの一つがRESTである．

RESTは，HTTPのメソッドを使って決まったルールに従ったアドレスにアクセスすることで，必要な情報を取得したり．情報を保存したりできるようにする．HTTPなので，他のサーバからアクセスして情報を取り出したりできる．

このRESTという考え方に基づいて設計されているプログラムをRESTfulである，と表現する．RESTfulなサービスは，情報の取得や送信など基本的な操作の方法が統一されているため，他のプログラムから簡単にアクセスしてサービスを利用できる．

#RESTの考え方
##リソース指向
以下のような考え方をするというもの．
・WEB上に存在する全ての情報はリソースである．
・リソースは識別器（URI）を持つ
・URIを用いることで，プログラムはリソースが表現する情報にアクセスできる．（ちなみにURIはリソースを示すべきなので，名詞のみで構成されることが原則）
・ディレクトリ構造に似たURIを定義

##統一インタフェース
全てののWEBシステムでURIとHTTPメソッド（GET，POSTなど）という同じインタフェースを利用する，このようなスタイルのことを統一インタフェースと呼ぶ．

##ステートレス
リクエストに処理に必要な全ての情報を持つというもの．ステートとは「状態」を意味する．ステートフルとは違い，自己完結型である．サーバ資源をすぐに解放できるため，利用者や負荷の増大に応じて，性能や機能を向上させられる．ステートレスであれば，各要求で別々のサーバがクライアントのリクエストに応答（レスポンス）することが可能である．


#RESTのメリット
・アプリケーション中のリソースが，URIで示せる
アドレス欄に入力すれば，そのリソースを参照できる．

・ステートレスにすることで，スケーラビリティが向上
将来想定されるシステムの規模の増大に対応可能な設計．RESTの一番のメリットとされる部分である．

・統一インタフェース
シンプルで一貫性のある設計．リソースへの操作はCRUDの４種類という制約．
メソッドを限定することによりプロトコルがシンプルに保たれる．

・標準なデータフォーマット（XML，JSON）を扱うことで，他のシステムとの連携が容易になる．

・RESTに基づいたWEBアプリでは，インタフェースが固定されているため，互換性の問題が発生しない．


#まとめ
REST原則に基づいてシステムを構築することで，色々とメリットがあるよ．だからREST原則に則ってシステムを構築しRESTfulなサービスを構築しようね．て感じでいいかな．
Gitの流れ(pushまで)

#Gitの大まかな流れ(pushまで)#
今回は実際にGit hubを使っていきます。

##リモートリポジトリの新規追加##

git hubにプッシュするためにまずリモートリポジトリの新規追加をしていきます。

まず自分のページに行って**Repositories**という項目があるのでクリックして**右側の緑のNew**というボタンがあるのでクリックしてください。<img width="678" alt="スクリーンショット 2020-06-09 17.04.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612696/26b522d5-5af8-3bec-96f9-1958ba90b32f.png">

↑の様なページまで行けたら**Repository name**に好きな名前を記入してください。
それ以外は変更を加える必要はないです。

そして**create**を押したらリモートリポジトリ作成完了です！
次に**Code**というページに飛ぶと思います。
そこで**…or push an existing repository from the command line**という欄があります。
そこの**git remote add origin〜〜〜**とあるのでコピ-してターミナルに戻ります。

```terminal
git remote add origin  ~~URL
```

もしくはoriginとは違う名前で登録した場合は
```terminal
git remote add self-name  ~~URL
```

基本的な所は同じです笑

これを入力することで今度からorigin(self-name)でアクセスできる様になりました。

###git push###

そしていよいよ最後まで来ました。**push**していきましょう！

```terminal
git push -u origin(self-name) master
```

このように入力することでGithubにアップロードできたと思います。
各自で確認してみましょう。

ここで今回のコマンドについて説明します。
この**-u**とオプションを付けることでこの(origin master)で再度pushする際に**git pushと入力するだけでよくなります**。

また今回ブランチ名をmasterとしていますが、基本的に何もいじってなければ最初は気にしなくて大丈夫です。

第一回はこちらです
[git commitまでの流れ]https://qiita.com/juki1007/items/e45f8f753a01d9788015
標準入力をコード中に記述する

例えば標準入力のテストをしたい時など、毎回入力するのも面倒だし、かといって外部ファイル読み込むのもゴミが増えるだけ
なるべく元のコードを汚さずにテストしたい場合、input()をオーバーライドするのがよさそう

以下のようにテストしたい標準入力の中身を書いておいて、

```python
stdin_test = """1 2
3 4
5 6
"""
```

ジェネレータでinput()をオーバーライドする

```python
def inp(t):
    from io import StringIO
    for i in StringIO(t):
        yield i
input = inp(stdin_test).__next__
```

使用例

```python
a = [list(map(int, input().split())) for i in range(3)]
print(a)

>>> [[1, 2], [3, 4], [5, 6]]
```

もっといいやり方がある気がしないでもない
おわり
laravel で削除機能

#laravel削除機能
laravelで削除機能を実装しようと動画や記事を参考にしたら、ほとんでjavascript経由でコントローラーに値を渡していたので、それ以外の方法でやりたいと思いました。railsを学習していたとき、jsを経由せずにlinkを作成してコントローラーに渡せていたので、laravelでもjsを経由せずにできるのではないかと思いました。

##結論
httpコントローラーをgetにすれば、urlからコントローラーのdeleteメソッドに渡すことができます。

##ハマったこと
最初は以下のようにresourceを使うとcrudのルーティングを自動で設定できます。
しかし、destroyメソッドのhttpメソッドにはdeleteが与えられているので、これをgetに変えてあげる必要があります。
これに気がつかずかなり時間を使ってしまいました。

```php:web.php
Route::resource('test',TestController);
```
他のアプリへの共有（SNS共有など） Android[Kotlin]

めっしーです。[Twitterはこちらです](https://twitter.com/175Atsu175)

Androidアプリでテキストや画像を他のアプリに共有する際の手順について。
ツイッターやインスタに画像や文字の共有ができます。（SNS共有）

# 共有方法
Android Sharesheetを使います


## Android Sharesheet について
アプリの外部へのコンテンツの送信、別ユーザーへの直接のコンテンツの送信、またはその両方のために設計されています。たとえば、友人との URL の共有などです。


## テキスト共有
```sample.kt
val sendIntent: Intent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_TEXT, "他のアプリに共有したいテキスト書く")
            type = "text/plain"
        }

        val shareIntent = Intent.createChooser(sendIntent, null)
        startActivity(shareIntent)
```

## 画像共有
画像をuriにして渡します。

```sample.kt
val shareIntent: Intent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_STREAM, uri)
            type = "image/jpeg"
        }
        startActivity(Intent.createChooser(shareIntent, "title"))
```


# 参考
詳しいことはここに
[他のアプリへの単純なデータの送信](https://developer.android.com/training/sharing/send?hl=ja#send-binary-content)
Rails アプリ起動時のMysqlエラー を解消 (Mysql2::Error::ConnectionError ・ Can't connect to local MySQL server through socket '/tmp/mysql.sock')

# 何をしようとして起きたエラーか？
自分で開発した Ruby on Rails のアプリを異なる開発環境で GitHubからソースコードをコピー（git clone)し、起動させようとしたところ Mysql エラーが起きた。

# エラー内容
git clone した後、`rails s` でアプリを起動しようと試みる。
しかし、このようなエラーがでる。↓↓
<img width="1299" alt="スクリーンショット 2020-06-09 18.26.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/05fad4dd-7115-732d-23cd-82bdf60da851.png">

「DBを作成してないからだ！」と思い、

    rails db:create

を実行するも `rails s` と同じような内容でエラー↓↓
<img width="1368" alt="スクリーンショット 2020-06-09 18.28.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/57922332-59a0-e3c1-c575-d22c7525f70d.png">



# 結論！(エラーの原因)
### - 原因1
`/tmp/mysql.sock` のファイルが無かった
### - 原因2
`config/database.yml` 内で `socket`の指定先が違っていた

以下で解決した方法を解説↓↓
# 解決のために行ったこと2つ

### ①原因1について
`/tmp/mysql.sock` ファイルが無かった原因は `.gitignore`に記述してあるファイルのため Git 管理外のファイルとなっており、GitHub に無かったようである。

そこで、エラー文で指摘されている箇所ファイルを作成する。
下記のコマンドを実行

    $ sudo touch /tmp/mysql.sock

もう一度 `rails db:create` を実行してみるがエラー↓↓

<img width="777" alt="スクリーンショット 2020-06-09 18.36.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621162/2af059d7-e5cf-4dd6-1214-925c72b65f6d.png">

同様のようなエラーに見えるが、エラー文の最後が (2) →　(13) に変わっている。

### ②原因2について
調べてみるとどうやら今度は 
`config/database.yml` 内で `socket`の指定先が違っていたよう

```config/database.yml
    default: &default
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
      username: root
      password:
      socket: /tmp/mysql.sock # ←ここの部分
```
このファイルの `/tmp/mysql.sock`（６行目） ここが間違っているようだったので


```config/database.yml
      socket: /tmp/mysql.sock
```

この部分を

```config/database.yml
      socket: /var/lib/mysql/mysql.sock
```
このような記述に修正すると 解決！

その後、
`rails db:create`　→　`rails db:migrate`　→　`rails s` でアプリ起動成功！
# 参考にした資料
https://qiita.com/fujitora/items/d341c52706d1954cae28
https://qiita.com/carotene4035/items/e00076fe3990b9178cc0
# 最後に
色々調べて、闘っていたら何時間も消費してしまいました。自分の場合は上記のような方法で解決しましたが、DBや開発環境周りの知識が浅く、正直理解できていない部分がほとんどです。
同じよなエラーに遭遇した方のヒント、参考になれば幸いです。

間違い等々あればご指摘ください！
AtCoder参加したったー（ABC169編）

こんにちは！バイオインフォマティクス系オタク修士学生のroadricefieldです！前回から死ぬほど間が空いていますがABC169に参加したのでその参戦記をば.  

# [A問題](https://atcoder.jp/contests/abc169/tasks/abc169_a)  

3桁までの掛け算は現行の教育指導要領では小学3年生までに習います.  

私の解答  

```python:A.py
A,B = map(int, input().split())
print(A*B)
```  

# [B問題](https://atcoder.jp/contests/abc169/tasks/abc169_b)  

一回書いてあるとおりに実装してみました.  

```python:B.py  

N = int(input())
A = list(map(int, input().split()))

ans = 1
for i in range(N):
    ans *= A[i]

if ans <= 1e18: print(ans)
else: print(-1)
```  

結果は`TLE`. 数字も大きいですし, ですよねといった感じです.  

入力に0があればその瞬間答えは0なので最初に入力に0がないかを判定してあれば掛け算を行わずに`0`を出力して終了, 計算中も途中で10<sup>18</sup>を超えればそこでbreakして`-1`を出力するようにすれば速くなるだろうと考え以下のように書きました.  

```python:B.py  

N = int(input())
A = list(map(int, input().split()))

ans = 1
flg = True

if 0 in A: print(0)
else:
    for i in range(N):
        ans *= A[i]
        if ans > 1e18:
            flg = False
            break

    if flg: print(ans)
    else: print(-1)
```  

ちなみにこれで計算時間が最大`2206 ms`から`56 ms`まで落ちました. ちょっとの工夫でかなり速くなるものですね.  

# [C問題](https://atcoder.jp/contests/abc169/tasks/abc169_c)  

浮動小数点の話なのは分かっていたのですが色々やってもうまく行きませんでした...情報技術の勉強が足りなさすぎる...  

# [D問題](https://atcoder.jp/contests/abc169/tasks/abc169_d)  

この問題ではC++を使用しました. 以下のように操作することで操作数を最大にできます.  

まず, 与えられた*N*を素因数分解します.

```math  

N = a^{6} \times b^{4} \times c^{3}  

```  

z = a<sup>1</sup>とします. NをN/zに置き換えます. 同じzは選べないので次はa<sup>1</sup>の次に小さいa<sup>2</sup>をzに選びます. NをN/zに置き換えます. ここまでで  

```math  

N = a^{3} \times b^{4} \times c^{3}  

```  

となりました. まだz=a<sup>3</sup>で割れます. NをN/zに置き換えます. これで  

```math  

N = b^{4} \times c^{3}  

```

となりました. 次はz=b<sup>1</sup>で割ります...  
  

というように素因数の1乗, 2乗, 3乗で割っていくことを繰り返していき, 途中でその素因数が*N*の中で尽きたら次の素因数の1乗, 2乗, 3乗で割っていくことを繰り返せばいいわけです.  

私の解答  

```cpp:D.cpp

#include<bits/stdc++.h>
using namespace std;

vector<long long> pri_fac(long long N){
    vector<long long> yakusu;
    long long now = 0; 
    long long a = 2;
        while(N >= a*a){
            if(N%a == 0){
                yakusu.push_back(a);
                 N /= a;
            }else{
                a++;
            }
        } 
    if(N != 1) yakusu.push_back(N);
    return yakusu;
}

int main(){
    long long N;
    cin >> N;

    vector<long long> vec_all;
    vec_all = pri_fac(N);

    if(N == 1) cout << 0 << endl;
    else if(vec_all.size() == 1) cout << 1 << endl;
    else{
        long long now;
        now = vec_all[0];
        vector<long long> unique_count;
        unique_count.push_back(1);
        for(long long i=1;i<vec_all.size();i++){
            if(vec_all[i] != now) unique_count.push_back(1);
            else unique_count[unique_count.size()-1]++;
            now = vec_all[i];
        }

        long long ans = 0;

        for(long long i=0;i<unique_count.size();i++){
            long long j = 1;
            while(j <= unique_count[i]){
                ans++;
                unique_count[i] -= j;
                j++;
            } 
        }

        cout << ans << endl;
    }
    return 0;
}
```  

*N*が1だったときや素数だったときはバグって欲しくなかったので最初に例外処理をしています. `pri_fac`は素因数分解を行なってひたすら素因数をvectorにpush_backする関数です.
Zoomで会話+自動字幕生成

公開し忘れてコロナの時期を過ぎ去ってしまいましたが、せっかくなので。




落合陽一氏の以下のツイートがバズってましたが、自分も仕事柄Zoomを使っていて実験的に再現できたので記録しておきます。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/xdiversity?src=hash&amp;ref_src=twsrc%5Etfw">#xdiversity</a> <a href="https://twitter.com/xdiversity_org?ref_src=twsrc%5Etfw">@xdiversity_org</a> <a href="https://twitter.com/hashtag/stayhometokyo?src=hash&amp;ref_src=twsrc%5Etfw">#stayhometokyo</a> <a href="https://twitter.com/hashtag/%E9%9F%B3%E5%A3%B0%E6%96%87%E5%AD%97%E5%A4%89%E6%8F%9B?src=hash&amp;ref_src=twsrc%5Etfw">#音声文字変換</a> <a href="https://t.co/VNKQcZONsR">pic.twitter.com/VNKQcZONsR</a></p>&mdash; 落合陽一 (@ochyai) <a href="https://twitter.com/ochyai/status/1260610691041357825?ref_src=twsrc%5Etfw">May 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#使用ツール一覧

自分の環境は以下で実現できました。
![zoom環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585369/106f48f9-1b26-0c62-0ff0-1f5cf03330a1.png)

それぞれのアプリ・ソフトの解説をすると

「音声文字変換アプリ」：音声を文字変換できます。(そのまま)

「Vysor」：USB接続したAndroidの画面をPC上に表示することができます。

「OBS」：PCの画面を仮想カメラとして認識させることができます。

言い換えると、
①スマホのアプリで音声→文字に変換
②Vysorで文字に変換したスマホ画面をPC上でも見れるように
③OBSでフロントカメラ(自分の顔映すカメラ)と文字字幕を合成させて、その画面を仮想カメラとして認識させる
④Web会議ソフトでその仮想カメラを選択すれば、他ユーザからも字幕付きの自分の姿が見られる
といった感じです。

#各ツール使用法

基本的に以下サイトらを参考にしました。
https://note.com/takashiokashi/n/n4482f008afbf


Vysor使用法：https://tonari-it.com/vysor-android-app-remote-mirrorring/

OBS使用法：https://level69.net/archives/26918




※OBS使用時の字幕合成に「クロマキー合成」を紹介してるところもありますが「カラーキー合成」の方が鮮明に映ります。
https://level69.net/archives/27503


#注意事項
・フロントカメラ使用時Zoomだと左右反転する
(対応法は上記OBS使用法に記載されてます)

・バッテリー・発熱問題
自分はノートPCで行っているため、デフォルト設定で3時間ほど会議をして終わるころには30%～40%くらいまでバッテリーがなくなってます。そのうえ、スマホをUSB接続をしているので電気をスマホ側に持ってかれます。PCかスマホ側に電力供給をオフにする機能があれば良いのですが......見つからず。
controllerで引数を反対にすると起るエラー

##引数を反対にすると起るエラーについて
このようにしている時、


```php:controller.php
    public function delete(Request $request,File $file,Customer $customer)
    {
        $file->delete();
        return redirect()->route('customers.show',compact('customer'));
    }

```
deleteを実行すると以下のようにブラウザでエラーが返されました。

```
Argument 2 passed to App\Http\Controllers\FilesController::delete() must be an instance of App\File, instance of App\Customer given
```

ルートはcustomerが先なので、コントローラーの引数もcustomerを先にしてあげる必要がありました。

```php:web.php
Route::get('/customers/{customer}/files/{file}', 'FilesController@delete')->name('customer.file.delete');
```

次のようにコントローラーの引数をルートの順番に合わせる必要がありました。

```php:controller
public function delete(Request $request,Customer $customer,File $file)
    {
        $file->delete();
        return redirect()->route('customers.show',compact('customer'));
    }
```

基本的な間違いです
コードで解決するSEO対策

## この内容について
この内容は、こんな感じのコードを書けばSEO対策になる
ものをまとめたものです。

## SEO対策とは
SEOは**S**earch **E**ngine **O**ptimizationの略で、
Googleなどの検索結果を上位にするための対策のこと。

## SEO対策 必須
### h1タグは1つ
Webページ1つにつきh1タグは1つにします。

### h2タグにはキーワード
h2タグをWebページに使うことがあると思いますが、使うタイミングとしては
そのページのキーワードを含めたものにh2タグをつけるようにしましょう。
それ以外の見出しはh3以下を使います。

また今では推奨となっていませんが、私の感覚では今でもメタキーワード
は入れた方が検索エンジンの評価は良いです。

```html:HTML例
<meta name="keywords" content="SEO対策,００,００">
```

### ディスクリプション
Webページの概要を記述します。
概要は、Googleの検索結果に表示され、ユーザはそれを見てサイトを訪問するか決めることもあるので、
より関心を持たせるよう記述しましょう。

```html:HTML例
<meta name="description" content="SEO対策を知っていますか？SEO対策は実は００をするだけで良いんです。">
```

### URLの正規化
値canonicalを使って、URLの正規化をします。
ページをリライトして、リダイレクトする場合は必ずする作業ですが、
これは全てのページでやっておくと良いでしょう。

これは、「このページはこのURLで評価してください」という意味です。

```html:HTML例
<link rel="canonical" href="https://korenarawakaru.com">
```

### OGP設定
OGPのコードを記述します。
詳しい書き方は、[こちら](https://qiita.com/engineerhikaru/items/d5e71abcea2faaed674e)

```html:HTML例
<head prefix="og: http://ogp.me/ns#">
  <meta property="og:site_name" content="サイト名">
  <meta property="og:title" content="ページタイトル">
  <meta property="og:description" content="ページ説明">
  <meta property="og:url" content="ページURL">
  <meta property="og:type" content="article">
  <meta property="og:image" content="画像のURL">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:site" content="@twitterid">
  <meta name="fb:app_id" content="数字15桁">
</head>
```

### 構造化マークアップ
構造化マークアップのコードを記述します。
ホームページには、「Website」、
記事ページには、「Article」と「BreadcrumbList」を指定します。
詳しい書き方は、[こちら](https://qiita.com/engineerhikaru/items/c4bb1b4d1188d4053009)

```html:HTML例
<script type="application/ld+json">
  [
    {
      "@context": "http://schema.org",
      "@type": "WebSite",
      "headline": "サイト名",
      "description": "ディスクリプション",
      "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "ホームページURL"
      },
      "image": {
        "@type": "ImageObject",
        "url": "OGP画像"
      },
      "author": {
        "@type": "Person",
        "name": "サイト管理者名",
        "image": "サイト管理者画像"
      },
      "publisher": {
        "@type": "Organization",
        "name": "サイト管理会社名/サイト名",
        "logo": {
          "@type": "ImageObject",
          "url": "ロゴ画像"
        }
      },
      "datePublished": "作成日付(例:2020-04-01T00:00)",
      "dateModified": "更新日付(例:2020-05-01T00:00)"
    }
  ]
</script>
```

### SSL化
Webページにアクセスした時に、「このサイトは安全ではありません」と表示されることがある時は
SSL化できていないので、SSL化するようにしましょう。

## SEO対策 推奨
### サイト表示速度
サイトの表示速度は、3秒以内がベストですがリッチなサイトにしようとすると
難しいので、5秒以内になるようにするのがベターです。

テストは下記のサイトを使ってやりましょう。
[PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights/)
[GTmetrix](https://gtmetrix.com/)

### タイトル最適化
Webページのタイトルは、検索結果で一番目立つので、これを最適な名前にすることで、
ユーザのクリック数を増やすために重要です。
なお、タイトルを後から変更すると一時的に検索順位が下がるので、そこは注意しましょう。

### レスポンシブ対応
レスポンシブ対応はスマホ向けに見やすく表示させることです。
最近ではPCよりもスマホで検索する人が多いので、今どきのサイトは必須です。

## まとめ
SEO対策をすることでサイトへの流入が増え、
企業であればお問い合わせの増加やブログ収益の増加などが見込めます。
今回紹介したコードを書くだけでSEO対策になるのであれば、是非やっておきたいものですね(^^)

この記事が良いと思った方は、LGTMをしていただければ嬉しいです！
フォローも是非お願い致します(^^)
Rustで可読性が高いと思う構文

# はじめに

Rustは所有権など新しい概念が多く学習難易度が高いと言われています。
しかし個人的な感触としてはかなりソースコードの読みやすさに振った言語ではないかと感じているので、
そのあたりを説明したいと思います。
内容的に論理的な話というより感覚的な話が多く出てきますのでポエムということにしておきます。

ちなみに筆者がこれまで経験してきた言語はC/C++/C#/Java/Python/Ruby/Scalaあたりです。
そのためどうしても「それらの言語と比べてどうか」という話になりがちですが、
Rustが他言語より優れている/劣っているといった主張をするつもりはなく、
あくまで目指している方向が違う（と個人的に思っている）のだとご理解ください。

# 数値型

Rustの数値型は例えば

* `i32`: 符号付き32bit整数
* `u128`: 符号なし128bit整数
* `f64`: 64bit浮動小数点数
* `isize`: 符号付き整数（ポインタと同じサイズ）

といった感じです。`int`が何ビットか、といったことを覚えておかなくてもビット数が明確ですし、アーキテクチャ依存のある型（`usize`と`isize`）が分離されているのも分かりやすいと思います。

また、Rustは数値型間の暗黙のキャストを許容しないので、（たとえ`i32` -> `i64`のように明らかに情報が落ちない場合でも）型変換は必ずソースコード上に明示されることになります。
これは記述が増えるので嫌われる傾向にあると思いますが、個人的にはどこで型が変わったかソースコードを追う必要がなくなるという点で、明示されている方が読みやすく感じます。

# `let`と`let mut`

`let`は不変の変数宣言、`let mut`は可変の変数宣言です。
基本的にはできるだけ不変で宣言したいので、可変の場合だけキーワードを追加するのは理にかなっていると思います。

```rust
let x = 0;
let mut y = 0;
y = 1;
```

例えば同じように可変と不変を宣言できるScalaの場合は以下のようになります。
こちらはこちらで縦方向に揃うのが好きなのですが、`val`と`var`の区別がし辛いので`mut`の方がより可変であることが分かりやすいと思います。
（またRustの方はあえて縦方向に揃えないことで、注目を促しているようにも見えます）

```scala
val x = 0;
var y = 0;
y = 1;
```

# シャドーイング

Rustでは以下のように同一スコープで同名の変数を再度宣言することが可能です。
（これは代入ではないので、2つの`value`は型が違っていてもいいですし、`mut`も必要ありません）

```rust
let value = "0";
let value: i32 = value.parse().unwrap();
```

この挙動はあまり一般的ではないので初見殺しと言われたりするようですが、変数名をシンプルに保つ効果があるのではないかと思っています。
（他にも`mut`をつけたり外したりするのにも使うので、そのためだけの機能ではないですが）

例えば同じコードをC#（`Parse`の字面が似ているので選びましたが他の言語でも似たような感じになると思います）で書くと以下のように型毎に変数名を変える必要があります。
この`_str`や`_int`は本来変数名に必要な情報ではないのではないか、ということです。

```cs
string value_str = "0";
int value_int = Int32.Parse(value_str);
```

初めてRustのシャドーイングの仕様を見たときは「これは想定外の箇所でシャドーイング起こしてバグの原因になるのでは？」と思ったのですが、5年ほど書いて特に困ったことも起きていないです。
型検査がしっかりしているので、予想外のシャドーイングが起こった場合すぐコンパイルエラーとして検出されるからなのかな、と思っています。

# エラー処理

Rustにはいわゆる（C++やJavaにおける）例外はなく、失敗する可能性のある処理は`Result`という型を返すことで表します。

```rust
fn failable() -> Result<i32, Error>;
```

これは特に関数呼び出し側の読みやすさに寄与していると感じます。
例えば上記の`failable`関数の呼び出しは以下のようになります。

```rust
let x = failable()?;                      // 失敗したらearly return
let y = failable().expect("failed at y"); // 失敗したら"failed at y"を表示して強制終了
let z = failable().unwrap();              // 失敗したら強制終了
let w = failable();
...
w.unwrap(); // 後でエラー処理する場合
```

このように失敗する可能性のある関数は必ず失敗したらどうなるかを呼び出し時（あるいは結果を使う前）に明示することになります。
明示しなければコンパイルエラーとなるので、忘れるということもありません。

例外の場合、各関数からどのような例外が上がってくるのかをソースコード上から知る術はなく、
いつも「必要な`catch`を網羅出来ているんだろうか？」という漠然とした不安があったのですが、
Rustの方式では（ちゃんと処理するか無視するかは別として）全てのエラーになんらかの対処をしている、と感じられるように思います。

# まとめ

以上、個人的にRustが読みやすいと思っている部分についてご紹介しました。
Rustというと「所有権が～」という話になりがちですが、こういう特徴もあるよ、ということで。
考古学のためのR統計解析〜Ben Marwick先生の授業を復習する（t検定編）〜

この記事は、2020年5月7日に行われた「第2回考古学のためのR統計解析」の復習です。前回の[「カイ2乗検定編」](https://qiita.com/ishiijunpei/items/b27be10622ac8c7a7baa)の続編です。

使用するデータは、前回と同様、北海道埋蔵文化財センターさんの[厚真町オコッコ1遺跡（２）](https://sitereports.nabunken.go.jp/70356)（北埋調報356,p234-243）の石器一覧表データを使用しました。`tabulizer`パッケージを使用して、pdfの表データを読み込んでいます。

[当日資料「Statistical Inference and Data Exploration for Archaeologists」](https://benmarwick.github.io/stat-inference-and-exploration-for-archaeologists/stat-inference-and-exploration-for-archaeologists.html#1)

```{r}
# パッケージ読み込み
library(tidyverse)
library(infer)
library(knitr)
```

# データ準備

1. 長さと幅を実数型に変換して「つまみ付きナイフ」だけを選択します。
2. 石材をShとそれ以外（Other）に分けます。

```{r}
tbs2 <-
  tbs %>%
  mutate(
    長さ = as.numeric(長さ) , # 長さを実数に変換
    幅 = as.numeric(幅) , # 幅を実数に変換
    ) %>%
  filter(遺物名 %in% "つまみ付きナイフ") %>% # つまみ付きナイフだけを選択
  mutate( 石材分類 = # mutate()を利用して石材を再分類（頁岩とそれ以外にする）
    case_when(
      石材 %in% "Sh" ~ "Sh" , # 石材　sh（頁岩）はshにする（そのまま）
      石材 %in% c("Ag" , "Obs" , "Si") ~ "Other" # Ag Obs Si（メノウ、黒曜石、珪岩？） をOtherにする。
    )
  )
```


```{r}
# クロス集計表
tbs2 %>%
  count(遺物名, 石材分類) %>%
  spread(key = 石材分類 ,value = n) %>%
  kable()
```

作成したデータはこのような形です。Sh（頁岩）が圧倒的に多いです。

|遺物名           | Other| Sh|
|:----------------|-----:|--:|
|つまみ付きナイフ |    29| 73|


基本的な手順はカイ2乗検定と同じす。標本から1000回リサンプリングした標本群に対して、t値を算出します。

```{r}
# 1000回のリサンプリングでt値を算出
null_distribution <-  
  tbs2 %>%
  specify(長さ ~ 石材分類) %>% # 長さと石材分類の2列のtbble形式データを作成
  hypothesize(null = "independence") %>% # 帰無仮説は「石材分類と長さは独立である」
  generate(reps = 1000, type = "permute") %>% # 1000回リサンプリング
  calculate(stat = "t", order = c("Sh", "Other")) # t統計量を計算
```

続いて、データ本体のt値を算出し、`t_stat`オブジェクトに格納します。

```{r}
# 標本のt値を算出
t_stat <- 
  tbs2 %>%
  specify(長さ ~ 石材分類) %>% 
  calculate(stat = "t" ,order = c("Sh", "Other")) %>%
  dplyr::pull() # caluculate()の結果の要素（chitestの統計量）にアクセス
```

`infer::visualize()`でt値のヒストグラムを表示します。

```{r}
# 可視化する
null_distribution %>% # 1000回サンプリングした標本のt値
  visualize() + # ヒストグラム描画
  shade_p_value(obs_stat = t_stat, # 標本のt値
                direction = "right") # 片側検定
```

![tstatｔ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/6e1b46ff-9a8e-ef06-6395-c01be1134e34.png)

見た目には、帰無仮説が棄却されるかどうか、なかなか微妙なところにいます。
帰無仮説は棄却されるでしょうか？

密度図で石材分類ごとの長さの分布を比較します。

```{r}
# 密度図で可視化する
tbs2 %>%
  ggplot(aes(x = 長さ , fill = 石材分類)) +
  geom_density(alpha = 0.4 , colour = "white") +
  scale_fill_viridis_d(option = "cividis")
```
![density.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60438/a09243b1-2c76-4a97-b321-d954953bd53c.png)
密度図からは、石材によって石器の長さが明らかに異なっている、という印象は受けません。


いよいよp値を算出します。

```{r}
# p値の算出
tbs2 %>%
  t_test(長さ ~ 石材分類 , order = c("Sh","Other")) %>%
  kable()
```

| statistic|     t_df|   p_value|alternative |  lower_ci|   upper_ci|
|---------:|--------:|---------:|:-----------|---------:|----------:|
| -2.589326| 66.56431| 0.0118003|two.sided   | -1.603729| -0.2074192|

「棄却すべき有意確率は最初に決めておきなさい」という教えの理由がよくわかる結果です。5%なら棄却できるけど、1％では棄却できません。

（次回は「ANOVA編」です。）
ReactNativeでテキストを省略させる[...]　三点リーダー

# 用途
* 文字が多い時に省略させる  

### numberOfLines
* テキスト表示のコンテナ行数 

>行の合計数がこの数を超えないように、行の折り返しを含むテキストレイアウトを計算した後、
省略記号を使用してテキストを省略します。この小道具は一般的にで使用されellipsizeModeます。

### eliipsizeMode
* テキストに「...」を表示させる位置を設定する


* head
 線が表示され、端がコンテナーに収まり、線の最初の欠落したテキストが省略記号で示されます。 
`例： "... wxyz"`

* middle
 行が表示され、最初と最後がコンテナに収まり、中央の欠落したテキストが省略記号で示されます。
`例：「ab ... yz」`

* tail
 行が表示され、最初がコンテナーに収まり、行末の欠落したテキストが省略記号で示されます。
 `例：「abcd ...」`

* clip
 線はテキストコンテナーの端を越えて描画されません。

> numberOfLinesが設定されている場合、この小道具はテキストの切り捨て方法を定義します。numberOfLinesこのプロップと組み合わせて設定する必要があります。



### まとめ
* テキストを省略させたいときは、`numberOfLines`と`eliipsizeMode`を使う

### 引用
https://reactnative.dev/docs/text#accessible
[メモ] 携帯電話番号の判定について

# 概要

[google-libphonenumber](https://www.npmjs.com/package/google-libphonenumber)を使っていて正しい電話番号と判定されなかった番号があったため調査したら

- 0900
- 0700

という携帯電話番号は今の所なさそうと知った。

# 詳細

0900XXXXXXXという形式の携帯電話番号が正しい携帯電話番号と判定されなかったため、調べたところ `[7-9]0[1-9]\d{7}` という正規表現でチェックしていた。
何か仕様書がないか探していたら、下記の資料を教えてもらった。

[「携帯電話番号の有効利用に向けた電気通信番号に係る制度の在り方」答申（案） 概要](https://www.soumu.go.jp/main_content/000390863.pdf)

> 0AB0番号帯の一部は付加サービス向けに使用してきており、0900番号帯及び0700番号帯は携帯電話番号として割り当てていないが、番号のひっ迫状況によっては、将来的に0900番号帯及び0700番号帯は携帯電話向けに使用することもあり得るため、引き続き留保しておくことが適当

注意：平成２７年１２月１７日の資料
よって0900~は正規の番号ではない。
google-libphonenumberはそこまでチェックしててすごいなぁと思った。
初心者がEclipseとOracleDBの連携に詰まった話

##やりたかったこと

EclipseとOracleDB (11g Release2)を連携させて、Javaプログラムを使ってDB内の値を取得したい。

すでにMYSQLとの連携はできているので、データアクセス層当たりのコードいじるだけでできるはず。

##詰まったこと
・そもそもDBとの接続文字列に指定するものは何？
・SQL文がMYSQLを操作する際に使用していたものと同じでは、謎のエラーが出る。
・ResultSetを受け取ったあたりで謎の警告が出る。

特にSQL文のエラーは解決するのにだいぶ時間かかりました。。。
もしかしたら全く同じことでつまずく人がもしかしたらいるかもしれないので、メモとして残しておきます。

##そもそもOracleDBとの接続文字列に指定するものは何？

詰まった3つのことをすべて書くととても長くなりそうなので、今回は接続文字列についてのみ記事にします。
結論から言うと、jdbc:oracle:thin:@localhost:1521:XEで通りました。（OracleDB 11g Release2）
※OracleDBは最新だと19cとか出てますけど文献少なかったので今回はあきらめました。

試してみたコードはこちらです。

```java:TestConn
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestConn {

	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		Connection conn = null;
		String url = "jdbc:oracle:thin:@localhost:1521:XE";
		String user = "OracleDBに作成したID";//ここは適宜変更して下さい。
		String password = "OracleDBに作成したpassword";//ここは適宜変更して下さい。

		try {
            //Driverのロード
			Class.forName("oracle.jdbc.OracleDriver");
            //コネクションの確立
			conn = DriverManager.getConnection(url, user, password);
			System.out.println("接続に成功しました");

			PreparedStatement pre_statement 
                        = conn.prepareStatement("SELECT PASSWORD from user_id where id = 123456");
            //実行したいSQL文に変更してください

			//SQL実行
			ResultSet result_set = pre_statement.executeQuery();
			System.out.println("取得しました");
			result_set.next();
			System.out.println(".next()実行しました");
			System.out.println(result_set.getString("PASSWORD"));

		} catch (ClassNotFoundException | SQLException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}

	}

}
```

![OracleDB Test接続結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640581/c4ad34a6-cc86-e6a5-a852-cf193f2e176f.png)

こんなかんじで出来ました。
（DB側のスクショ取り忘れましたが、取得したい値はpasswordであっているので、成功しています。）

この接続文字列についてですが
1. ConnectionTypeが、jdbc:oracle
2. Driverがthin(なんなんだthinて。。。)
3. ホストの名前が今回はlocal環境で操作させているのでlocalhost
4. JDBCポートが 1521
5. SIDがXE(メモリの名称,自分がインストールしたOracleDBのフォルダの中をいじるとファイル名になってる。)

これをつなぎ合わせてるみたいですね。

社内研修ではおまじないのように使用していたので、これを機に勉強できてよかったです。

##最後に
残りの２つも随時記事にして自身の備忘録に出来たらなあと思っています。

乱文なので見ずらいかもしれませんが、ご了承ください。
【PHP】「' '」と「" "」の違い

## 文字列の括り方
PHPで、文字列を記述する場合は、文字列をシングルクォーテーション「' '」またはダブルクォーテーション「" "」で括ります。

```php
<?php
$string1 = 'シングルクォーテーションだよ';
$string2 = "ダブルクォーテーションだよ";
```

基本的にはどちらを使っても良いですが、2つの括り方には違いがあり、書き方も微妙に違う部分があります。


## 2つの括り方の違い
大きな違いは、文字列の中に変数があった場合です。
文字列の中に変数があった場合、

- シングルクォーテーションでは変数が「文字」として認識される
- ダブルクォーテーションでは変数が「変数内の値」に変換される

```php

<?php
  $count = '5'; //変数名$countに「5」を代入
  echo 'バナナが$count本あります。'; //シングルクォーテーション使用
  echo '<br>'; //「改行」
  echo "バナナが{$count}本あります。"; //ダブルクォーテーション使用
```

実行結果

```
バナナが$count本あります。
バナナが5本あります。
```

変数の変換処理がある分、動作の速度的には

- シングルクォーテーション＞ダブルクォーテーション

になりますが
[Swift] for inとforEachの使い方メモ 

for in と forEachの使い方を忘れていた。。。

アプトプットも兼ねて自分用にまとめてみます。

#よく使う書き方

```swift

for i in 0..<5 {
    print(i)  // 0~4
}

for i in (0..<5).reversed() {
    print(i)  // 4~0
}
```
```swift

let arr = ["a", "b", "c", "d"]

for i in 0..<arr.count {
    print(arr[i])  // a, b, c, d
}

for i in arr {
    print(i)  // a, b, c, d
}

arr.forEach {
    print($0)  // a, b, c, d
}

Array(0..<arr.count).forEach {
    print(arr[$0])  // a, b, c, d
}
```
#for in と forEachの違い
結論から言うと、

・for in文ではbreakでループ処理を抜けることができる
・for each文はreturnやbreakなどでループ処理を終わらせて抜けることができない


以下、Playgroundでコードをいじってみました

```swift
var numbers = [0, 1, 2, 3, 4, 5]
 
//for in
for num in numbers {
    if num == 3 {
        break
    }
    print(num)  //0 1 2
}

// forEach
numbers.forEach {
    if $0 == 3 {
        return
    }
    print($0)  //0 1 2 4 5
}
```

へえ、forEach文の中身はあくまで関数のため、returnはループ内の関数を抜けるだけでループ自体は継続するんですね。

ちなみに上のコードにおいて、for inの方でreturnを書いたり、forEachの方でbreakをかくとエラーが出て実行できません。


補足しておくと、
breakとreturnのざっくりとした違い
・break・・・ループをその場で終了させる。
・return・・・関数内の処理を抜ける。
【C#】配列やリストの中からランダムに1つ返す関数

# はじめに
Unityを使っていると `複数のオブジェクトの中から1つの要素を同様に確からしい確率で取得したい` という場面が多々ある。
アイテムのランダムドロップやガチャがその場面に該当する。

この処理の実装自体は簡単なのだが以下の問題がある。

- 配列の中からの取得、リストの中からの取得、どちらにも入っていない集団からの取得で実装方法が異なる
- 関数を作らない場合はコピペコードが量産される
- ジェネリックを使わない場合は型ごとに関数を実装する必要がある

今回は上記の問題を解決する関数を作った。

# 配列やリストの中からランダムに1つ返す関数

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Helper : MonoBehaviour
{
	internal static T GetRandom<T> (params T [] Params)
	{
		return Params [Random.Range (0, Params.Length)];
	}

	internal static T GetRandom<T> (List<T> Params)
	{
		return Params [Random.Range (0, Params.Count)];
	}
}

```

## 使用例

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
	private void Awake()
	{
		Debug.Log (Helper.GetRandom (1, 2, 3, 4, 5));
		Debug.Log (Helper.GetRandom (new float [] { 0.5f, -1.5f, 9.99f }));
		Debug.Log (Helper.GetRandom (new List<string> () { "aiueo", "12345", "abcde" }));
	}
}

```

実際に以下のようなログが流れる。
![GetRandom_Log](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318712/72e56d8c-2848-e2a6-1c79-2f8f8974d20c.png)

## おまけ：配列とリストのみに対応する場合
`IList` を使えば配列とリストに対応可能。
ただし上の例の `Helper.GetRandom (1, 2, 3, 4, 5)` はエラーが出る。

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Helper : MonoBehaviour
{
	internal static T GetRandom<T> (IList<T> Params)
	{
		return Params [Random.Range (0, Params.Count)];
	}
}

```
attr('action')を遷移先にする仕組み

ajax通信での非同期通信の復習している最中、そういえばと目に止まったのがactionで遷移先を指定している以下のjsコード記述

````
※投稿ボタンを押した際、ajax通信を行う部分の抜粋

    let url = $(this).attr('action');
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType:'json',
      processData: false,
      contentType: false
    })
````

注目して頂きたいのが

````
let url = $(this).attr('action');
````

と言う箇所。
遷移先の変数を定義している部分なのですが、引っかかったのはattr('action')。
actionで遷移先指定できちゃうの・・・？どういう理屈で・・・？(震え声)

そんなこんなで好奇心に駆られて気づけばあれこれと調べていたのです。

さてここでattrについておさらいしていきましょう。

[attrの使い方]　　※jQueryでの記述

````
$(指定したい要素など).attr('属性値');
````
属性に対する値を取得する際に用いられる。もし値がないならundefinedで返す


つまり指定要素内のaction属性を取得してることになるんですね。
しかしながら最大の謎はaction属性でなぜ遷移できちゃうのか？

次にactionについておさらいしましょう。

今回は投稿ボタンでの部分、つまりform要素内です。
form要素ではactionは"送信先を指定する”ために使われるものなのです。

つまりactionにはそもそもURIパターンが入っているので、遷移先として指定できてしまうというわけです。

便利ですな〜


余談英会話

attrメソッドは、attribute(アトリビュート)の略。
使い方：
attribute A to B ： AをBのおかげと考える。/AをBのせいと思う。
ex)
He attributed his success to working hard.
彼は成功したのは勤勉のおかげと考えた。


この単語がプログラミングではデータ属性の抽出として使われてることが非常に面白いですね。
りそなのソフトウェアトークンを1Passwordで使った話

# りそなのソフトウェアトークン
VIP Accessとかいうアプリを入れさせられる
入れたスマホがないと振り込みができなくなる
~~**くそじゃん！！！**~~

# ここに良いこと書いてあった
https://www.reddit.com/r/1Password/comments/8yey6y/how_do_i_use_symantec_vip_with_1password/
・1Passwordで使えるようにするためにリバースエンジニアリングして作ったツールが有るよ
・作者は更新してないけどフォークされてるのが使えるよ

#1Passwordのワンタイムパスワード機能で使えるようにしたい
できそう

#必要なもの
pip3

python-vipaccess
↓ここにインストール方法書いてある
https://github.com/dlenski/python-vipaccess

```sh:
pip3 install python-vipaccess
pip3 install https://github.com/dlenski/python-vipaccess/archive/HEAD.zip
```

qrencode
Macなら

```sh:
brew install qrencode
```
# 使う

## 認証
```sh:
# トークンタイプはSYMCにしなきゃだめ
vipaccess provision -p -t SYMC
```

出力された

```sh:
You will need the ID to register this credential: SYMCxxxxxxxx
```
ってのが重要なので、右の12桁の英数字をコピる

## QRコード作る
「optauth://」から始まるURLもコピっておく
1Passwordのワンタイムパスワードのところに登録する
スマホアプリ版ならQRコードを発行して入れる

```sh:
qrencode  'otpauth://totp/VIP%20Access:SYMCxxxxxxxx?secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&digits=6&algorithm=SHA1&issuer=Symantec&period=30' -o ~/Downloads/qr.png
```

ダウンロードフォルダにできるから、スマホの1Passwordアプリで読み取る

# りそなで登録

Credentialは、上でコピーした英数字12桁
ワンタイムパスワードは1Passwordが吐いてくれるワンタイムパスワード

ソフトウェアトークンのリセットして改めて登録すれば使えるようになる

# 終わり
スマホ一個落としただけで（スマホが手元にないと）、振り込みできなくなる糞システムとサヨナラ！！
あと、パソコンもスマホも1Passwordも、ちゃんと十分なパスワードを設定しておこうね！！
【備忘】VirtualBoxにUbuntuがインストールできない

自分のホストは、Windows10で、Hyper-Vはオンの状態。
Docker Desktopをインストールしていて、共存が出来るようになったとの噂でやってみようとしたときの記録。

VirtualBoxのバージョン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29848/a1a16d50-216f-42ef-8477-84eb5bc4ff69.png)

Ubuntu20.04をインストールしようとすると、インストーラーがクラッシュ！？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29848/8ea534aa-15c5-3105-cbb5-ce216d477b16.png)

どうしたものか・・・