OmniAICreator/Qiita-1.07M huggingface dataset:
AZ-900:Microsoft Azure Fundamentalsに合格するために役立つ無料教材

# はじめに

Microsoft Azure はその基礎的な知識を測るための試験として、AZ-900: Microsoft Azure Fundamentals という試験があります。
Azure を業務で利用する場合、この試験に合格する程度の知識を身につけておく方が良いと思います。
[AZ-900の詳細はこちら](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-900)

私はこの試験を受験して合格したので、その時の勉強に役立った無料教材を紹介します。
これから受験される方の助けになれば幸いです。

# Microsoft Virtual Training Days

Microsoft は AZ-900 に必要な知識をWebinar形式で教えてくれる無料のVirtual Trainingがあります(日本語です)。
しかも2021年6月時点では、トレーニングの受講を完了するとAZ-900の受験費用が無料になる特典があります。
開催頻度がどのくらいでいつまで開催し続けるのか分かりませんが、2021年6月時点では、毎月のように開催していました。
[Microsoft Virtual Training Daysの申し込みはこちら](https://www.microsoft.com/ja-jp/events/top/training-days.aspx)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/c5b9c7c7-5c4a-7f5a-316a-d5fb601d6a17.png)

上記のトレーニングは合計6時間程度で、これを受けることで、AZ-900の試験範囲の内容を、概ね理解することができました。

オススメの受講方法として、下図のように学んだことを何かにメモしつつ、デモの時は実際に自分のAzureアカウントで同じようにAzureを触ってみたりすると、理解が促進されて良いと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/c052d846-6072-b65c-ff90-c0073eb65660.png" width=80%>

# Microsoft Learn

Microsoft の技術を学ぶ人のために、Microsoft Learn という学ぶための公式教材が公開されています。
これがメインの学習教材でした。
サインインしてページを閲覧すれば、読んだページが記録され、自分がどこまで学習したか分かるようになります。
また、章ごとに小テストのようなページがあり、それを一発で合格することを目標にすると、読む時のモチベーションが上がります。
[Microsoft Learn (Azure の基礎)](https://docs.microsoft.com/ja-jp/learn/paths/az-900-describe-cloud-concepts/)

下図のパート1からパート6がAZ-900の出題範囲です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/2694b92e-dbf6-a54f-c0b3-834a14d3dd04.png)

# AZ-900 : Microsoft Azure Fundamentals 試験対策

AZ-900の試験対策に特化したウェビナーです。
試験の概要や位置づけ、各試験問題の特徴や解説、回答のポイントなどが紹介されています。
こちらのウェビナーを受講すると、そのウェビナーで使用された資料をもらうことができます。
その資料がとても分かりやすいので、重宝しました。
[AZ-900 : Microsoft Azure Fundamentals 試験対策](https://info.microsoft.com/JA-HCSAzureHybridInfra-WBNR-FY21-02Feb-11-AZ900PrepSession-SRDEM61308_LP02OnDemandRegistration-ForminBody.html)

# まとめ

私は上記の教材で学習した結果、700点合格に対して800点で合格できました。
これから受験される方の助けになれば幸いです。
axiosのinterceptorsを利用してグローバルなエラーハンドリングを行う

今回は自身で開発・運営している「Hello Books」で利用している技術について紹介したいと思います。  
  
#### [Hello Books](https://hellobooks.org)について
https://hellobooks.org

* エンジニア向け技術書レビューサービス
* 購入前の判断にエンジニアのレビューを役立てることができる
* アカウントを作成することで自身もレビューを投稿したり、技術書をブックマークしたりできる
* 詳細な条件による技術書の検索が可能
![スクリーンショット 2021-05-27 10.20.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521599/52eb5728-a133-3759-011d-95571d1f006d.png)

### axiosについて
[Hello Books](https://hellobooks.org)のフロントエンドはReactを使っています。Reactを使って実装を行う際にはAPI通信に[axios](https://github.com/axios/axios)を利用することも多いと思います。

axiosのエラーハンドリングは通常リクエストから取得されるPromiseのcatch節で行われると思います。個別ケースのエラーハンドリング実装であれば"呼び出し箇所のcatch節でエラーハンドリングする"として問題ないと思いますが、ある特定のエラーに対応するためにレスポンスを毎回確認する様な必要がある場合には個々の呼び出し元catch節でハンドリングを行うのはあまりに冗長な実装になってしまいます。

グローバルエラーハンドリングには様々なアプローチがあると思いますが、今回はaxiosのinterceptorsを利用してお手軽に対応する方法を紹介します。

#### axiosインスタンスの設定

```typescript
export const api = axios.create({
    baseURL: process.env.REACT_APP_URL_SCHEME,
    timeout: 30000,
});


api.interceptors.response.use(
    response => response
    , error => {
        console.log(error.response);

        // TODO: グローバルに対応したいエラーハンドリング処理を実装する

        return Promise.reject(error);
    });
```

`axios.create`としてaxiosのインスタンス`api`を定数として作成しています。`export`しているので、こちらのインスタンスはシングルトン的に他ファイルからも参照可能です。

あとは作成した`api`インスタンスにinterceptorsを設定するだけで完了です。このaxiosインスタンスを利用してAPIリクエストを行う様にすればinterceptorsによるグローバルエラーハンドルが行われます。これらのハンドリングは個別の呼び出し箇所で設定されている`then`・`catch`より前の段階で実行されます。お手軽ですね！

今回はresponseに対してinterceptorsを設定していますが、`interceptors.request`とすることでリクエストに対してもinterceptorsを設定することが可能です。

ここで紹介したのはいちれいですので、詳細については[axiosの公式github](https://github.com/axios/axios#interceptors)をご参照ください。

##### 最後に
最後まで読んでくださり、ありがとうございました。複雑な処理や要件を実装する必要がある場合にはaxiosのinterceptorsだけでは対応できないこともおあるかもしれませんが、比較的シンプルな処理であれば簡単に実装できます。よろしければ[Hello Books](https://hellobooks.org)にも是非遊びに来てください！
unity5.2の作法 その14 game

#概要

unity5.2の作法、調べてみた。
ゲームを作る、構想編。

#方針

ヒエラルキーは使うが、インスペクターは使わない。
2Dでやる。
スクリプトは、一個だけ。
makefile、手順を書く。
当たり判定、使わない。
画像、使わない。
音、使わない。
重力、使わない。
prefab、使わない。
perticle、使わない。


以上。
npm pinyinをAngular(typescript)で実装して、ピンインを表示する

```
npm install pinyin
```
<hr>

```
npm i --save-dev @types/pinyin
```
<hr>

```app.component.ts
import { Component } from '@angular/core';
import * as pinyin from 'pinyin';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  pinyinForDisplay: string[][] = pinyin("你好");
}

```
<hr>

```app.component.html
<h1>你好のピンインは{{pinyinForDisplay}}です</h1>
```
<hr>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/c9621a06-4968-048b-1977-0d1cd0ad7a9c.png)
cakephp3.9でペジネーション【コントローラーのみで】

#備忘録です。

##Controllerにて

```php:TopController
        public $paginate = [
//limitiの値は任意で変更してください。
            'limit' => 12
        ];
```
あとはいつも通り取得

```php:TopControllerのメソッド内
                //テーブル
                $postes = TableRegistry::getTableLocator()->get('postes');
                $dataes = $postes->find('all')
                ->where(['del_flg' => 0,
                'composition LIKE' => $whereSerch]);

                //取ってきた情報をここで引数にして渡す。
                $dataes = $this->paginate($dataes);
                
                $this->set(compact('dataes'));
```

##viewにて
以下のようにすれば超えていてれば勝手に出てくるし、超えて無ければ出てこない。
簡単実装だね。


```php:view.ctp
    <ul class="pagination">
        <li>
            <?php 
                if ($this->Paginator->hasPrev()) {  
                    echo $this->Paginator->prev('< 前へ');
                }
            ?>
        </li>
            <?php 
             if (!empty($this->Paginator->hasPrev())){
                echo $this->Paginator->numbers();
             }
             ?>
        <li>
            <?php
                if ($this->Paginator->hasNext()) {  
                  echo $this->Paginator->next('次へ >');
                }
            ?>
        </li>
    </ul>
```

色んなフレームワークを触って仕事してるので忘れがち。
とりあえずメモとして保存ですよ。
Font Awesomeの登録方法

#はじめに

**Font Awesome**のアイコンを使いと思ったのですが何かに登録しないといけない。。。

全部英語でどこからやればいいか分からない。。。

こんな状況に私自身なったので誰かの役に立てればと思い、投稿します

###利用できるまでのステップ

- 登録する(メールアドレス)

- パスワードを決める

- 指定された記述を<head>タグ内に貼り付ける

この3点で利用できるようになります。


#登録する

こちらがサイトになります。
まずはアクセスしましょう。

https://fontawesome.com/

トップページに**start for free（無料で始める）**とあるのでこちらから新規登録します。

右は課金しなければ使えません。

![スクリーンショット 2021-06-30 10.41.18（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/227e94c2-cd85-b35b-5698-5bd536a57060.png)

こちらにメールアドレスの入力するフォームがあるので自分のアドレスを入力して下さい。
入力後、`send kit code`をクリックして終了です

![スクリーンショット 2021-06-30 10.47.40（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/77838153-b84c-a5cb-93c2-b3811fc07d8c.png)

#パスワードを決める

メールアドレスを設定したらそのアドレスにメールが届きます。

**click to confirm your email address + set things up(クリックすると、メールアドレスの確認と設定ができます。)**と書いてあるのでクリックします。

![スクリーンショット 2021-06-30 10.52.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/5ef58478-08d8-6dd9-9dad-ea57ec701379.png)

パスワードを2回入力する画面に遷移するので自分のパスワードを決めます。

![スクリーンショット 2021-06-30 11.02.53（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/7f98839c-32e1-ef71-9df0-6d814ff1f246.png)

入力後このような画面が出てきます。
もっとあなたの事を知りたい！と言われますが私は無視してしまいました。

**ごめんよ。Font Awesomeさん・・・**

![スクリーンショット 2021-06-30 11.04.51（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/5792ae94-6b43-6b4c-e7bf-8c3ea6f240d2.png)



いよいよアイコンが利用できるようになります。

・・・の前に一点最後に記述する必要がある項目があります。

#指定された記述を<head>タグ内に貼り付ける

![スクリーンショット 2021-06-30 11.07.26（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/4650f866-1515-a0c6-0196-d851b40665e4.png)

この画面に遷移すると思います。

そしたら①の**Add Your Kit's Code to a Project（あなたのキットコードをプロジェクトに追加）**とあるのでコピーして貼り付けます。



```application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>アプリ</title>
    <link 
    <script src="https://kit.fontawesome.com/個人ID.js" crossorigin="anonymous"></script>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

後は使いたいアイコンを見つけて貼り付けをすれば利用できます

！![スクリーンショット 2021-06-30 11.23.02（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/65662ba0-3628-dd51-5510-dc03ced62ee4.png)

```.html
<i class="fab fa-youtube"></i>
```

#参考
https://www.webdesignleaves.com/pr/plugins/fontawesome_03.html
unity5.2の作法 その13 mouse

#概要

unity5.2の作法、調べてみた。
マウスで線をひく、やってみた。

#makefile

- menu->file->new sceneする。
- menu->file->save sceneでsenとする。
- menu->gameobject->create emptyする。
- menu->assetes->creates->c# scriptでsen.csつくる。
- ダブルクリックして、コードを書く。
- ヒエラルキーのgameobjectに、コードを重ねる。
- 三角で実行。

#サンプルコード


```
using UnityEngine;
using System.Collections;

public class sen : MonoBehaviour {
    LineRenderer lr;
    int n;
	void Start () {
        lr = new GameObject().AddComponent<LineRenderer>();
        lr.SetColors(Color.red, Color.red);
        lr.useWorldSpace = true;
        lr.SetWidth(0.5f, 0.5f);
        n = 0;
	}
	void Update () {
        if (Input.GetMouseButtonDown(0))
        {
            lr.SetVertexCount(n + 1);
            Vector3 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
            lr.SetPosition(n, new Vector3(point.x, point.y, 0f));
            n++;
            Debug.Log(n);
        }
        if (Input.GetMouseButtonUp(1))
        {
            lr.SetVertexCount(0);
            n = 0;
        }
	}
}




```

以上。
Ubuntu コマンドインストール

### 必要に応じて
```
# キーバインドを変更するなら(一部のPCで効かない)
# DELL Vostro 3020 Small Desktopで有効だが再起動で忘れる
$ setxkbmap -option ctrl:swapcaps
# キーバインド戻す
$ setxkbmap -option

# キーバインドを変更するなら(一部のPCで効かない)
# DELL Vostro 3020 Small Desktopで有効
$ sudo vi /etc/default/keyboard
XKBOPTIONS="ctrl:swapcaps"
$ sudo systemctl restart console-setup
# Ubuntu再起動

# ユーザーを追加してsudo可能に設定するなら
$ sudo adduser masumi
$ sudo gpasswd -a masumi sudo

# 現在のネットワーク設定を表示するのにifconfigを使うなら
$ sudo apt -y install net-tools

# Ethernetリンク速度を表示するなら
$ sudo apt -y install ethtool

# 動作クロックを表示するなら
$ sudo apt -y install cpufrequtils
```

### git global設定
```
$ cd
$ git config --global credential.helper store
$ git config --global user.email "taro@nihon.co.jp" # メルアドを設定
$ git config --global user.name "Taro Nihon" # 氏名を設定
```

### 時刻が９時間ずれるので対応
BIOSの時刻を日本時間に合わせる
WindowsはBIOS日本時間を使う
UbuntuはBIOS時間をローカル時間として解釈するように設定する
```
$ sudo hwclock -D --systohc --localtime
```
link
https://dlrecord.hatenablog.com/entry/2020/06/13/112553

### WindowsからUbuntuにリモートデスクトップ
https://orenda.co.jp/blog/rdp-ubuntu%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89/
https://ao-tela.com/vnc-vino/
https://www.peconet.org/server/ubuntu20/xrdp.html

### 不要なカーネルを削除する
```
$ dpkg --get-selections | grep linux-
$ sudo apt-get autoremove --purge linux-image-3.13.0-{65,71}
```

### メモ
bash for文
https://www.koikikukan.com/archives/2014/03/03-015555.php
keyswap
https://linuxfan.info/capslock-ctrl
apt apt-get 違い
https://qiita.com/quzq/items/8e47414bf95d1fcfa24a
CCNA試験学習(忘備録)〜STP〜

#STPとは
・レイヤ２スイッチのお話。
・**ブロードキャストストーム**を防ぐためのプロトコル。
・ブロードキャストストームが起こればCPUの負荷が上がり、ネットワーク機器がダウンする。
・**ブロッキングポート**を決めて、フレームのループを防ぐ。

#STPが機能する仕組み

**①ルートブリッジの選出**

ルートブリッジとはSTPのツリー構造の起点となるスイッチのこと。
ブリッジIDが最も低いスイッチがルートブリッジとなる。
スイッチ間で情報をやり取りする管理用フレームのことを**BPDU**という。

**②ルートポートの選出**

ルートポートとはルートブリッジまでの最短のパスコストを持つポートのこと。

ルートポート選出の３つの基準

>①累計のパスコストが最も小さいポート
②送信元のブリッジIDが最も小さいBPDUを受け取ったポート
③送信元ポートIDが最も小さいBPDUを受け取ったポート

**③指定ポートの選出**

指定ポートとはスイッチ間のより上位のBPDUを送信するポートのこと

指定ポート選出の３つの基準

>①ルートパスコストが最も小さいBPDUを送信するポート
②送信元ブリッジIDが最も小さいBPDUを送信するポート
③送信元ポートIDが最も小さいBPDUを送信するポート

・ルートポートの向かい側は指定ポートになる
・ルートブリッジは全て指定ポートになる

**④ブロッキングポートの選出**

最後まで残ったものがブロッキングポートになる

#ポートの状態遷移

以下の図のような遷移となる。

![スクリーンショット 2021-06-27 16.59.12 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973512/cbb9d57b-b794-2442-031c-9ccb2ce13ffd.png)

**ディセーブル(Disabled)状態**
電源がオフの状態。

**ブロッキング(Blocking)状態**
電源を入れるとブロッキングになる。BPDUは受信する。
最大エージタイマーはデフォルトで**20秒**。
最大エージタイマーとは、障害が発生したと判断して再計算を始めるまでの時間。

**リスニング(Listening)状態**
BPDUを送受信し、各ポートの役割を決めている状態。
転送遅延タイマーはデフォルトで**15秒**。
転送遅延タイマーとは、ルートブリッジから離れているスイッチのことを考慮して、
リスニングとラーニングの状態で待つ時間。

**ラーニング(Lerning)状態**
BPDUを送受信し、**MACアドレスを学習している**状態。
ここも転送遅延タイマーはデフォルトで**15秒**。
**ブロッキング状態**は、15秒待たずにブロッキングになる。

**フォワーディング(Fowarding)状態**
データ転送が可能な状態。

上記のように、STPはコンバージェンスまで**50秒**かかる計算になる。

#障害発生時の動作

**直接的な障害の場合**
トポロジが変化し、再度コンバージェンスするまでに**30秒**かかる。

**間接的な障害の場合**
トポロジが変化し、再度コンバージェンスするまでに**50秒**かかる。

#Port Fast

スイッチ以外のPCといったデバイスがネットワーク内にあり、PCをオン/オフしただけでも
トポロジが変化したと認識され、50秒の待ち時間が出てしまう。ということが起こります。
それは意味のない待ち時間なので、**Port Fast**の設定でPCなどのポートのアップ/ダウンは
トポロジの変化と認識されないようにできます。
すぐに**フォワーディング状態**になり、通信可能になります。
・Cisco独自の技術。
・スイッチ間のリンクではループの原因になるので設定してはいけない。
・Port Fastとセットで**BPDU**ガードも設定する。

#ルートガード

![スクリーンショット 2021-06-30 9.43.45 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/973512/fb986b05-e7ee-b492-98b8-a5f6c105aeac.png)
上の図のように、意図しないスイッチが接続され更にそのスイッチのプライオリティが低かった場合、
ルートブリッジに選ばれてしまい、再計算されもともとブロッキングポートだったところが変わり、トポロジが変わってしまう。
それを防ぐためにルートガードを設定し、ポートを**ルート不整合**状態にする。
ルート不整合状態であれば、通信がブロックされる。

#RSTP

・標準化されたプロトコル
・STPの上位互換
・コンバージェンスまでの時間が数秒までに短縮
・非指定ポートを更に分割し、**代替ポート(ルートポートの予備)**と**バックアップポート(指定ポートの予備)**となる
・ポートのステータスがディセーブル、ブロッキング、リスニングが統合され**ディスカーディング(Discarding)**に
・Port Fastのような機能がデフォルトで備わっていて、RSTPでは**エッジポート**が担う

#CST

VLANが使われていたとしても、STP構成はひとつ。
メリットとしては、
・メモリの負荷は軽い
デメリットとしては、
・複数のVLANを一つのSTPで管理するため効率の悪いルートを通る可能性がある
・STP構成が一つなので、特定のリンクにトラフィックが集中する

#PVST

STP構成をVLANごとに構成できるのがCisco独自の技術である**PVST(Per VLAN Spanning Tree)**
**PVST+**ではIEEE802.1Qでも使用可能に。
メリットとして、
VLANごとに効率の良いルートを通ることができ、トラフィックを分散できる
デメリットとして、
STPインスタンスが複数になるのでメモリの負荷は増加する

#コマンド

・**#show spanning-tree**コマンドでSTPの状態を確認できる。
「This bridge is the root」の表示で、このスイッチがルートブリッジであることを示す。
「Bridge ID」でスイッチのプライオリティとMACアドレスを確認できる。

・**#debug spanning-tree events**コマンドで障害発生時の動作確認
・**#no debug spanning-tree events**コマンドで上記のコマンドを停止

・**#show spanning-tree interface [インターフェイス]**コマンドでSTPが動作しているインターフェイスの確認

・**(config-if)#spanning-tree guard root**コマンドでルートガードの設定
DebianのJavaをデフォルトからJava16へ上げたときの覚書

#はじめに
GCPを利用してMinecraftのサーバーを建てて遊んでいます。
minectaft1.17からJavaの最低要件がJava16に変更されており、minecraft本体に合わせてJavaもアプデしました。その時の簡単な覚書です。

#minecraft1.17へのアプデ
mojangの公式サイトから1.17のserver.jarをダウンロードしてきます。
server.jarはサーバー上のマイクラのフォルダの中の古いserver.jarと置き換えます。
minecraft側はこれで終わり。

#java16へのアプデ
ひとまず現行のJavaのバージョンを確認します。

```sh
$ java -version
```
私の場合、jdk11.0.11くらいでした。
このままserver.jarを起動させると、
>java classが低くて起動できぬぞよ。class60以上が使えるjavaにしてくれたまえ。

みたいなことを言われます。class60を取り扱えるのがjava16以降です。
[Javaとclassの話はこちらが分かりやすかった[1]](https://www.ne.jp/asahi/hishidama/home/tech/java/version.html)


インストールしたいバージョンのJavaが登録されていればapt-getが手軽です。
apt-getでのインストールを試します。

```sh
$ sudo apt-get install openjdk-16-jdk
```

>error：そんなもん無いぞ

apt-getはダメそう。探し方が悪かっただけかも。
仕方ないので手動でやります。

手順としては
１．Java16のtar.gzをダウンロードする
２．所定の場所へtarを解凍する
３．今使っているJavaから新しくインストールしたJavaへ参照を書き換える
４．minecraft1.17が起動することを確認して完了

#アプデ作業
###１．Java16のtar.gzのダウンロード
流れは[参考サイト[3]](https://www.digitalocean.com/community/tutorials/how-to-manually-install-oracle-java-on-a-debian-or-ubuntu-vps)と大方同じ。

適当なフォルダにopenJDKの公式からtar.gzをダウンロードする。

```sh
$ wget https://download.java.net/java/GA/jdk16.0.1/7147401fd7354114ac51ef3e1328291f/9/GPL/openjdk-16.0.1_linux-x64_bin.tar.gz
```

###２．所定の場所へtarを解凍
sudo権限が必要

```sh
$ sudo su
```
jdkをインストールする場所を作る。

```sh
~$ mkdir /opt/jdk
```
tarの解凍

```sh
~$ tar -zxf /ダウンロードしたディレクトリ/openjdk-16.0.1_linux-x64_bin.tar.gz -C /opt/jdk
```
###３．参照の書き換え
update-alternativesはざっくり言うとソフトが呼び出された時のリンク先を管理してるやつ（らしい）
[詳細は参考サイト[4]参照](https://manpages.debian.org/wheezy/dpkg/update-alternatives.8.ja.html)

```sh
~$ update-alternatives --install /usr/bin/java java /opt/jdk/openjdk1.16.0.1/bin/java 100
```

>update-alternatives　--install　（リンク先を変える対象）（対象の名前）（新しいリンク先のパス）（優先度）


環境によってパスなどは適宜変更されたい。

javaの既定リンク先が変わっているか確認。--configの使い方は[参考サイト[5]](https://qiita.com/yochapan/items/af86a320035f8db7daf4)に詳しい。


```sh
~$ update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).

  Selection    Path                                            Priority   Status
------------------------------------------------------------
* 0            /opt/jdk/openjdk1.16.0.1/bin/java                100       auto mode
  1            /opt/jdk/openjdk1.16.0.1/bin/java                100       manual mode
  2            (前のJava)   　　　　　　　　　　　　　　　　　　　　　10        manual mode
　
Press <enter> to keep the current choice[*], or type selection number: 2
```
多分こんな感じで表示される。＊がついてるやつが現在選択されているJava。

###４．minecraft1.17の起動
サーバーを再起動させるなり、コマンドたたくなりする。

```
$ screen -d -m -S mcs java -Xms1G -Xmx3G  -jar server.jar nogui
```

#終わりに
忘れたころにまたJavaのアプデが入ると思うので書き残しときます。


##参考サイト
[1] Javaのバージョンとクラスの関係：
https://www.ne.jp/asahi/hishidama/home/tech/java/version.html

[2] apt-getを使ったJavaのインストール：
https://www.linuxmania.jp/apt-install-java.html

[3] OracleJDKのインストール：
https://www.digitalocean.com/community/tutorials/how-to-manually-install-oracle-java-on-a-debian-or-ubuntu-vps

[4] update-alternativesの解説：
https://manpages.debian.org/wheezy/dpkg/update-alternatives.8.ja.html

[5] update-alternativesでJavaのバージョンを切り替える：
https://qiita.com/yochapan/items/af86a320035f8db7daf4
ご紹介：DMM.comPF事業本部です

はじめまして。DMM.com PF（プラットフォーム事業本部）公式のQiitaをはじめました！今回は、簡単にDMM.comのプラットフォーム事業について、とどのような記事を公開していくかのご紹介をしたいと思います。


#PF事業本部とは
![pf_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1706758/ee9401bf-8666-2599-1c4b-e2ce5a56b507.png)

DMM.comサイトでサービスを始めるうえで土台となる機能を管轄している事業です。代表例としては、会員登録やログイン、決済機能などを持っています。

![Frame 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1706758/03966984-92d1-8da4-43f1-c6dae6af05ad.png)


メンバーは140名ほど在籍していて、機能ごとにチームが分かれています。

* 総合TOPやナビゲーションなどの送客・集客機能のチーム
* DMM Point Club（アプリ）の管轄チーム
* 会員情報やログイン機能の管轄チーム
* 管理機能のチーム
* 決済機能の管轄チーム
* DMMポイントの管轄チーム
* 不正対策の管轄チーム
* 他サービスがPF機能を利用するためのコンサルを行うチーム
* マイクロサービス化への促進を行うチーム
* カスタマーサポートと改善を行うチーム

#私たちが目指している姿
50事業あるサービスがDMM.comのサイトでビジネスをスタートするときに
安心・安全・最速でサービスインができるプラットフォームを目指しています。
**目指せ、10分でDMM.PFを使えること！**です。

そのために以下を注力しています。

**1.PF機能のグロース**

* よりコンバージョンを高めるための会員登録フローに改修
* 決済のラインナップを追加

**2.プラットフォームとしての基盤整備**

* マイクロサービス化を行うための基盤整備
* APIを外でも利用できるような認証・認可の最適な在り方の改修
* リプレイスによる負債消化

**3.ビジネスに対する支援**

* 新規ビジネスで必要なPF機能を実装する
* また、その機能が何かの要件を明確にする支援を行う


#Qiitaで提供したい記事
DMM.comプラットフォームでは技術面以外にも、多数ある事業への支援やエンドユーザーへのサポートなどあらゆる人的支援での工夫を常に考え、行動しています！
その業務で生まれる気づきをTipsとして紹介していきたいと思います。
具体的には…

* 技術紹介やプログラミングの記事
* プラットフォームの新サービス、機能
* 事業へのサポート支援における施策
* エンドユーザーへのカスタマーサポート施策
などを考えています。

#もっとDMM.PFについて知りたい
DMMinsideにて公開しているのでご覧ください！

https://inside.dmm.com/archive/category/%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E4%BA%8B%E6%A5%AD%E9%83%A8

どうぞよろしくお願いしますmm
Xcode12.4対応 no such module、simulator起動できない、ビルドできない等対応

### 結論
#####carthageのバージョンを上げる
`brew upgrade carthage`

##### carthageコマンドを変更
`carthage update --platform iOS --cache-builds`
↓
`carthage update --platform iOS --cache-builds --use-xcframeworks`

- - -
追記 20210706
いざappstoreにアップロードしようとすると
`Found an unexpected Mach-O header code: 0x72613c21`
エラーが出てしまった。

Frameworks, Libraries, and Embedded Content
のEmbedが正しく設定できてなかった。
frame workごとに
`Embed & Sign`か`Do Not Embed`を正しく選んでやらないとだめだったようで。。。
一旦全部`Do Not Embed`にして、実機でビルドしてimage not foundになるframe workを片っ端から`Embed & Sign`にしていく虱潰し作戦でなんとかアップロード成功！
追記 20210706ここまで 
- - - 

##### Build　Settings変更
・`Build　Settings`の`User-Defined`から`VALID_ARCHS`を全部削除
・`Build　Settings`の`Architectures`　に `Exclude　Architectures`を設定
このへん参考
https://zenn.dev/yimajo/articles/7e275bc23999fe7d8b87

##### Frameworks変更
・target → `General` →　`Frameworks,Libraries,and Embedded Content` に`xcframework`を設定
以下画像のように設定
`Do Not Embed`にしないとstoreにアップする際にエラーが出てしまった。
![スクリーンショット 2021-06-30 10.41.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17315/eff801be-59d9-8d8c-77cf-dd45948bcf2b.png)

##### Build PhasesのRun scriptを削除
`/usr/local/bin/carthage copy-frameworks`のコマンドがある場合は、Run scriptを削除する。
xcframeworkになって不要になったらしい。

このへん参考
https://zenn.dev/ykws/articles/carthage-meet-xcode-12

## 経緯
久々にビルドしようとしたところxcodeのバージョンアップに伴い、
過去最大級にハマっていろんな情報を見て何度もやり直したり試行錯誤してやっとビルドできるようになった。 

・`VALID_ARCHS`の設定
・ビルド時の`No such module`
・シミュレーター起動しようとして`Could not find module 'XXXXX' for target 'x86_64-apple-ios-simulator'; found: arm64, armv7-apple-ios, arm64-apple-ios, arm, armv7`
等、多岐に渡るエラーの情報を見ながら試行錯誤してやっとこさここまで。

やっとビルドできるようになったけど、機能は何も追加されたりしてないからモヤモヤする達成感。。。
【Google Cloud Day'21】「スターバックス社の北米 3 万店向け最先端データ サイエンス プロジェクトを徹底解説 !」を視聴して

https://cloudonair.withgoogle.com/events/google-cloud-day-digital-21/watch?talk=d1-gl-26
"
スターバックス社の北米 3 万店向け最先端データ サイエンス プロジェクトを徹底解説 !"
需要予測、サプライチェーン最適化、顧客体験の向上、レコメンデーションにおける取り組みを解説いたします。構造化データと非構造データ、そしてバッチ処理とストリーミング処理を統合。大量のデータを高速に処理可能なプラットフォームを構築。100 人以上のデータ プロフェッショナルが効率的に協業可能なアーキテクチャーを実現しています。「 需要予測 」のノートブックのサンプルと、無償トライアルをご提供します。

<table>
	<tr>
		<th>切り口</th>
		<th>内容</th>
	</tr>
	<tr>
		<th>会社概要</th>
		<td></td>
	</tr>
	<tr>
		<th>サービス概要</th>
		<td>他のパブリッククラウドにもサービスを展開しているが、コンテナ上で動くのは初。データエンジニア、データサイエンティストが使いやすい仕様になっている。</td>
	</tr>
	<tr>
		<th>スターバックス事例概要</th>
		<td>今回は需要予測とサプライチェーンの話</td>
	</tr>
	<tr>
		<th>課題</th>
		<td>どんぶり勘定だったが、データドリブンで需要予測する必要が出てきた</td>
	</tr>
	<tr>
		<th>開発時の課題</th>
		<td>店舗数の多さ、店舗ごとの分析モデルの必要性もあった。</td>
	</tr>
	<tr>
		<th>解決策</th>
		<td>databricksのツールでは、並列モデルを使えたので、解決可能。且つ、より詳細な分析が可能になった。</td>
	</tr>
	<tr>
		<th>databricksとBQのつながり</th>
		<td></td>
	</tr>
	<tr>
		<th>並列分散の仕組み</th>
		<td></td>
	</tr>
	<tr>
		<th>プランに説明</th>
		<td></td>
	</tr>
</table>
Crystalをマルチスレッドで実行してCPUのコアを効率的に使う

Crystalは実行速度が非常に強力です。そのため、マルチスレッドで実行して、CPUのコアを効率的に使いたいなと感じることがあります。公式リファレンスを見ると、[並列処理](https://ja.crystal-lang.org/reference/guides/concurrency.html)の項目があり、Crystal言語は並行処理をサポートしていないと明記してありますが、実際には、試験的な機能として提供しています。

クラッシュしたりオーバーハングしたりする可能性があり、オーバーヘッドも非常に大きいということです。
なので、現時点では正式に提供されている機能ではないそうです。

Crystal公式ブログの説明

https://crystal-lang.org/2019/09/06/parallelism-in-crystal.html

dev.to の解説記事

https://dev.to/jgaskins/enabling-crystal-s-new-multicore-support-4l4g

## 要点

スクリプトのコンパイル：　`-D preview_mt` をつける。

```
crystal build -D preview_mt hoge.cr
```

スクリプトの内容： `channel, spawn` を利用する。


```crystal
channel = Channel(MyValue).new(array.size)

array.each do |value|
  spawn do
    # 処理
    channel.send process(value)
  end
end

results = Array.new(array.size) { channel.receive }
```

並列で実行した結果をファイルに保存して、親プロセスに結果を返却しないようなケースでも、channelは必ず利用する必要があります。そうしないと、単にspawnを実行せずに終了します。spawnの実行順序は不定で順番通りにはならないことにご注意ください。

```crystal
channel = Channel(nil).new(array.size)

array.each do |value|
  spawn do
    # ファイルに結果を保存し、親プロセスに結果を戻さない処理
    channel.send(nil)
  end
end

array.size.times do
  channel.receive
end
```

使ってみた印象だと、オーバーヘッドは大きいらしく、メモリも結構使用します。
今後Crystalの並列処理が便利になって、誰でも便利に使いこなせるようになることを願います。
MySQLについて

###MySQLについて
リレーショナルデータベースの１つで、構造としては１つのアプリケーションに対して1つのデータベースがあり、１つのデータベースの中に複数のテーブルがある。
特徴としては
・テーブルはカラム(縦)とレコード(横)で構成される。
・カラムに保存するデータの制約を設定できる。
・データの保存や取得にはSQLという言語を用いる。

###データベースの初期設定
文字化け対策

```
cat /etc/mysql/mysql.conf.d/mysqld.cnf | sed -e '/utf8/d' | sed -e '/sql_mode/d' | sed -e '$acharacter-set-server=utf8\nsql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' | sudo tee /etc/mysql/mysql.conf.d/mysqld.cnf
```
文字化け対策を行った後はサーバーを再起動後ログインして実行

```
mysql> show variables like "chara%";　　(実行)
```



###CRAD
データベースを扱う基本操作のSQL

```
・Create　作成、保存　(INSERT)
・Read　　取得　　　　(SELECT)
・Update　更新　　　　(UPDATE)
・Delete　削除　　　　(DELETE)
```
データを定義するSQL

```
CREATE　新しいデータベース、テーブルの作成
DROP　　既存のデータベースやテーブルの削除
```

###データベースサーバの起動と停止と接続
```
sudo service mysql start   　(起動)
sudo service mysql starts  　(起動状態確認)
sudo service mysql stop   　 (停止)
sudo service mysql restart 　(再起動)
sudo mysql -u (ユーザー名) 　 (ログイン、接続)
mysql> exit                　(切断)
source [フォルダとファイル名]　(ファイルの実行)
```
###データベースの作成
ログインする。

```
CREATE DATABASE データベース名;   (データベース作成)
show databases;　　　　　　　     (データベースの一覧を確認)
DROP DATABASE データベース名;     (データベースの削除)
USE データベース名;               (操作するデータベース選択)
```
###テーブルの作成
・データ型
INT（整数）
DOUBLE（小数）
VARCHAR（可変長の文字列）
TEXT（文章用の長い文字列）
TIMESTAMP（日付時刻型）

以下は例です。

```
CREATE TABLE データベース名.テーブル名 (
    id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    title VARCHAR(100),
    price INT,
    created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
```

###テーブル一覧と設計内容の確認

```
SHOW tables;         (テーブル一覧)
DESCRIBE テーブル名;  (設計内容の確認)
DROP TABLE データベース名.テーブル名;   (テーブルの削除)
```

###データの作成、保存と取得と更新と削除

```
INSERT INTO テーブル名 (カラム1、カラム2)　VALUES　(値1、値2);   (作成)
SELECT カラム名 FROM テーブル名;   (データの取得。*を使うとすべてのカラム。)
UPDATE テーブル名　SET カラム名1　= 値1, カラム名2 = 値2;   (更新)
DELETE FROM テーブル名; (削除)
```

###条件で絞込み

```
WHERE カラム名 = 値;
```

###表示順の並び替え
テーブル内部の順番は変わらず、表示だけ変わる。
データ量が多いと負荷がかかる。

```
SELECT カラム名　FROM　テーブル名　OREDER BY　カラム名;　　　(データを昇順に並び替え)
SELECT カラム名　FROM　テーブル名　OREDER BY　カラム名　DESC;　　　(データを降順に並び替え)
```

###集計関数での分析

COUNT関数
　WHEREを用いて条件に合ったものだけカウントもできる。

```
SERECT COUNT(*)　FROM テーブル名;　　　(レコードの数)
```

SUN関数
　合計を表示。

```
SELECT SUN (カラム名)　FROM　テーブル名;   (合計値を表示)
```

AVG関数
　平均を表示。

```
SELECT AVG (カラム名)　FROM テーブル名;   (平均値を表示)
```
[Tableau]クエリパイプラインの必要性をざっくり理解したい

今回はクエリパイプラインについて、ざっくり理解しつつまとめていきたいと思います。

Tableauをやるならクエリパイプラインは暗記すべし！ 的な記載もよく見かけますが、今回はまず、

> 「クエリパイプラインってなんのこっちゃ」
「なにがそんなに大事なのさ？」

というところが理解できれば良いくらいの温度感で整理したいと思います。
ので、あまり細かいところは書きません。

# クエリパイプラインってなんのこっちゃ？

クエリのパイプライン…？

Tableauの用語ってわりと日本語訳されてることが多いと思うんですが、こいつはカタカナ語のままなのでなんとなくイメージしづらい用語だなと思います。

端的に言えば、**Tableauがデータを取ってきて表示するまでの処理順** のことです。
何かの機能名とかではなく、概念を指す言葉なのです。

<br/>
公式ドキュメントには↓の図が載っていますが、この順番に処理が進んでいくよー、ということですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513463/ea926888-91ce-cc13-c3ef-4e6e625ea4bc.png)
（出典 https://help.tableau.com/current/pro/desktop/ja-jp/order_of_operations.htm）

日本語ドキュメントだけどこの図は英語なのでちょっと身構えてしまいますが、例えばDimension Filters（ディメンションフィルター）はTable Calc Filters（表計算フィルター）より上にある（=先に実行される）とかがわかります。

なんだそれだけか、という感じ。
特に難しい話ではありませんね。

# なにがそんなに大事なのさ？

では、Tableauの処理の実行順が、なんでそんなに大事なのか？という話です。

Tableauが勝手にやるんだから別に知らなくていいじゃん、と思わなくもありませんが、これを理解しているとしていないとでは、Vizを作る上で
`「ああ！　もう！ なんでそうなるんだよ！」`
と憤怒する回数が大きく変わってきます。

## 例 フィルターしたら表計算の値が変わった！

個人的によくぶつかるのが、表計算でうまく行かないケースです。

なぜかというと、上記のクエリパイプラインの図にあるように、表計算（Table Calc）は実行順がかなり下の方。
つまり、他の計算の影響を受けやすい位置にいるからです。

例えば、サブカテゴリごとに表計算の「合計に対する割合」を使って↓のようなグラフを作るとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513463/48f1aad0-7912-a7d3-e863-39e9c717ea0c.png)

ここで、カテゴリのフィルターで「家電」を除外します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513463/14b84ef8-035b-6169-c169-ff19a0f1f673.png)

よしよし、家具と事務用品だけになったな！
…と思ってよく見ると、「椅子」の値が21%になっています。
フィルターをかける前は13%だったのに、値が変わっている！ となるわけです。

この挙動を期待していたなら万事OK!なのですが、あくまで全カテゴリの中の割合をみたいケースでは、困ってしまいます。

## なんでこうなるのか？

お察しの通り、21%というのは家具と事務用品カテゴリの合計に対しての割合です。
家電がなくなった分、分母が減ったので相対的に椅子の割合が増えたわけですね。

クエリパイプラインの話で言うと、

1. カテゴリのフィルター（ディメンションフィルター）を適用して、家電を除外する
1. 「合計に対する割合」の表計算を適用して、割合を計算する

と言う順序なので、割合を計算する時点で家電が既に除外されてしまい、家具と事務用品だけの件数を100%とした値になるわけです。

## どうすればよい？

これを解消するには、フィルターと割合計算の順番を逆にする必要があります。

<br/>

「合計に対する割合」の計算式を見てみると、↓のようになっています。

> SUM([売上]) / TOTAL(SUM([売上]))

分子である`SUM([売上])`は、サブカテゴリのディメンションの影響を受けて、サブカテゴリごとに売上合計になります。

そして分母の方にある`TOTAL`関数は、各ディメンションの`SUM([売上])`の合計を求める表計算関数です
こいつが表計算関数なので、ディメンションにフィルターがかかった後、つまり「家電」カテゴリが除外された後に実施されることになります。

なので、この分母を求める式を変えて↓のようにしてみます。

> SUM([売上]) / MAX({FIXED: SUM([売上])})

`{FIXED: SUM([売上])}`は、LOD関数である`FIXED`を使って、ディメンションで区切らずに（つまり全体の）売上合計を求めています。

ちなみに、LOD関数はその結果が非集計として扱われるため、集計関数であるSUM([売上])との混在ができません。
なので、無理やり集計関数にするためにMAXをつけています。（値は全て同じなのでMINでもAVGでも良い）

https://qiita.com/Horino_Yohei/items/f82dca6d3ab0af7f4291

話を戻すと、このFIXEDを使った表現は、ディメンションをまたいで合計を求めると言う点ではTOTALと同じですが、クエリパイプライン上では大きく意味が異なります。

前述のクエリパイプラインの図をみると、**FIXEDの処理はディメンションフィルターよりも1つ上**に位置しています。
つまり、このFIXEDを使った合計の計算は、「家電」カテゴリを除外する前の全カテゴリを対象とした合計になるわけです。

Vizの方を変更してみると、今度は想定どおり、椅子が13%のままで家電カテゴリを除外できていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1513463/ed93c34f-b5a1-fbdb-abfa-4d839c915aae.png)

# まとめ

Tableauのデータ処理順であるクエリパイプラインが、Vizを作る上でどう影響してくるかのなんとなくのイメージがつきましたでしょうか？

特にフィルター周りで、期待していた結果となんか違う！ というケースは、このクエリパイプラインが関係している場合が多いと思います。
パイプラインを丸暗記はしなくても良いと思いますが、怪しいなと思ったらあの図を参照してみるということができれば、課題解決力がぐんとアップするはずです。

<br/>

この記事で6本目なのでDataSaberのお題としてはクリアなのですが、やっぱり記事にアウトプットすると自分の理解もクリアになるので、ゆるりと続けていきたい気持ちです。
WSLのLinuxからWindows10側のPostreSQL(などのサーバー)を呼び出す

# 経緯

- WSLのLinxからWindows10側のPostgreSQL(などのサーバー)を呼び出そうとして、すぐにできなかったのでメモ
- WSLのLinuxとWindows 10間の通信で考慮することがある
- 結構、大変なので、WSL側にPostgreSQL Serverを入れるなどを検討した方がよいのかもしれない

# 環境

## Windows 10 側

- Windows 10 
- postgresql-13.3-2-windows-x64.exe
- Windows Terminal
- WSL2

## WSL Ubuntu 側

- Windows Subsystem for Linux Ubuntu 20.04
- postgresql-client-common
- postgresql-client-12
- net-tools


```bash
sudo apt install postgresql-client-common
sudo apt install postgresql-client-12
sudo apt install net-tools
```

# WSLのLinux上でのIPアドレスを確認(WSLの操作)

```
ifconfig
```

# WSLからWindows 10側にアクセスするためのIPアドレスを取得する(WSLの操作)

- nameserverがWindows10側のIPになるのを利用している？ (*1を参考にした)


```
grep nameserver /etc/resolv.conf | awk '{print $2}'
```

- 起動の度にIPが変わるようなので、Windows10側のIPを書きだすコマンドを .bashrc に追加するなどの仕組みが必要そう (*1 ではhostsに追記しているようだ)
- 今回は試していないが、以下が *1 にあるの内容

```
cat /etc/hosts | grep 172.; test $? -eq 0 && $1 || echo -e "$(grep nameserver /etc/resolv.conf | awk '{print $2, " host"}')\n$(cat /etc/hosts)" | sudo tee /etc/hosts
```

# PostgreSQL Client Authentication Configuration File(アクセス制御)の設定 (Windows 10側の設定)

- PostgreSQL の pg_hba.conf を編集


# 場所

```
C:\Program Files\PostgreSQL\13\data\
```

# 編集内容例

- WSLから通信できるように設定する
- (クラスBのプライベートIPアドレスを指定したつもりだが正しいだろうか)

```
host    all             all             172.16.0.0/12           trust
```

# アンチウィルスなどのセキュリティアプリの設定

- 各アプリで、通信できるように設定を見直す

# Windows Defender Firewallの設定例

- 「受信の規則」で「プロトコルおよびポート」を開放
- 「スコープ」を指定して、IPアドレスを指定

![defender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/eb2973d7-d423-212a-74a8-883529df99c0.png)

![rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/f7c708af-cb6c-2cfc-08b5-efc93a9f3f42.png)

![port.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/5a1f0c4c-7ed8-cdd9-149a-2c2bb008caf9.png)

![range.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1083912/24174c24-f6d7-2049-e0be-72b8cc94a3e4.png)



# psqlの実行

```
psql -h 172.x.x.x -U postgres
```


# 参考資料

- *1 https://stackoverflow.com/questions/56824788/how-to-connect-to-windows-postgres-database-from-wsl
fvm導入後にfvmでインストールしたFlutterが使われない

# 概要
Flutter2を簡単に試すためにfvm(Flutterのバージョン管理ツール)を導入しました。導入方法は適当なサイトで見て導入していて、使い方が完全に間違っていたので共有します。

# fvmの使い方

```
> fvm flutter {command}
```

fvm導入後は上記のコマンドでbuildなどを実行してください。fvm導入前のようにflutter {command}で実行すると他のバージョンが参照される可能性があります。

また、下記のように直接flutterのsdkを叩く方法もあります。

```
.fvm/flutter_sdk/bin/flutter {command}
```


# 最後に
公式ドキュメントは読もう!:https://fvm.app/docs/guides/running_flutter
Immutable Tableを試す(2)（Oracle Database 19c)

[前記事](https://qiita.com/plusultra/items/f5176d98975d863d81e6)ではImmutable Tableの作成を試したので、本記事ではImmutable Tableに対する操作を行います。

# DMLの制約
## INSERT文の実行
INSERT文には制約はありません。トランザクション制御にも変更はありません。

```
SQL> INSERT INTO immutable1 VALUES (100, 'data1');

1行が作成されました。

SQL> COMMIT;

コミットが完了しました。

SQL> SELECT * FROM immutable1;

        C1 C2
---------- ----------
       100 data1
```

## UPDATE文の実行
UPDATE文は更新対象のレコード有無にかかわらず失敗します。下記の例では更新対象レコード（WHERE c1=300）は存在しませんが、エラーORA-05715が発生しています。

```
SQL> UPDATE immutable1 SET c2='update' WHERE c1=300;
UPDATE immutable1 SET c2='update' WHERE c1=300
       *
行1でエラーが発生しました。:
ORA-05715: operation not allowed on the blockchain or immutable table
```

## DELETE文の実行
DELETE文の実行も失敗します。レコードの削除はDBMS_IMMUTABLE_TABLEパッケージを使います。

```
SQL> DELETE FROM immutable1 WHERE c1=100;
DELETE FROM immutable1 WHERE c1=100
            *
行1でエラーが発生しました。:
ORA-05715: operation not allowed on the blockchain or immutable table
```

# DDLの制約
## TRUNCATE文の実行
  TRUNCATE TABLE文は実行できません。

```
SQL> TRUNCATE TABLE immutable1;
TRUNCATE TABLE immutable1
               *
行1でエラーが発生しました。:
ORA-05715: operation not allowed on the blockchain or immutable table
```

## DROP TABLE文の実行
　テーブル作成直後の場合、DROP TABLE文は成功します。

```
SQL> CREATE IMMUTABLE TABLE immutable2 (c1 NUMBER, c2 VARCHAR2(10))
  2        NO DROP UNTIL 1 DAYS IDLE
  3        NO DELETE UNTIL 16 DAYS AFTER INSERT
  4        TABLESPACE blockts1;

表が作成されました。

SQL> DROP TABLE immutable2;

表が削除されました。
```

しかしレコードが格納された状態ではDROP TABLE文は指定された期間失敗します。

```
SQL> DROP TABLE immutable1;
DROP TABLE immutable1
           *
行1でエラーが発生しました。:
ORA-05723: drop blockchain or immutable table IMMUTABLE1 not allowed
```

## ALTER TABLE文の実行
列の追加や削除は失敗しますが、制約の追加／削除は成功します。

```
SQL> ALTER TABLE immutable1 DROP COLUMN c2;
ALTER TABLE immutable1 DROP COLUMN c2
*
行1でエラーが発生しました。:
ORA-05715: operation not allowed on the blockchain or immutable table

SQL>  ALTER TABLE immutable1 ADD (c3 VARCHAR2(10));
 ALTER TABLE immutable1 ADD (c3 VARCHAR2(10))
*
行1でエラーが発生しました。:
ORA-05715: operation not allowed on the blockchain or immutable table

SQL> ALTER TABLE immutable1 ADD CONSTRAINT pk_immutable1 PRIMARY KEY (c1);

表が変更されました。
```

テーブル削除の制限期間はデフォルト設定では変更することができます。しかし現在の値よりも短くすることはできません。

```
SQL> ALTER TABLE immutable1 NO DROP UNTIL 2 DAYS IDLE;

表が変更されました。

SQL> SELECT table_name, table_inactivity_retention FROM user_immutable_tables;

TABLE_NAME                     TABLE_INACTIVITY_RETENTION
------------------------------ --------------------------
IMMUTABLE1                                              2

SQL> ALTER TABLE immutable1 NO DROP UNTIL 1 DAYS IDLE;
ALTER TABLE immutable1 NO DROP UNTIL 1 DAYS IDLE
*
行1でエラーが発生しました。:
ORA-05732: retention value cannot be lowered
```
unity5.2の作法 その12 mouse

#概要

unity5.2の作法、調べてみた。
マウスにひっつくやつ、やってみた。

#makefile

- menu->file->new sceneする。
- menu->file->save sceneでboxとする。
- menu->gameobject->create emptyする。
- menu->assetes->creates->c# scriptでbox.csつくる。
- ダブルクリックして、コードを書く。
- ヒエラルキーのgameobjectに、コードを重ねる。
- 三角で実行。

#サンプルコード

```
using UnityEngine;
using System.Collections;

public class box : MonoBehaviour {
	void Start () {
	}
	void Update () {
	}
    void OnGUI() {
        GUI.color = Color.yellow;
        GUI.Box(new Rect(Input.mousePosition.x, Screen.height - Input.mousePosition.y, 50, 50), "A BOX");
    }
}



```

以上。
備忘：AnacondaのPip SSLエラー(Windows10)

pip関係をインストール・アップデートしようとした際のSSLエラーについて、
多くの記事・コメントがプロキシ問題と書かれているが、プロキシが正しく設定されても下記SSLエラーが出たため、備忘録として残しておく。
Could not fetch URL https://pypi.org/xxx/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /xxx/ (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1125)'))) - skipping


①まずはプロキシ設定の確認
Anaconda promptでconda info --all で確認
ちゃんと下記になっているか。
http: http://proxy.aaa.bbb.co.jp:8080
https: http://proxy.aaa.bbb.co.jp:8080 ※httpsではエラーになる
ちなみにusername:passwordは別にいれなくてもいける

②conda自体の動作確認
conda update condaでエラーになるか実行してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185944/eefd842b-888f-0a89-7d22-38eae54d7927.png)
普通にアップデートできたのでプロキシの問題ではなさそう。

③pipでCythonをインストールしてみる
なのにpip関係をアップデート・インストールしようとした際にプロキシと思われるエラーが発生した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185944/490872a9-bb94-58cd-4c48-bad2ca9acfcb.png)

解決方法：
1)まずconda listを実行し、pipバージョンを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185944/5beca51c-4ec5-0543-867a-30f2325a541c.png)

pip ver.21.x.x以降ではなぜかサーバーに通れないので、pipをダウングレードしないといけない。
(ver.20.3.xもいけたりいけなっかたりって聞いたけど、試してない。）

そのため、古いバージョンの20.2.3をインストール：
conda install pip=20.2.3を実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185944/49d0ae16-3a0e-4e56-ae0d-47b19e7f6c09.png)

もう一回Cythonをインストールしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185944/53355bae-08ee-362b-e409-65f1c013c735.png)
やっと解決できた。。。
WSL2でUbuntu(20.04.2LTS)で最新のGolangをaptでインストールする

# はじめに
こんにちは。先ほど1年間無料のネット回線として契約してたRakuten UN-LIMITを解約しました :pray:
テレワークでとっても便利でしたが、都内から川崎市に引っ越してからパートナー回線しかつながらなくてほったらかししてました。

パートナー回線だと付き5GBで制限掛かるので使い物になりませんでした。

エリア内のはずなのに :thinking: 

さて、今回はGolangを始めようと思い立ち、インストールしていこうと思います！
インストール方法はいろいろあると思いますが、**apt**で入れていこうと思います。

# WSL2でUbuntu(20.04.2LTS)で最新のGolangをaptでインストールする
公式GitHubのWikiを参考に進めていきます :pray:

https://github.com/golang/go/wiki/Ubuntu

## 1. リポジトリ追加
最新バージョンが欲しいのでPPAの追加します。
Enterキー押してと言われると思うので押してください:pray:

```sh
$ sudo add-apt-repository ppa:longsleep/golang-backports

 Golang 1.8, 1.9, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15 and 1.16 PPA for Ubuntu
 More info: https://launchpad.net/~longsleep/+archive/ubuntu/golang-backports
Press [ENTER] to continue or Ctrl-c to cancel adding it.

Hit:1 https://cli-assets.heroku.com/apt ./ InRelease
Get:2 http://ppa.launchpad.net/longsleep/golang-backports/ubuntu focal InRelease [17.5 kB]
Get:3 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Hit:4 http://ppa.launchpad.net/ondrej/php/ubuntu focal InRelease
Hit:5 http://archive.ubuntu.com/ubuntu focal InRelease
Get:6 http://ppa.launchpad.net/longsleep/golang-backports/ubuntu focal/main amd64 Packages [2512 B]
Get:7 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:8 http://ppa.launchpad.net/longsleep/golang-backports/ubuntu focal/main Translation-en [1568 B]
Get:9 http://archive.ubuntu.com/ubuntu focal-backports InRelease [101 kB]
Get:10 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [1077 kB]
Get:11 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 Packages [825 kB]
Fetched 2252 kB in 7s (309 kB/s)
Reading package lists... Done
```

## 2. おなじみの`apt update`

```
$ sudo apt update
```

## 3. インストール
golang-goはデフォルトで最新バージョンをインストールするので指定は不要 :ok_hand: 

```sh
$ sudo apt install -y golang-go
```

## 4. バージョン確認
インストール完了しました！

```sh
$ go version

go version go1.16.5 linux/amd64
```

# おわりに
意外と簡単にインストールできました:v:
それでは！
ServiceNow - Upgrade Centerを利用する（商用版インスタンス）

# 概要
Upgrade Centerを利用して商用ServiceNowインスタンスをアップグレードする手順メモ。
Upgrade Centerを利用するとServiceNowインスタンス内からアップグレードを確認及び予約することができます。

# 手順
1. アプリケーションナビゲータから「upgrade center」を検索して「Upgrade Preview」を選択。<br/>![upgrade_center_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/0ca46abe-aaea-bbce-8082-d06e27a2584a.png)
1. アップグレードするリビジョンを選択。<br/>![upgrade_center_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/3640d920-b7be-89df-b169-50bb9856af9a.png)
1. プレビューが表示されない場合は「Go」ボタンを押下。<br/>![upgrade_center_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/f0af63e0-d19c-4abc-db40-1dc115d655ee.png)
1. プレビューが表示される。「View preview details」リンクを選択して詳細を表示。<br/>![upgrade_center_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/db205b25-178b-ff6e-4dd1-b03daeb2cbca.png)
1. 「Predicted Skips to Review」、「Predicted Skips Reviewed」、「Previewed Changes」タブを選択して詳細を表示。「Previewed Changes」タブの「Resolution」ヘッダを選択してレビューが必要な項目があるか確認。<br/>![upgrade_center_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/efe832fe-803b-834c-79ba-5322c38b2fab.png)
1. 確認した後は前のページに戻る。<br/>![upgrade_center_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/5a318ffb-3ea9-3421-aed2-e03a7e9f74b8.png)
1. 「To review」、「Predicted skipped records by priority」、「Automated Test Framework (ATF) results」の内容を確認して問題が発生する箇所があるかを確認。<br/>![upgrade_center_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/6e64d5d9-e869-cade-9e53-ad153a5037f2.png)
1. 問題がない場合は「Schedule upgrade」ボタンを押下してアップグレードを予約する。<br/>![upgrade_center_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/79da8813-a4ec-5cc1-83e1-206a5b13a1ab.png)

以上
Athena に `mismatched input 'external'. expecting: 'or', 'schema', 'table', 'view' ` と言われた

Database 名に `-` (ハイフン) が含まれていたせいでした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8219/7cbe01d3-a66e-cdff-7f80-ead65897f03a.png)


どのように作成したか覚えていないですが、普通に `CREATE TABLE` する分にはハイフンを含む名前で Database を作成することは出来ないようですが、 Glue ベースで作成するとハイフン付きのデータベース名が作れてしまう気がする。
Macのターミナル(zsh)で表示される名前を短くする方法

筆者のMacの環境
・MacOS Big Sur 11.4
・ターミナルはzshシェル

この記事では、ターミナルに表示されるコンピューター名やユーザー名を表示せず、`$`のみを表示する方法を説明しています。

自分のサイトがzshシェルかわからないという方はターミナルに

```
echo $SHELL
```
と入力してください。

`/bin/zsh`と表示されたらzshシェルです。
##やり方##
まずはターミナルを開き

`touch .zshrc`と入力します
このコマンドで`.zshrcファイル`を作成します。`.zshrcファイル`はターミナルの表示内容を変更するのに必要なファイルです。

次に

```
open -e .zshrc
```

を入力します
これで先ほど作成した`.zshrcファイル`を開きます
![スクリーンショット 2021-06-30 8.55.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1709437/35247537-d141-23c9-225e-f689690baa37.png)



最後に開かれた`.zshrcファイル`内に

```
PROMPT='$ '
```
と入力し、command+sをします。(可読性を高めるために`$`の後に空白を入れています。)
`.zshrcファイル`を閉じてからターミナルに

```
source ~/.zshrc
```
と入力したら設定が反映されます。
その後にターミナルを一度閉じてから、再度開きます。

すると![ターミナル.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1709437/3843689f-f24b-7c4d-91bb-fe38e676f8e1.jpeg)

このように`$`マークだけが表示されるようになります。

##参考サイト一覧##

https://medium.com/@ajaykarwal/edit-the-terminal-prompt-name-on-macos-4d80163be6a1

https://qiita.com/tonkotsuboy_com/items/b752a86cee7eaedf28da
【Devise導入手順】インストールと設定方法

Railsで簡単にログイン機能を実装できる devise の導入手順をまとめてみました。
この手順通りに設定を進めれば、問題なく実装できるはずです！
<h2>Gemfileの一番下に gem 'devise' を記述</h2>
まずはGemfileに記述します

```
gem 'devise'
```

<h2>ターミナルで bundle install を実行</h2>
Gemfileに記述 ＋ bundle install をすることで Gemfile.lock に追加されます

```
$ bundle install
```

<h2>ターミナルで rails g devise:install を実行</h2>
これで devise 関連のディレクトリやファイルが追加されます

```
$ rails g devise:install
```

<h2>各ファイルに設定を追加</h2>
rails g devise:install を実行するとターミナルに下記の文章が出てきます
番号通りに４つの設定を追加していきます

```
===============================================================================

Depending on your application's configuration some manual setup may be required:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.

     * Required for all applications. *

  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"
     
     * Not required for API-only Applications *

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

     * Not required for API-only Applications *

  4. You can copy Devise views (for customization) to your app by running:

       rails g devise:views
       
     * Not required *

===============================================================================
```

<h3>① config/environments/development.rb の一番下にコードを追加</h3>
デフォルトURLの設定

```
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
```

<h3>② config/routes.rb に下記コードを追加</h3>
ルーティングの設定

```
root to: "home#index"
```

<h3>③ app/views/layouts/application.html.erb に下記コードを追加</h3>
フラッシュメッセージの追加

```
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
```

<h3>④ ターミナルで rails g devise:views を実行</h3>
devise 関連の view を作成

```
$ rails g devise:views
```

<h2>ターミナルで rails g devise userを実行</h2>
User model を作成(model名は任意)

```
$ rails g devise user
```

<h2>rails db:migrateを実行</h2>
users テーブルを作成

```
$ rails db:migrate
```

以上で devise 関連の設定は終了です！
お疲れさまでした！
Nuxt.jsにnuxt-storybookを導入する

Nuxt.jsにStorybookを導入したら事あるごとにエラー発生して心折れかけていたところ、
nuxt専用のStorybookがすべて解決してくれた話。

# 公式ドキュメント
https://storybook.nuxtjs.org/

# 導入

```
# npm i -D @nuxtjs/storybook
```

ビルド時にインストールしろと言われたので以下も必要かもしれない

```
# npm i -D postcss@latest @storybook/addon-actions @storybook/addon-docs

```

# 起動

```
# npx nuxt-storybook
```

# 設定
## storiesのディレクトリを変更する
```nuxt.config.js
export default {
  //略
  storybook: {
    "stories": [
      "~/_stories/**/*.stories.mdx",
      "~/_stories/**/*.stories.@(js|jsx|ts|tsx)"
    ],
```

## Globalなcssの呼び出し方
styleResourcesで読み込んだCSSが読み込まれない件。
模索中です。
ドキュメントに載ってない。。。

【追記】
**→いつの間にか読まれてました。**
むしろ設定から読まれてない方が不思議だったのだけど。
にしてもなぜ。。。
入れない理由がない、便利なgooglechromeアドオン一覧




-------------------
## Adblock Plus 

https://chrome.google.com/webstore/detail/adblock-plus-free-ad-bloc/cfhdojbkjhnklbpkdaibdccddilifddb?hl=ja
PC画面を汚染する不用なポップアップ広告をブロックしてくれる。
入れない理由がない。



## google翻訳アドオン版

英文ページやその他の言語も翻訳してくれる。
入れない理由がない。

## chrome remote desktop

ネットに繋がっていれば、ログインしてるgoogleアカウントを使って
リモートデスクトップで別のPCをリモート操作可能。
便利だが不正利用されないよう注意。

## LastPass: Free Password Manager
https://chrome.google.com/webstore/detail/lastpass-free-password-ma/hdokiejnpimakedhajhdlcegeplioahd?hl=ja

LastPassアカウントにパスワードを設定することで
パスワードの管理をやってくれる。
使えるようになるとセキュリティ面も上がるし便利。


## Absolute Enable Right Click & Copy
https://chrome.google.com/webstore/detail/absolute-enable-right-cli/jdocbkpgdakpekjlhemmfcncgdjeiika?hl=ja

よくwebにあるコピーガード機能
（右クリック禁止）（文字選択禁止）（コピー禁止）（解析禁止）を
完全に解除してくれる。
入れない理由がない。



-----
## AWS Extend Switch Roles

https://chrome.google.com/webstore/detail/aws-extend-switch-roles/jpmkfafbacpgapdghgdpembnojdlgkdl?hl=ja

awsの開発者向けのアカウント管理アドオン。
設定さえすれば組織に作った複数のawsアカウント等を一瞬で切り替えることができる。
Golang 標準入力

###よくあるパターン①　n回ループして各値を受け取る
```
5
3 1 2 4 5
```

```
package main
 
import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)
 
var sc = bufio.NewScanner(os.Stdin) //読み取る準備完了
 
//これを呼ぶたびに入力を受け取る
func nextInt() int {
	sc.Scan()                         //まず読み込む
	ret, _ := strconv.Atoi(sc.Text()) //Textで実際に文字列を読み取る
	return ret
}
 
func main() {
	sc.Split(bufio.ScanWords) //スペース区切りでscanしたい
	n := nextInt()            //n回繰り返すために最初だけ入力を受け取る
	for i := 0; i < n; i++ {
		m := nextInt()	
	}
}
```



###よくあるパターン② 　空白区切りの数値を受け取りたい
```
0 1000
```
##### パターン1

```

package main
import "fmt"
func main(){
    var A,B float64
    fmt.Scan(&A) //fmt.Scanは空白、改行までを取ってくる
    fmt.Scan(&B)
    fmt.Printf(A,B)
    #=>0 1000
}
```

##### パターン2

```

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int {
	sc.Scan()
	ret, _ := strconv.Atoi(sc.Text())
	return ret
}

func main() {
	sc.Split(bufio.ScanWords) //スペースで文字列を区切る
	a := float64(nextInt())
	b := float64(nextInt())

	fmt.Printf(A,B)
        #=>0 1000
}

```

### よくあるパターン③ 一つだけ受け取りたい

```
180
```

```
package main
 
import (
	"fmt"
)
 
func main() {
	var a int
	fmt.Scan(&a)
}

```
CypressでVue.jsのE2Eテストをしてみる


## Cypressとは？

#### E2Eテストフレームワーク
JavascriptフレームワークのFrontend開発者向けに作られたフレームワークで
手安くEnd-to-Endテストができる。

#### Javascriptで操作
Javascriptを使って、Domイベントを直接操作する。
Domイベントを直接操作によって、NightWatchより便利な使い方ができる。

#### WebDriver不要
Seleniumの場合とは違って、WebDriverは不要。CypressをインストールするだけでOK。

#### 色んなブラウザーでテスト可能
Chromeはもちろん、Firefox、Edge、Electron、Brave上でも動かせる。

#### テスト機能
Cypress.ioに加入すると、無料で500件までのテスト実行画面のレコーディングも可能。ダッシュボードでテスト結果を見たり、テスト管理ができる機能がある。
https://www.toolsqa.com/cypress/cypress-dashboard-service/
コンポネントテストも出来るように、Pluginが用意されている。
https://docs.cypress.io/guides/component-testing/introduction#Writing-Component-Tests


## インストール

npmを使っているなら、簡単にインストールできる。

~~~
npm install cypress --save-dev
~~~
yarnを使っている場合は以下のコマンドを実行する。

~~~
yarn add cypress --dev
~~~


## テスト実行

基本的に、プロジェクトrootで以下のコマンドを実行してテストランナーを開く。

~~~
./node_modules/.bin/cypress open
~~~

npxコマンドでも実行できる。（npxは npm v5.2から含まれている。）　

~~~
npx cypress run
~~~

あるいは、yarnで実行。

~~~
yarn run cypress open
~~~

コマンドを実行すると、テストランナーが起動するので、ここでテスト一覧を見たりテストを実行したりする。

以下の画面が出たらテストの準備は完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544568/935b186c-5ce1-bef2-e58a-eab6ebe67da9.png)

tests タブにすべてのjsファイルが表示される。
テスト用jsファイルのリストは自動的に感知してくれる。sample testが入っている基本フォルダーは /cypress/integration

テストを実行すると、システム上のブラウザー画面でテストが実行され、ブラウザーコンソールから結果をリアルタイムで確認できる。


## コード作成

テストコードは以下の4つの段階に従って作成する。

1. テストページに接続
1. 要素を指定
1. 要素を操作して動かす（相互作用）
1. ページのコンテンツに対するassertionを実行


まず、新しいjsファイルを作成。/cypress/integration の下に sample_spec.jsファイルを作成する。
テストコードの基本的な形式は以下となる。

~~~
describe('Cypressテスト', () => {

it('テスト名', () => {

    // ここにテスト内容を作成
    expect(true).to.equal(false)
    })
})
~~~

#### ページ移動

テストしたいページに接続する。

~~~
cy.visit('https://example.cypress.io')
~~~

#### 要素を確認

'type'を含む要素を探す。

~~~
cy.contains('type')
~~~

#### 要素をクリック

'type'を含む要素を探してクリックする。

~~~
cy.contains('type').click()
~~~

#### assertion

.should()を利用して、assertionを作成する。

~~~
// urlが'/commands/actions'を含めているかチェック
cy.url().should('include', '/commands/actions')
~~~

## テスト画面

以下のコードでテストを実行してみた。
テストランナーから、作成したファイルをクリックするとブラウザーが開き、自動でテスト操作が始まる。

~~~
describe('Cypressテスト', () => {
    it('テスト1', () => {

        // ここにテスト内容を作成
        cy.visit('https://example.cypress.io')
        // Cypressはコンテンツがロードされるまで待ってくれる
        // cy.contains('type')
        // 'type'を含む要素を探して、クリックする
        cy.contains('type').click() 
        // クリックの結果、urlが'/commands/actions'を含めているかチェック
        cy.url().should('include', '/commands/actions')
    })
})
~~~

結果はこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1544568/551eae45-06e9-c63c-46f3-6a13edb48bd1.png)


APIはこちら。
https://docs.cypress.io/api/table-of-contents