OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntuにdebファイルをインストール

## debファイルがインストールできない
debファイルをダウンロード後、Ubuntuの「ソフトウェアのインストール」でのインストールができなかったため、コマンドを使ってインストールすることにした。

## apt
サイトからダウンロードしたファイルが存在するディレクトリに移動。

```
$ sudo apt install ./ダウンロードしたファイル名
```
上記のコマンドでインストールできるらしいが、自分のpcでは以下のエラーでインストールできなかった。原因はまだ調べていない。
[ファイル名]の部分は、インストールしたいファイルのパスが書かれている。

```
N: ファイル '[ファイル名]' がユーザ '_apt' からアクセスできないため、ダウンロードは root でサンドボックスを通さずに行われます。 - pkgAcquire::Run (13: 許可がありません)
```

## gdebi
aptと同じように、サイトからダウンロードしたファイルが存在するディレクトリに移動。

```
$ sudo gdebi ファイル名
```

gdebiでインストールしたらできました。何回か忘れているので記録しておきます。
アプリリリースしました　「Flexible Dice～シンプルで解析もできるダイスアプリ～」

play storeにて、アプリ
[Flexible Dice](https://play.google.com/store/apps/details?id=com.chelak.dice)をリリースしました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/6102ee3d-9058-12b2-3bac-ab0bcc81101c.png" width="160" height="326" class="jop-noMdConv"> <a href='https://play.google.com/store/apps/details?id=com.chelak.dice&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Google Play で手に入れよう' src='https://play.google.com/intl/en_us/badges/static/images/badges/ja_badge_web_generic.png'/ width="200"></a>

## 概要

1個2面～12個144面まで対応可能なシンプルなダイスアプリです。
これまでの出目を記録し、自動的に統計解析・グラフ化します。

TRPG、ゲームブック、すごろくの順番決めやマージャンなどのサイコロを使ったボードゲームに最適です。
ネットカフェでの暇つぶしにも。
<br>
２作目でFirebaseも使っていないので１週間強くらいで開発できました。

## 使い方

■各画面の説明
・Dice（ダイス）画面
CASTボタンでダイスを振り、STOPボタンで止めます。
SUMに合計値が表示されます。
左上に現在の設定が表示されています。（例：1個6面の場合＝1D6）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/77543573-802c-11c1-ad30-774605005516.png" alt="通知.png" width="165" height="293">　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/8d72ede6-8435-bb7f-80d4-43c0111db575.png" alt="通知.png" width="165" height="293">

・Analysis（解析）画面
設定中のダイス数/面でこれまで出した出目（合計値）を記録しています。
RESET DATAボタンでこれまでの記録を初期化できます。
青線：これまでの出目です。
赤線：その時点までの出目の平均値です。
黒線：出目の期待値です。
※ダイスをたくさん振ると赤線が黒線に近づいていくはずです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/cca0d7af-5b47-ef11-02fc-f7e862aa3c4f.png" width="165" height="293">

・Settings（設定）画面
ダイス数/面を変更できます。
number（ダイス数）とface（ダイス面の数）を選択し、SETを押すと設定を変更できます。
※設定時、数秒程度の広告動画が流れます。音量にご注意ください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/b7681880-f91c-3e44-915e-9aeb1db5faea.png" width="165" height="293">


***  
感想等頂けると嬉しいです。DLはこちらから↓  
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1344513/6102ee3d-9058-12b2-3bac-ab0bcc81101c.png" width="160" height="326" class="jop-noMdConv"> <a href='https://play.google.com/store/apps/details?id=com.chelak.dice&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Google Play で手に入れよう' src='https://play.google.com/intl/en_us/badges/static/images/badges/ja_badge_web_generic.png'/ width="200"></a>
date-fnsで日時をフォーマットしたり、パースする

Javascriptで日付操作をするライブラリとして、[date-fns](https://date-fns.org/)を重用しています。
これまでは[moment.js](https://momentjs.com/)や[dayjs](https://day.js.org/)などが使われていたみたいですが
momentは開発が止まっていたり、date-fnsの方が関数型で個人的に読みやすいので
今関わっている案件でもmoment => date-fnsに書き換える作業などを行なっています。

という事で今回は、date-fnsでよく使っている操作を紹介したいと思います。

### フォーマット

```javascript
import { format } from 'date-fns' 
import ja from 'date-fns/locale/ja'

console.log(new Date())

// Dateオブジェクト => yyyy/MM/dd
format(new Date(), 'yyyy/MM/dd')

// Dateオブジェクト => yyyy/MM/dd HH:mm
format(new Date(), 'yyyy/MM/dd HH:mm')

// Dateオブジェクト => yyyy年MM月dd日
format(new Date(), 'yyyy年MM月dd日', { locale: ja })

// Dateオブジェクト => yyyy年MM月dd日(曜日)
format(new Date(), 'yyyy年MM月dd日(eee)', { locale: ja })
```

### パース

```javascript
import { parse, parseISO } from 'date-fns' 
import ja from 'date-fns/locale/ja'

// yyyy/MM/dd => Date
parse('2021/08/21', 'yyyy/MM/dd', new Date())

// yyyy年MM月dd日 => Date
parse('2021年08月21日', 'yyyy年MM月dd日', new Date(), { locale: ja })

// ISO8601 => Date
parse('2021-08-21T09:00:00', 'yyyy-MM-ddTHH:mm:ss', new Date())
// または、これでも良い
parseISO('2021-08-21T09:00:00')
```

### パースとフォーマットを同時にやる

```javascript
import { format, parse, parseISO } from 'date-fns' 
import ja from 'date-fns/locale/ja'

// yyyy/MM/dd => yyyy年MM月dd日
format(
  parse('2021/08/21', 'yyyy/MM/dd', new Date()),
  'yyyy年MM月dd日',
  { locale: ja }
)

// ISO8601 => yyyy年MM月dd日
format(
  parseISO('2021-08-21T09:00:00'),
  'yyyy年MM月dd日',
  { locale: ja }
)
```
[Ruby] all?メソッド

##はじめに
all?というメソッドを見つけました。
私的には少し使い方が変わっていると感じました。とても便利なので記事で残しておきます。

##all?メソッド

配列に対して使用します。（配列でなくてもいいのかも？）
all?の後に{}を用意し、その中にブロック変数と条件式を記述します。
ブロック変数にall?直前の配列の要素を一つずつ放り込み、その配列の全ての要素が条件式で~~true~~ 真だったときに初めてtrueを返します。

一つでも~~false~~ 偽があるとfalseを返します。

```ruby
array = [1, 2, 3, 4, 5, 6]
array.all?{|x| x > 0 }
=> true

array = [0, 1, 2, 3, 4, 5, 6]
array.all?{|x| x > 0 }
=> false
```


参考: https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/all=3f.html
xrdp on ubuntu 18.04 (remote desktop) 黒画面の問題の回避

Ubuntu 18.04でのRDP (Remote Desktop)は、黒画面でつながりませんでしたので、いろいろとtrouble shootしたことを書きます。

```
$ sudo apt-get install xrdp
$ sudo ufw allow 3389
```

普通はこれだけでいけるんですが・・・真っ黒のままうんともすんとも・・・

```/etc/xrdp/xrdp.ini 
max_bpp=24
```

皆trouble shootでなぜかubuntu-mateを入れているので、僕もトライ

```
sudo apt install ubuntu-mate-desktop -y
```

```/etc/xrdp/startwm.sh
unset DBUS_SESSION_BUS_ADDRESS
export GTK_IM_MODULE=ibus
export QT_IM_MODULE=ibus
export XMODIFIERS="@im=ibus"
ibus-daemon -d
exec mate-session
test -x /etc/X11/Xsession && exec /etc/X11/Xsession
exec /bin/sh /etc/X11/Xsession
```

```
$ vim ~/.xsessionrc
```

```~/.xsessionrc
export GNOME_SHELL_SESSION_MODE=ubuntu
export XDG_CURRENT_DESKTOP=ubuntu:GNOME
export XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share:/usr/share:/var/lib/snapd/desktop
export XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
```

```/etc/xrdp/sesman.ini
[Chansrv]
; drive redirection, defaults to xrdp_client if not set
FuseMountName=.thinclient_drives
```


```
$ sudo apt-get install xrdp-pulseaudio-installer -y
$ sudo apt-get install xorgxrdp-hwe-18.04 -y
$ sudo vim /etc/X11/Xwrapper.config
```

```/etc/X11/Xwrapper.config
allowed_users=anybody
```

全部やったら直りましたが、多分、

```
sudo apt-get install xorgxrdp-hwe-18.04 -y
```

と

```/etc/X11/Xwrapper.config
allowed_users=anybody
```

でいけるんじゃないかなーとも思っています。

ちなみに、

```
$ sudo apt-get install xorgxrdp -y
```

が、依存関係の問題でだめといわれるために、上の ```xorgxrdp-hwe-18.04``` を指定しています。
多分、nVIDIAのドライバーを有効にしているので、そのあたりが影響しているのかも。
【Ruby】保存されている複数画像のうち1枚だけ表示した場合について

現在作成中のアプリケーションにて、画像表示について表題のような挙動にしたかったのですが、解決まで時間がかかったので備忘録用に。


##状況
1つの店舗に対して複数の画像を投稿できる機能を追加しました。
トップページ、詳細ページどちらも投稿された画像が全て表示されています。
トップページでは店舗の外観画像のみ表示し、詳細ページでは店舗外観とその他画像が確認できるようにしたい。
　　　
以下解決前コード

```rb
<% store.images.each do |image|  %>
 <div class="messages">
 <%= link_to image_tag( image, class: :card__img, size: '300x300'), store_path(store)  %>
 </div>
<% end %>
```
　　　
上記コードではstoreモデルが持っている画像を全件表示する、というコードになっていました。
削除後、下記コードに変更したところ解決しました。
とても単純でした。

```rb
  <%= link_to image_tag( store.images[0], class: :card__img, size: '300x300'), store_path(store) %>
```
1つの店舗に対して1枚目に外観画像、2枚目に店内画像を保存しているので、1枚目の指定つまり添字で[0]を指定するだけで実現できました。
What is MailServer?

メールサーバーとは、**メールの送受信を行うサーバーのこと**です。
Webサーバー、ファイルサーバー、DBサーバー、FTPサーバー...などあり、そのうちの一つなのです。
あなた送信したメールは、メールサーバーを経由して相手に届けられます。

## メールサーバーは３種構成
メールサーバーは、それぞれ異なった役割を持つ『SMTPサーバー』と『POPサーバー』『IMAPサーバー』の3つを組み合わせたものを指します。
それぞれ「送信」「受信」「保管」といった役割があります。
送信後はDNSサーバーがインターネット上の住所に当たるIPアドレスを把握し、相手側のメールサーバーへと届けます。
ひとつずつ詳しく見ていきましょう。

### 1.メールの送信を行う「SMTP」サーバー
SMTPサーバーは、**メールを送信先のサーバーへ配送する**役割を持ったサーバーです。
一斉送信、送信遅延などを回避、迅速かつ確実にメールを送信できるようになります。
SMTPは以下のような処理をしています。


**1.ユーザーがメールを送信する
3.メールソフトがメールヘッダの情報を使いエンベロープ(封筒)を作成します。
3.SMTPがDNSサーバーを通じてIPアドレスを特定し宛先のサーバーを把握する
4.本文などを最適化し、メールを配送する**

※ちなみにSMTPは普通、SSL化されSMTPSとして使われます。
#### メールを配送するためのメール・ルーティング
では、その後メールはどのようにして相手に届くのでしょうか。
そうした仕組みを**メール・ルーティング**と呼びます。
メールサーバというのは、**メール配信機能**と**メール転送機能**があります。

**・メール配信機能**
サーバのローカルでユーザーのメールボックスへメールを届ける機能のこと。
メールサーバには、ユーザーごとのメールボックスがある。サーバーはユーザー管理を行う。

**・メール転送機能**
メールをほかのメールサーバへと送信する必要がある。これが転送。
単にメール・ルーティングといった場合には、この転送だけを指す場合もある。
そしてこの転送で、ほかのメールサーバとの通信に使用されるのがSMTP。
送受信メールを一時的に保管し、実際の転送に備えるキューイングと呼ばれる機能を持つこともある
メール配信や転送機能を受け持つプログラムを総称して「MTA（Mail Tranfer Agent）」と呼ぶ。
メールサーバといわれるものは、このMTAとして定義されている機能を実装したサーバのこと。

#### メールアドレスとルーティング
MTAがどのようにメール・ルーティングを行うのかを見てみます。送信処理は、次の段階に分けられます。
**(1)MUAからMTAへメール送信を依頼
(2)あて先メールアドレスから送信先MTAを決定する
(3-a)送信先MTAが自身であった場合には、「配信」処理を行う → 送信終了
(3-b)送信先MTAへSMTP接続を行い、送信
(4)送信先MTAが「配信」処理を行う → 送信終了**

MUAから送信を依頼されたメールは、MTAによって「配信」か「転送」かが判別される。判別の根拠となるのが、メールアドレスです。

`ユーザー名@メールサーバ名またはドメイン名`

右辺が自分自身を指していれば、自身で管理しているユーザーへメールを配信すればよいし、違うなら該当するMTAへと転送する必要があります。
左辺が配信に、右辺が転送にかかわっていると思って大丈夫です。
また、メールサーバ名とドメイン名はまったく別物だということに注意してください。
本来、メールアドレスは右辺にメールサーバ名を有する書式が一般的でしたが、「長くなる傾向」「サーバ名の漏出することのリスク」「不格好さ」が重なり、DNSドメイン名を右辺に定義できる仕組みが考案されました。
距離が最も小さく近いMTAがそのドメインの「代表MTA」として、送信元MTAによって選択される決まりになっています。
もし何らかの原因で接続できない場合には、次に距離が短いMTAが選択されます。

### 2.メールの受信を行う「POP」サーバー
SMTPサーバーを経由して送られたメールは最終的にこのPOPサーバーに行き着きます。
また、POPサーバーではユーザーIDやパスワードが合っているかを確認してからメールが受信できるようにします。
さらに、メールデータをダウンロードするので、オフラインでもメールを見ることができます。
POPサーバーは以下のような処理がされています。

>1.受信者がメールソフトを立ち上げる
2.POPサーバーから認証を受ける
3.POPサーバーに用意されているメールボックスから、自分宛のメールを受信する


### 3.メールの保管を行う「IMAP」サーバー
IMAPサーバーはPOPサーバーと同じような役割を持ちますが、POPサーバーと違うのは、**メールデータをサーバーに残したまま管理する**ということです。
たとえばPCを移行することになったとしても、メールデータはサーバー上にあるのでデータの移行作業を行わずに済みます。

## Gmailでメールサーバーを見てみる
理解を深めるために、あなたが実際に使っているメールサーバーをいじってみましょう。
今回は「Gmailを、他のメールプラットフォームでチェックできるようにする」設定を見てみます。
IMAP を設定して SMTP の設定を変更すると、Microsoft Outlook や Apple Mail などの他のメールクライアントで Gmail のメールを読むことができます。

### IMAP を設定する
参考：[Googleヘルプ](https://support.google.com/mail/answer/7126229?hl=ja)
#### ステップ 1: IMAP 機能が有効になっていることを確認する
>[Gmail](https://mail.google.com/)を開いて右上にある設定>すべての設定を表示を開きます。
[メール転送と POP/IMAP]タブをクリックします。
[IMAP アクセス] の [IMAP を有効にする] をクリックします。
[変更を保存] をクリックします。

#### ステップ 2: メールクライアントで SMTP とその他の設定を変更する
|項目|設定内容|
|---|---|
|受信メール（IMAP）サーバー|imap.gmail.com<br>SSL を使用する: はい<br>ポート: 993|
|送信メール（SMTP）サーバー|smtp.gmail.com<br>SSL を使用する: はい<br>TLS を使用する: はい（利用可能な場合）<br>認証を使用する: はい<br>SSL のポート: 465<br>TLS / STARTTLS のポート: 587|
|氏名または表示名|氏名|
|アカウント名、ユーザー名、メールアドレス|メールアドレス|
|パスワード|Gmail のパスワード|

ちなみにSSLやTLSが「はい」になっていると、あなたが通信するメールデータ情報は暗号化されます。
[SSL 【Secure Sockets Layer】 ](https://e-words.jp/w/SSL.html)

以上、ありがとうございました。
CUDA Version: 11.2 + TensorFlow を Anaconda で使ったときの備忘録

所属研究室のワークステーション（Windows）に CUDA 11.2 が導入されていたが、tensorflow が GPU を活用しつつパッケージを揃えるのに少し苦労した。
調べても pip を使った方法ばかりだったが、pip を使わずに anaconda のみで解決しようとして少し躓いたので、備忘録を残す。
（初心者なので、間違いやもっと良い方法があれば教えてください m(_ _)m）

## 追記 2021/10/7
容量を気にしなければ、CUDA の別バージョンを入れてしまうのが早い気がしてきた。
考え方は、https://qiita.com/takeajioka/items/8737fab5cffbe0118fea 、詳しいやり方は https://ichiya.netlify.app/posts/2020/02/29/_20200229-2.htm を参照。

## 追記 2022/10/9
毎回 anaconda でパッケージを探して、なかったら conda-forge を探していたが、それを一発でやる方法があった。
チャンネルの優先順位もつけられる。
Ex. 優先順位最下位に conda-forge を追加する。
`conda config --append channels conda-forge`
https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-channels.html 参照。

## やったことまとめ
- `conda create -n tf25`
- `conda install tensorflow-gpu==2.5`
- conflict したら、Anaconda cloud で代わりのパッケージを探す
- `conda install -c conda-forge matplotlib`

以下、時系列で困ったことを書いていく。

## tensorflow で GPU を使ってくれない
まず、tensorflow で CUDA を介して GPU を使うためには、CUDA のバージョンに応じた tensorflow のバージョンにする必要がある。
バージョンの対応は以下。

https://www.tensorflow.org/install/source?hl=ja#linux

今回は、CUDA 11.2 だったため、tensorflow-gpu >= 2.5 をインストールする。

## conda install で conflict により tensorflow-gpu==2.5 が入らない
自分の環境に conda でパッケージが入らないときは、新たに仮想環境を作って入れたいパッケージを入れる。
とりあえず、`tf25` という名前の環境を作って、そこに入れた。

- `conda create -n tf25`
- `conda install tensorflow-gpu==2.5`

## 新しく作った環境に matplotlib や pandas が入らない
最初に tensorflow を入れようとして conflict したので、そこに入っていたパッケージのうちどれかは入らない。
自分の場合、matplotlib が入らないという事件が起きた。
matplotlib conflict で検索して、conda-forge からインストールすればいけるという回答を見つけた。

https://stackoverflow.com/questions/59723500/cant-install-matplotlib-in-conda-env-w-python-3-8

やってみた結果、できた。
- `conda install -c conda-forge matplotlib`

## 教訓
- anaconda のパッケージで conflict が起きても、めげずにパッケージを探す
- conda-forge すごい
AWS SecretsManager motoを使用してpytest する方法


#secretsmanager motoを使用してのpytest

pytestをする必要があったので検索しましたがあまり日本語がなさそうな雰囲気。。。
別にmoto使用しなくても全てmockにしてしまってもいいけどね。
なんとなく知的好奇心が沸いたので試してみました。
なので記事にしてみました。


##必要モジュール
boto3
moto
pytest


##実装箇所

```secrets_manager.py
import json
import boto3
import logging

# log_level
logging.getLogger().setLevel(logging.INFO)


class SecretsManagerClass:

    def __init__(self, secret_name):
        logging.info(secret_name)
        self.secret_name = secret_name

    def _open_boto_session(self):
        return boto3.session.Session()

    def _create_boto_client(self):
        return self._open_boto_session().client(
            service_name="secretsmanager", region_name="ap-northeast-1"
        )

    def get_secrets_info(self):
        get_secret_value_response = \
            self._create_boto_client().get_secret_value(
                SecretId=self.secret_name)
        rds_secret = json.loads(get_secret_value_response['SecretString'])
        return rds_secret

```
こんな感じで

##pytest箇所

```test_secrets_manager.py
import pytest
import boto3
from moto import mock_secretsmanager
from src.secrets_manager import SecretsManagerClass


class TestGetParameterClass(object):

    @pytest.fixture
    def create_mocked_secret_manager_connection(self):
        with mock_secretsmanager():
            yield boto3.session.Session().client(
                service_name="secretsmanager", region_name="ap-northeast-1"
            )

    @pytest.fixture
    def create_test_secret(self, create_mocked_secret_manager_connection):
        create_mocked_secret_manager_connection.create_secret(
            Name="mock_secret",
            SecretString="""{"mock_secret_key": "mock_secret_value"}"""
        )

    def test_get_secret_string(
        self, monkeypatch, create_mocked_secret_manager_connection, create_test_secret
    ):
        def get_mocked_secret_manager(*args, **kwargs):
            return create_mocked_secret_manager_connection

        monkeypatch.setattr(
            SecretsManagerClass, "_create_boto_client", get_mocked_secret_manager
        )

        credential_client = SecretsManagerClass("mock_secret")

        assert credential_client.get_secrets_info() == {
            "mock_secret_key": "mock_secret_value"
        }
```
使ってない変数とかあるけど、基本を残してるので多用的に使えるかと( ^ω^ )

まあざっとこんな感じ、元の参照した記事は何かもう忘れちまった。。。

けど大体日本語の記事より英語の記事の方が充実してるから英語がいいですよね。
stack overflow（英語版）とか

pytest最近すごく触れる機会が多いので段々と理解が深まってきました。





今日は以上です。
IPv4とIPv6の違いについて

## はじめに
今回はよく耳にするIPv4とIPv6について、LinuCの学習範囲でもあったのでまとめてみました。

## 概要
IPv4とIPv6は、どちらもインターネットの通信方法に関する規約のことですが、さまざまな違いあるそうです。

IPv6は、現在主流のIPv4に変わる次世代版のインターネットプロトコル
近年、インターネットの急速な普及や、接続機器の増加に伴い
IPアドレスの枯渇が問題となりました。
そこで、IPv4では32ビットの長さで表していたIPアドレスをIPv6では128ビットで表すことで、
使用できるIPアドレスが約340澗（かん）個（事実上無限）にまで増大させた

## IPv6について
現在主流のIPv4に変わる次世代版のインターネットプロトコル(IP)のこと。
近年、インターネットの急速な普及や、接続機器の増加に伴い、IPアドレスの枯渇が問題に。
そこで、IPv4では32ビットの長さで表していたIPアドレスをIPv6では128ビットで表すことで、使用できるIPアドレス(事実上無限）にまで増大した。

### 特徴
・128ビット表記による事実上無限のIPアドレス
・IPアドレスの省略表記が可能
・IPアドレスの自動割り当て機能を標準で実装
・IPsec（暗号化通信）を標準で実装
・IPv4との互換性は無い（但し、機器にIPv4とIPv6の両方のアドレスを割り当てるデュアルスタックなどの仕組みで相互運用は可能）
→IPv4とIPv6ではパケットフォーマットが異なる為、直接通信をする事はできません（互換性はありません）が、デュアルスタックなどの相互運用の仕組みを利用してIPv4とIPv6が混在したネットワークを構築することが可能。

メリット
・速度の改善

### IPv６から廃止されたもの
・IPv6からブロードキャスト（一斉送信は全てマルチキャスト（特定グループ宛通信）で行われる）
・IPv4にあった「クラス」の概念（代わりにサブネットプレフィックスとインタフェース識別子を割り当てることが推奨される）


## IPv4について

・ローカルネットワークでのみ使用が許可されている「プライベートアドレス」と、インターネット上で使用される世界で唯一の「グローバルアドレス」がある。




■サブネットプレフィックス:ユニキャスト（1対1通信）のアドレス割当における前半64ビット
■インタフェース識別子:ユニキャスト（1対1通信）のアドレス割当における後半64ビット
■ループバックアドレス：その機器自身を示す特殊なIPアドレス
## IPv4とIPv6の主な違い
|| IPv4 |IPv6 |
|---|---|---|
|表記例|192.168.100.1|2004:a80:e01:a8::3|
|種別|10進数 |16進数 |
|アドレス帳|32bit | 128bit |
|区切り|8bit(３桁)ごとに.(ドット)| 16bit(4桁)ごとに:（コロン）|
|アドレス自動割り当て|DHCPなどの技術を併用して実現|自動割り当て機能を標準で実装|
|セキュリティ|別のプロトコルを平用して実現|暗号化通信を標準で実装|
|アドレスの省略表記|不可|可能|
|ループバックアドレス|127.0.0.0/8の範囲|0:0:0:0:0:0:1または::1|

## 参考
https://www.fenet.jp/infla/column/network/ipv4%E3%81%A8ipv6%E3%81%AE%E9%81%95%E3%81%848%E3%81%A4%E3%81%A8%E3%81%AF%EF%BC%9Fipv4-over-ipv6%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%82%82%E8%A7%A3%E8%AA%AC/
Illuminate\Http\Requestについて雰囲気でやっていたので個人的にメモした



Controller内でRequestをいい感じに使えることができるように諸々まとめた

## リクエストされたURLを知りたいとき
クエリ文字列が必要ない場合は、以下

```php
$url = $request->url();
```

クエリ文字列が必要な場合は、以下

```php
$urlWithQueryString = $request->fullUrl();
```

パスのみが必要な場合は、以下

```php
$uri = $request->path()
```

## リクエストされたURL/メソッドによって処理を分けたいとき

```php
if ($request->is('admin/*')) {
    // 処理
}
```

名前付きルートに一致するか確かめるときは、以下

```php
if ($request->routeIs('admin.*')) {
    //　処理
}
```

リクエストメソッドが知りたいときは、以下

```php
$method = $request->method();
```

リクエストメソッドが指定のものか知りたいときは、以下

```php
if ($request->isMethod('post')) {
    //　処理
}
```


## URLのクエリ文字列にデータを追加したいとき

```php
$request->fullUrlWithQuery(['type' => 'phone']);
```

## リクエストしてきたIPアドレスが知りたいとき

```php
$ipAddress = $request->ip();
```

## リクエストに含まれる入力データが知りたいとき
### 全て欲しいとき
配列として取得したいときは、以下

```php
$input = $request->all();
```
連想配列として取得したいときは、以下

```php
$input = $request->input();
```

### 特定のものが欲しいとき

```php
$name = $request->input('name');
```

inputメソッドは２番目の引数としてデフォルト値を渡すことができる。指定した入力値がリクエストに存在しない場合、この値が返される。

```php
$name = $request->input('name', 'Sally');
```

配列入力を含むフォームを操作する場合は、「ドット」表記を使用して配列にアクセスすることができる

```php
$name = $request->input('products.0.name');

$names = $request->input('products.*.name');
```

### 論理入力値の取得
```php
$archived = $request->boolean('archived');
```

### リクエストに値が存在するかを確かめたいとき
リクエストにそもそもnameというkeyが存在しているのか？

```php
if ($request->has('name')) {
    //
}
```

指定されたすべての値が存在するかどうかを判別することもできる。

```php
if ($request->has(['name', 'email'])) {
    //　処理
}
```

指定値のいずれかが存在する場合、hasAnyメソッドを利用することができる。

```php
if ($request->hasAny(['name', 'email'])) {
    //　処理
}
```

こんなこともできたりする

```php
$request->whenHas('name', function ($input) {
    //
});
```

### 値がリクエストに存在し、空でないことを確認したいとき

```php
if ($request->filled('name')) {
    //
}
```

### 特定のキーがリクエストに含まれていないかを判定したいとき

hasメソッドの逆(?)

```php
if ($request->missing('name')) {
    //
}
```

## 入力値を一時保持後のリダイレクトするなどしたいとき

```php
return redirect('form')->withInput();

return redirect()->route('user.create')->withInput();

return redirect('form')->withInput(
    $request->except('password')
);
```

上記のデータを取得したいとき

```php
$username = $request->old('username');
```

## まとめ
いい感じに使えるようになりたい
STM32G031のArduinoでの時計,DS1307で時刻表示OLED,AL12832AWWB(PA11,P12にリマップ)


stm32g031,stm32l010用に最軽量化したもの

x がんばつて　OLEDをリマップした。PA11-CLK,PA12-IO
x 時間合わせは、別

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり

SSD1306 128x32


有機ＥＬディスプレイ　１２８×３２　白色
[AL12832AWWB-H-U02]
通販コード　P-14686


![h_con22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/02842b57-9c9e-6674-3146-adb85a4c237a.jpeg)




```c++


#include <Arduino.h>
#include <U8x8lib.h>
#include <Wire.h> //I2C library

//OLEDの定義
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);        
U8X8_SSD1306_128X32_UNIVISION_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE, /* clock=*/ PA11, /* data=*/ PA12);   // pin remapping with ESP8266 HW I2C

//ds1307のアドレス
#define ADDR    0x68  // 2進数 1101000

int     cursor1;      //カーソルの位置
char    data_read[8]; //i2cバッファー

//時間をoled表示形式に変換
char ch_hex_a_b[4];
char *ch_hex_a(int l_num)
{
    ch_hex_a_b[0] = '0' + (l_num >> 4);
    ch_hex_a_b[1] = '0' + (l_num & 0xf);
    ch_hex_a_b[2] = ':';
    ch_hex_a_b[3] = 0;
    return(ch_hex_a_b);
}//ch_hex_a

//oledに表示
void i2c_oled_w(char *s)
{
  //文字の表示
  u8x8.drawString(
  ((cursor1-0) & 0x07  )*2, // x
  (cursor1>>3)*2,           // y
  s);

  while(s[0] != 0) {
    s++;
    cursor1++;
  }

} //i2c_oled_w

//初期化
void setup(void)
{
  //I2Cの初期化
  Wire.begin(PA12,PA11); //stm32g031

  //OLEDの初期化
  u8x8.begin();

  //フォントの設定
  u8x8.setFont(u8x8_font_px437wyse700a_2x2_r);

  //スタートロゴ
  cursor1 = 0;
  i2c_oled_w("START");
  delay(500);

  //画面の初期化
  u8x8.drawString( 0,0,"        ");
  u8x8.drawString( 0,2,"        ");
  cursor1 = 0;

}//setup

//メインループ
void loop(void)
{
  //カーソルのクリア
  cursor1 = 0;

  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
    Wire.write(0x00);
  Wire.endTransmission();

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  for (int ii = 0; ii < 8; ii++) {
    while (Wire.available() == 0 ) {}
    data_read[ii] = Wire.read();
  }//for

//  data_read[2]=0x12; //debug
//  data_read[1]=0x34; //debug
//  data_read[0]=0x45; //debug

  //画面に表示
  i2c_oled_w(ch_hex_a(data_read[2]));
  i2c_oled_w(ch_hex_a(data_read[1]));
  ch_hex_a(data_read[0]);ch_hex_a_b[2]=0;
  i2c_oled_w(ch_hex_a_b);
  
  //1秒待つ
  delay(1000);

}//loop



```



時間合わせ


```c++

#include <Wire.h> //I2C library

//STM32G031J6M6
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

#define ADDR    0x68  // 2進数 1101000

char    data_read[8]; //i2cバッファー

#define HH  12
#define MM  34

void setup()
{
  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

//i2c書き込み
  Wire.beginTransmission(ADDR);

  Wire.write((char) 0    ); //0 レジスターの位置は0
  Wire.write((char) 0    ); //1 秒
  Wire.write((char) ( MM /10)*16+( MM %10) ); //2 分
  Wire.write((char) ( HH /10)*16+( HH %10) ); //3 時

  Wire.write((char) 3    ); //4 曜日
  Wire.write((char) 1    ); //5 日
  Wire.write((char) 1    ); //6 月
  Wire.write((char) 0x20 ); //7 年

  Wire.endTransmission();

} //end setup

void loop()
{

} //loop


```
[React]ルーティングの基礎

#[React]ルーティングの基礎
## 開発環境
CodeSandboxを使用します。
導入方法については[こちら](CodeSandboxでReact学習用の開発環境をサクっと作ろう)を参考に導入してください。

## 最終的なコード
```React:App.jsx
import { BrowserRouter, Link } from "react-router-dom";

import { Home } from "./Home";
import { Page1 } from "./Page1";
import { Page2 } from "./Page2";

export default function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <Link to="/">Home</Link>
        <br />
        <Link to="/Page1">Page1</Link>
        <br />
        <Link to="/Page2">Page2</Link>
      </div>
　　　　　　　　　　　　<Switch>
        <Route exact path="/">
　　　　　　　　　　　　    <Home />
        <Route path="/page1">
          <Page1 />
        </Route>
        <Route path="/page2">
          <Page2 />
        </Route>
　　　　　　　　　　　　<Switch>
    </BrowserRouter>
  );
}
```

遷移先のコンポーネントを以下の通りに作成しておく。
Page1、Page2も同様に作成。

```React:Home.jsx
export const Home = () => {
  return (
    <div>
      <h1>Homeです</h1>
    </div>
  );
};

```

## `<BrowserRouter>`
react-router関連のコンポーネントは全て`<BrowserRouter> ~ </BorwserRouter>`で囲って使います。

```React:App.jsx
import { BrowserRouter, Link } from "react-router-dom";

export default function App() {
  return (
    <BrowserRouter>
      <-- 各リンク先の記述  -->
    </BrowserRouter>
  );
}
```

## `<Link to=~~~>`
aタグみたいにリンクタグを用意してくれる。

## `<Switch>`
パス毎にどのコンポーネントを表示するかを決めるためのタグ。

## `<Route>`
`<Route />`にはルーティング先のURLと、そのURLで表示したいコンポーネントを指定する。
exactを書くと完全一致するか判定される。
path="/"としていて、exactを書いておかないとどのパスでもHomeにレンダリングされてしまう。

## 参考文献
- [CodeSandboxでReact学習用の開発環境をサクっと作ろう](CodeSandboxでReact学習用の開発環境をサクっと作ろう)
- [【React】react-routerの使い方を丁寧に解説](https://dezanari.com/react-react-router/)
備忘録：DOSコマンドで日付を出力する

フィールドSEという職業柄、訪問した客先でバッチファイルを作成することがある。簡単なBATを書く場合でもログに日付を出力したいが、よく忘れるので備忘録として記載する。
日付8桁

```text:コマンドプロンプト
d>set YYYYMMDD=%date:~0,4%%date:~5,2%%date:~8,2%
d:\>echo %YYYYMMDD%
20210822
```
西暦4桁

```text:コマンドプロンプト
d:\>set YYYY=%date:~0,4%
d:\>echo %YYYY%
2021
```
月2桁

```text:コマンドプロンプト
d:\>set MM=%date:~5,2%
d:\>echo %MM%
08
```
日2桁

```text:コマンドプロンプト
d:\>set DD=%date:~8,2%
d:\>echo %DD%
22
```
fontsフォルダのDIRリストをログに出力する。

```text:コマンドプロンプト
d:\>set YYYYMMDD=%date:~0,4%%date:~5,2%%date:~8,2%
d:\>cd c:\windows\fonts
c:\Windows\Fonts>dir /s >d:\test_%YYYYMMDD%.txt
```
結果は以下のように出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436570/09fd22dc-f5be-5394-33ee-1b032aef11d4.png)
繰り返し処理【PHP】

こんにちは
PHP初心者です。
今回は繰り返し処理についてメモしていきます！

# while

while構文はある条件が満たされるまで
処理を繰り返すことができます。

書き方としては

```php
初期化処理
while(繰り返す条件) {
   繰り返したい処理
　　　　　　更新処理
}
```
というカンジで例を出すと、
以下のような記述になります。

```php
$i = 1;
while ($i <= 100) {
  print($i . "\n");
  $i += 1
}
```

初期化処理は```$i = 1```にあたります。
変数iに１を代入したんですね。
繰り返す条件は```($i <= 100)```
これは$iが100以下であれはtrueとなり、
中かっこ{}の中身の処理を行います。


処理が行われる順番としては
1. $i = 1を定義
2. ($i <= 100)がtrueかどうか判断
3. 2がtrueになるのであれば、$iの値を出力
4. $iに１を加算

この順番で$i ＝100になるまで繰り返されます。

比較演算子<=が出てきたのでごめん思い出したから
関係ないけどアウトプットさせてね。

RubyだとAとBが等しい時

```ruby
A == B
```
と記述するけど

PHPだと

```php
A === B
```

ってするらしい。

あと、Rubyでは自己代入演算子って言われてるこれなんやけど、
PHPでも使えるとのこと（PHPでは代入演算子というらしいけど）。
PHPでは1を代入するときだけ、さらに省略した書き方ができるらしい。

```php
$num += 1
$num++;
$num--;
```

# for

なんか本題とそれたメモばっかり増えたな。

for構文の書き方テンプレは以下の通り

```php

for(初期化処理; 繰り返す条件; 更新処理) {
  繰り返したい処理
}

for ($i=1; $i<= 100; $i++) {
  print($i . "\n")
}
```

例もついでに載せました。
さっそく1を代入する省略する処理を使いましたわ！

whileよりforで繰り返し処理を記述する方が記述が少なくなって
さっぱりする印象を受けますね。

ただ単にシンプルな処理を繰り返したいときはfor構文を使用すればいいのですが、
初期化処理や、更新処理が複雑なケースはwhile構文を使った方がいいとのことです。
理由はまだ知らないけどね〜〜！！


# foreach

配列や連想配列（Rubyでいうところのハッシュ）を繰り返して
取り出したいときはforeach構文を使用します。
まあ配列専用の構文ですわ。

```php
<?php 
$powerful_shaman = [ 
  "name" => "五条悟",
  "age" => "28",
  "magic" => "無下限呪術",
  "rank" => "特急呪術師",
  "special_skill" => "無量空処"
];

foreach ($powerful_shaman as $profile => $val) {
  print($profile . ":". $val . "\n");
}
?>
```

連想配列にforeach構文を使用してみました。
foreachの``` $profile => $val```の部分は
名前なんでなんでもいいです。
例えば、$profileには、
"name"、"age"、　"magic"、　"rank"、　"rank"が代入されており、
＄valには、
"五条悟" 、"28"、　"無下限呪術"、　"特急呪術師"、　"無量空処"が
代入されています。

よってこれを出力すると、
![スクリーンショット 2021-08-22 18.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1435543/cb79b8c3-c309-4b01-b575-bcfb90710207.png)

五条先生のプロフィールが帰ってきます。
やっぱりテストコード書いたほうが早くないですか？


## 前置き
現職ではテストコードを記載する文化がない会社に所属しています。

自分なりに実装する中でテストコードコードを書いたほうが発速度が早いのでは？と考えるようになり、ポエムとしてこの記事を書き残したいと思います。

## 現職の考え方と反論

### スピード感重視なのでテストは書かなくて良い
テストを書いている分記載量が多くなり、工数がかかってしまうという考え方です。
確かにコード量が増えてしまうのは確かですが、デバックのやり方等でこの工数を改修できるのでは？と思っています。

 例）外部APIを利用している場合
テスト無し：検証する度に外部APIにリクエストを送信する必要がある
テスト有り：外部APIのモックを用意して、何回も簡単に検証することができる。
例えば決済用のAPIを利用していて、ユーザーが返金を要求してきたケースなど、
**特定の状態を用意する必要がある場合**、上記の差がはっきりとでると感じています。

また最近ではフレームワーク自体が強力なテストツール（Laravelだと[factory](https://readouble.com/laravel/8.x/ja/database-testing.html)）が用意されており、めちゃくちゃ簡単にテストコードを用意できるようになりました。

### 手動テストするので、テストコードで重複して確認する必要はない
現職ではデプロイ前のプロセスとして手動でのテストが必須となっているので、重複した確認は不要という考え方です。

確かにテストケースが少ないかつ、テストが簡単な場合はこの考え方に同意できるのですが、現場のシステムは大概複雑になっており、影響範囲がどの程度になるか想像と違ってくる場合が多々あります。

手動テストは実施にかなりのコストがかかるので、繰り返し何度も実行するのに向いていません。それに対してテストコードは一度書けば繰り返し何度でも検証が可能です。

特に影響範囲がとても大きいプログラム言語、ミドルウェアのバージョンアップではコマンド一つ叩けば大体の影響範囲を把握することができるので、とても強い武器になると思います。

しっかりとテストコードを書いていた場合このあたりでテストコードを書いた工数は回収できると考えています。

### ブラウザを見てデバックするのが当たり前である
現職ではテストの際dump系のコマンドを使って値を毎回ブラウザに出力させる方法でデバックを行っています。

機能が小さいテストであれば上記で十分なのですが、機能が大きくなってくると切り分けてテストすることができなくなります。

それに対してテストコードを書いた場合、細かい関数単位をいろんな値を利用して検証できるので、とても便利です。

## 要するになぜテストコードを書くのか？
手動でテストを実行するのに比べ、下記のメリットが得られるというのが私なりの回答です。  

 - 複雑な箇所を切り分けて簡単に検証できる
 - 一度書いただけではなく、繰り返し検証ができる

逆にいうと上記のメリットを得られないような簡単なシステムや使い捨てる場合、テストコードを書かなくてよいと考えています。

## ここだけは拘りたい、テストを書く注意点
上記のメリットを得るために、テストコード書く上で下記だけは気を付けています。
本当はカバレッジなども考える必要があると思うのですが、私自身がまだそこまでのレベルに行けていないです。。。

### 再現性
DBや環境値に依存させず、いつ実行しても同じ結果が得られるようにすべきだと考えています。

最近ではテストコード用のDBや環境を再現するマイグレーションを用意するのが一般的になってきたように感じます。（現職だとまだ直接CREATE文を打ち込んだりしていますが）

### 独立性
なるべくテストコードの関数は短く持つべきで、一つの関数で複数の事象を検証しないように記載します。
Laravelのselectフォームでoption hiddenを利用した時のvalidationについての忘備録

##バリデーションで実現したい事
フォーム内のselectで選択されずに(option hiddenの項目が選択されたまま)submitされた時、
バリデーションエラーにする。

今回は「会社」を登録する時の情報のうち
住所の「都道府県」をselectから選択するようにした。

```php:corp/create.blade.php
//省略

//都道府県データ
//$prefs =['北海道','青森県','岩手県'・・・・];

  <select name="pref" required>
    <option hidden>都道府県</option>
    @foreach ($prefs as $pref)
      <option value="{{ $pref }}" selected>{{ $pref }}</option>
    @endforeach
  </select>
```

上記のような場合、selectで「都道府県」は選択出来ないようになっているが
選択しないまま送信すると「都道府県」がvalueとなって送信されて、
requiredのバリデーションが掛からない。

そこで選択されていない場合、バリデーションエラーとなるように以下のように修正した。

###カスタムバリデーションを登録する
```
php artisan make:request CorpRequest
```
Requestフォルダに「CorpRequest.php」が作成されるので
カスタムバリデーションを設定する。
今回は「prohibited_if」を利用した。ついでにエラーメッセージも登録。

バリデーション参考：
Laravel公式ドキュメントサイト: [ReaDouble](https://readouble.com/laravel/8.x/ja/validation.html)

```php:app/Http/Request/CorpRequest.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class CorpRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;//※trueに変更
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'pref' => 'prohibited_if:pref,null',
        ];
    }

    public function messages()
    {
        return [
            'prohibited_if' => ':attributeを選択してください。',
        ];
    }
}

```

作成した「「CorpRegisterRequest」をcontrollerで読み込む

```php:app/Http/Controller/CorpController.php
<?php
namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Corp;
use App\Http\Requests\CorpRequest;//クラスを読み込む

//省略

    public function store(CorpRequest $request)//RequestをCorpRequestに変更
    {
        Corp::create([
            'pref' => $request->pref,
//以下省略
```

###viewの一部を修正
selectを選択せずにsubmitするとprefにnullをセットする

```php:corp/create.blade.php
//省略

//都道府県データ
//$prefs =['北海道','青森県','岩手県'・・・・];

  <select name="pref" required>
    <option value="null" hidden>都道府県</option> //valueに「null」を設定
    @foreach ($prefs as $pref)
      <option value="{{ $pref }}" selected>{{ $pref }}</option>
    @endforeach
  </select>
```
以上のように変更することで、selectのhiddenが選択されたままsubmitされると
バリデーションエラーが実現できた。

もっと良い方法があれば、コメントいただけると喜びます。
TypeORMの初期サンプル実行やCLIツール作ろうとするときプロセスが終わらない問題の解決

TypeORMでプロジェクトを下記コマンドで作成する

https://github.com/typeorm/typeorm

```
typeorm init --name MyProject --database mysql
```

src/index.ts にサンプルファイルが出力される

```typescript
import "reflect-metadata";
import {createConnection} from "typeorm";
import {User} from "./entity/User";

createConnection().then(async connection => {

    console.log("Inserting a new user into the database...");
    const user = new User();
    user.firstName = "Timber";
    user.lastName = "Saw";
    user.age = 25;
    await connection.manager.save(user);
    console.log("Saved a new user with id: " + user.id);

    console.log("Loading users from the database...");
    const users = await connection.manager.find(User);
    console.log("Loaded users: ", users);

    console.log("Here you can setup and run express/koa/any other framework.");

}).catch(error => console.log(error));

```


これを下記で実行するとコンソールが処理が終了せずに固まる

```
ts-node src/index.ts
Inserting a new user into the database...
Saved a new user with id: 3
Loading users from the database...
Loaded users:  [
  User { id: 1, firstName: 'Timber', lastName: 'Saw', age: 25 }
]
Here you can setup and run express/koa/any other framework.
 ＜ここでフリーズする＝処理が抜けない＞
```

mysql> show processlist;で確認すると＜ここでフリーズする＞の箇所ではコネクションは活きている状態になっている。


typeormを使ってCLIツールなど使うときこれだと困るので、一つの解決策は``` process.exit()```を差し込めばいいがさすがにそれは最終手段なのでコネクションをクローズすることで処理が抜けるようになった。


```typescript
import "reflect-metadata";
import {createConnection} from "typeorm";
import {User} from "./entity/User";

createConnection().then(async connection => {

    const users = await connection.manager.find(User)
    console.log("Loaded users: ", users)
    await connection.close() // ここを追加

}).catch(error => console.log(error));
```

TypeORMのサンプルは明示的にcloseの記載はないので、明示的に終了したいときはcloseをいれるのが良さそう。
qiitaの記事と質問は、タグは共通みたいです。

①qiitaの記事と記事は、自動的にリンク。相互リンク?かかるみたいですが、
記事と質問は、自動的にならないみたいです。
②qiitaの記事と質問は、タグは共通みたいです。
③記事の閲覧数は、表示されますが、
　質問の閲覧数は、表示されない仕組みみたいです。

間違っていたら、ご指摘お願いします。

#参考資料
記事

https://qiita.com/nekonisi/items/c2a9465ca63f169da640

質問

https://qiita.com/mrrclb48z/questions/38b84e6a31126ccd1086


タグ

https://qiita.com/tags/%e3%82%b9%e3%83%9e%e3%83%9b?type=questions
6-LEDs Signal　CDT7350-02

#はじめに
LEDを順点灯させたり、点滅など出来る。5通りの動作モードをスイッチの設定できる。点滅や順点灯のスピードを半固定抵抗での調整を行う事ができる。

#CDT7350-02を使用
LEDの点灯制御専用ICで、少ない外付け部品で6個のLEDを5通りの発光パターンで点灯させることができます。RC発振回路内蔵で、外部に発振器が不要です。また、外付けの抵抗により発光周期を容易に調整可能です。LEDを電流制限(明るさ調整用)抵抗を介して接続することができます。
https://akizukidenshi.com/catalog/g/gI-03190/

#目次
1. 仕様
2. 部品リスト
3. 回路図
4. 動作動画


# 1.仕様　
スイッチの組み合わせで点灯方法の制御組み合わせは以下の通りを行っている。「ON/OFF」の記載されている所は、どちらを選択していても問題はない

||動作モード|SW1|SW2|SW3|SW4|
|::|::|::|::|::|::|
|１|順点灯|OFF|OFF|OFF|OFF|
|２|往復点灯|OFF|OFF|OFF|ON|
|３|順送り|OFF|ON|OFF|OFF|
|４|全点滅|ON|ON/OFF|OFF|ON/OFF|
|５|全点灯|ON/OFF|ON/OFF|ON|ON/OFF|



# 2.電子部品リスト

||部品番号|品名|数量|
|:---:|:---:|:---:|:---:|
|１|IC1|IC　CDT7350-02|1個|
|２|L1~L6|LED 青色|6個|
|３|R1~R6|1/4W抵抗　100Ω|6個|
|４|R7|1/4W抵抗　330kΩ|1個|
|５|VR1|半固定抵抗　300kΩ|1個|
|６|C1|電解コンデンサ　47uF|1個|
|７|C2,C4,C5.C6|積層セラミックコンデンサ　0.1uF|1個|
|８|C3|セラミックコンデンサ　1000pF|1個|
|９|ICソケット||1個|
|１０|SW1|DIPスイッチ　４回路|1個|
|１１|SW2|スライドスイッチ|1個|
|１２||基板|1個|

#3.回路図
参考程度にお願いいたします。
__配線図__
![回路.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/28d315eb-7a66-60a2-3f39-582930ac4412.jpeg)

__実体配線図__
![実体配線図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/661c58a2-d788-3f32-5a9d-45f05781ec96.jpeg)






# 4.動作動画
下の画像を選択すると動画が再生されます。
__YouTube__に飛びます。

https://youtu.be/_GAuTkO1GSE

[![ビデオが開けなかった場合に表示されるテキスト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675881/906db7b4-470e-baed-7a9f-387a37ba1b34.jpeg)](https://youtu.be/_GAuTkO1GSE)
scpを毎回自動でパスワード入力して実行する


# 概要

以下、同僚の話である.

>同僚 A は、リモート Linux に対して頻繁に scp でデータを転送していたが、
毎回ログインパスワード入力をしていて手間であった.
　
そこで上司に対してパスワード入力が省略できる「SSH公開鍵認証を行いたい」と
訴えたが、上司が次のように (意味不明な理由を) 言って拒否した.
　
「パスワード入力が省略できてしまうなんてダメです」
「毎回、パスワードを入力することに意味があるんです」


個人的には、このような上司の意見は無視して SSH公開鍵認証をしてしまえば良いと思うが、
同僚は次のようにして律儀に守ったようである.

　
# 実装

ローカルにある local.data を、リモートLinux の /tmp/. に配置する場合を例とする.

`SSH_ASKPASS` を使って「パスワードを標準出力するプログラム」を指定している.
そして「パスワードを標準出力するプログラム」は一時ファイルを用いたようである.
ここでのリモートLinux のログインパスワードは「password」である.

```bash
#!/bin/bash

# 一時ファイルを作成する. 作成された一時ファイルの絶対パスが TMPF に格納される.
TMPF=`mktemp`

# ソフトウェア割り込みが発生したら掴まえてパスワード表示プログラム「$TMPF」を削除する
trap "test ! -z \"$TMPF\" && rm -f $TMPF && exit 1" 1 2 15

# パスワード表示プログラムを「$TMPF」に書き出す
cat <<'EOL' > $TMPF
#!/bin/bash
echo 'password'
EOL

# パスワード表示プログラム「$TMPF」に実行権限を付与する
chmod +x $TMPF

# 環境変数「SSH_ASKPASS」に「$TMPF」の絶対パスを指定するだけでなく、
# 環境変数「DISPLAY」を空にして、且つ setsid を指定して実行する.
DISPLAY='' SSH_ASKPASS=$TMPF setsid scp -rp local.data <アカウント>@<IP>:/tmp/.

# 最後にパスワードが記された「$TMPF」を削除する.
rm -f $TMPF

```

以上.

　

## 参考にした記事

・https://qiita.com/wadahiro/items/977e4f820b4451a2e5e0
Laravel8ログの出力方法

##今回はログの出し方をアウトプットしていく
ログを使用する理由
①意図した値が変数に入ってきているか確認できる。
②どこまで正しい処理ができているのか確認できる。
ログを出力するために**Log::debug**を使用する。
確認場所はstorage/logs/laravel.logファイルで確認できる。

①の使用例

```php
//Log::debugを使用するため読み込む
use Illuminate\Support\Facades\Log;

class AuthenticatedSessionController extends Controller
{
    public function store(LoginRequest $request)
    {
        $request->authenticate();
        //$requestの中身をログで出す
        Log::debug($request);

        $request->session()->regenerate();

        return redirect()->intended(RouteServiceProvider::HOME);
    }
}

```

②の使用例

```php
//Log::debugを使用するため読み込む
use Illuminate\Support\Facades\Log;

class AuthenticatedSessionController extends Controller
{
    public function store(LoginRequest $request)
    {
        //正常な処理なのでLogには1が表示される
        $request->authenticate();
        Log::debug('1');

        //正常な処理なのでLogには２が表示される
        $request->session()->regenerate();
        Log::debug('2');

        //エラー処理なのでLogには3が表示されない
        $request-> 
        Log::debug('3');   

        return redirect()->intended(RouteServiceProvider::HOME);
    }
}

```

##日ごとでlaravel.logファイルを分ける
通常laravel.logファイルは一つにまとめられているのでわかりやすいように日ごとにlogファイルを分ける。
設定はconfig/logging.phpで行う。
Laravelはメッセージをログに記録するときに、デフォルトでstackチャンネルを使用しているのでstackチャンネルのチャンネルドライバの設定をdaily設定に変えてあげる

```php
   'stack' => [
            'driver' => 'stack',
            'channels' => ['daily'],//日毎にファイルを切り替えるRotatingFileHandlerベースのMonologドライバ
            'ignore_exceptions' => false,
        ],
```
設定を変えたら一度キャッシュする必要がある。
下記のコマンドを実行してキャッシュする。

```
$php artisan cache:clear
$php artisan config:clear
```

##追記
下記に使用可能なログチャンネルドライバを記載しておきます。

・**custom** = 指定ファクトリを呼び出してチャンネルを作成するドライバ
・**daily** = 日毎にファイルを切り替えるRotatingFileHandlerベースのMonologドライバ
・**errorlog** = ErrorLogHandlerベースのMonologドライバ
・**monolog** = Monologがサポートしているハンドラを使用するMonologファクトリドライバ
・**null** = すべてのログメッセージを破棄するドライバ
・**papertrail** = SyslogUdpHandlerベースのMonologドライバ
・**single** = 単一のファイルまたはパスベースのロガーチャンネル(StreamHandler)
・**slack** = SlackWebhookHandlerベースのMonologドライバ
・**stack** = 「マルチチャンネル」チャンネルの作成を容易にするラッパー
・**syslog** = SyslogHandlerベースのMonologドライバ
railsチュートリアルでherokuへのpushができない

# これは何
- ruby on railsのチュートリアルでherokuへアプリケーションをデプロイする場面があるのですが、以下のようなエラーで先に進めませんでした

```
remote: -----> Installing dependencies using bundler 2.2.21
remote:        Running: BUNDLE_WITHOUT='development:test' BUNDLE_PATH=vendor/bundle BUNDLE_BIN=vendor/bundle/bin BUNDLE_DEPLOYMENT=1 bundle install -j4
remote:        Your bundle only supports platforms ["x86_64-darwin-19"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote:        Bundler Output: Your bundle only supports platforms ["x86_64-darwin-19"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
remote: 
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !
```
- エラーメッセージにある``bundle lock --add-platform x86_64-linux``を試しても解決できず
- 同様のエラーをぐぐるとbundlerのバージョン下げるべしとの記事も多数見つかるのですが、私の場合解決できませんでした。

# どう解決した
- Gemfile.lockのPLATFORMSにrubyを足す

```
PLATFORMS
  roby
  x86_64-darwin-19
  x86_64-linux
```

- すいません理屈はわかりませんわかったら追記します
- 以下のissueを参考にしました
  - https://github.com/rubygems/rubygems/issues/4269#issuecomment-759591430

- チュートリアルやってて同様の箇所でつまづいた人の助けになりますよう
【Project Euler】Problem 220 Heighway Dragonの感想（その１）

## Heighway Dragonとは
はじめて投稿します。Proejct Eulerをやられている方は結構いらっしゃるみたいですが100番以降になると、なかなか日本語の投稿が見つからなかったので、なんとか解けたもの感想等を投稿して行きたいと思います。（解答のコードは掲載していません）
元の問題はこちら->[Project Euler 220 Heighway Dragon](https://projecteuler.net/problem=220)

要はD50のHeighway Dragon曲線の10<sup>12</sup>番目の点の座標を求めろという問題です。

開発環境は[Google Colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb)上でPythonで書いています。

## まずHeighway Dragonを描いてみた
Heighway Dragonがどんなものか知らなかったのでまず素直に定義通りにプログラムを書いて描いてみました。関数HDragonを再帰的に使っています。

```python
# Heighway Dragon ; s: string, dp: depth 
def HDragon(s,dp): 
  if dp == -1: return 
  for c in s:
    if c == "a":   HDragon("aRbFR", dp-1)
    elif c == "b": HDragon("LFaLb", dp-1)    
    elif c == "F": pos = hdpath.forward()
    elif c == "R": dir = hdpath.turnR()
    elif c == "L": dir = hdpath.turnL()
  return 

depth = 18
posx, posy = [0], [0]
hdpath = path(np.array([0,0]),0,0)
HDragon("Fa", depth)
print(f"End: step={hdpath.step}, dir={hdpath.dir}")
```
Class ***Path***は各文字の***F,R,L***に従って座標や方向の変数を書き換えています。

```Python
DL = np.array([[0,1],[1,0],[0,-1],[-1,0]])  # U, R, D, L
class path:  
  def __init__(self,pos,dir,step):
    self.pos = pos
    self.dir = dir
    self.step = step
  
  def forward(self):
    self.pos += DL[self.dir]
    self.step += 1
    posx.append(self.pos[0])
    posy.append(self.pos[1])
    return self.pos
  
  def turnR(self):
    self.dir = (self.dir+1)%4
    return self.dir
  
  def turnL(self):
    self.dir = (self.dir-1)%4
    return self.dir
```
この結果得られた座標のリストを使ってmatplotlibで書いたものはこちらです（Depth=18）。

[Dragon Curve D=18]![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1922159/08c689cc-d1f2-6cea-1a2d-9519fc63ee81.png)
[01] ネットワーク名前空間で検証する ... ip addr add

# 概要

ip コマンドの挙動をチェックしたいが、通信障害を発生させてはいけない.

という状況で、仮想環境としてネットワーク名前空間を使った手順を記す.


# 環境

ホスト環境は Ubuntu 18.04 である.


# 手順

## 1. ネットワーク名前空間を作成する.

### 1-1. ネットワーク名前空間「host1」を作成する

```bash
$ sudo ip netns add host1
```

### 1-2. 仮想ネットワークI/F「veth-h1」を作成する

```bash
$ sudo ip link add name veth1-h1 type veth
```

作成できたことを確認する

```bash
$ ip link | grep veth1-h1
13: veth1-h1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 12:34:56:78:9a:bc brd ff:ff:ff:ff:ff:ff
```

### 1-3. 名前空間「host1」に対して、仮想ネットワークI/F「veth-h1」を適用する

```bash
$ sudo ip link set veth1-h1 netns host1
```

 
## 2. 上記「1」で作成した名前空間にログインする

プロンプトが「#」に変化した.

```bash
$ sudo ip netns exec host1 sh
# 
```


## 3. 「ip addr add」コマンドを実行する

### 3-1. 実行前の状態を表示する

コマンド「ip addr show」を実行する.

```bash
# ip addr show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: veth1-h1@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 12:34:56:78:9a:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0
```


### 3-2. ip addr add を実行する

「ip addr add 〜」を実行して IPアドレス、ネットマスクを設定する.

```bash
# ip addr add 192.168.1.1/24 dev veth1-h1
```


### 3-3. IPアドレスが設定できたことを確認する

コマンド「ip addr show」を実行する.
名前空間から脱出する際は、`exit` を実行する.

```bash
# ip addr show
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
13: veth1-h1@if12: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 12:34:56:78:9a:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.1/24 scope global veth1-h1
       valid_lft forever preferred_lft forever
```

　

# 補足

上記では名前空間にログインをしたが、
次のようにログアウトまでを実行することも可能である.

・`sudo ip netns exec <名前空間名> コマンド`」


```bash
## IPアドレス、ネットマスクを設定する
$ sudo ip netns exec host1 ip addr add 192.168.1.1/24 dev veth1-h1
 
## IPアドレスが設定できたことを確認する
$ sudo ip netns exec host1 ip addr show
```
Windows10 で Ruby3 + pg gem を利用して postgreSQL にアクセスするとエラー `AddDllDirectory failed for x64-mingw32` になる

## 現象

`bundle exec rake db:migrate` したけどエラーが発生する

```
PS C:\app> bundle exec rake db:migrate
rake aborted!
RubyInstaller::Runtime::DllDirectory::WinApiError: AddDllDirectory failed for C:/app/vendor/bundle/ruby/3.0.0/gems/pg-1.2.3/lib/x64-mingw32
C:/app/vendor/bundle/ruby/3.0.0/gems/pg-1.2.3/lib/pg.rb:15:in `block in <top (required)>'
C:/app/vendor/bundle/ruby/3.0.0/gems/pg-1.2.3/lib/pg.rb:26:in `rescue in <top (required)>'
（略）

LoadError: 126: 指定されたモジュールが見つかりません。   - C:/app/vendor/bundle/ruby/3.0.0/gems/pg-1.2.3/lib/pg_ext.so
C:/app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.1/lib/active_support/dependencies.rb:332:in `require'
C:/app/vendor/bundle/ruby/3.0.0/gems/activesupport-6.1.4.1/lib/active_support/dependencies.rb:332:in `block in require'
（略）
(See full trace by running task with --trace)
```

## 結論

環境変数 `RUBY_DLL_PATH` に `<your-path-to-postgresql>/bin` をセットして実行する。

### Powershell の場合（VSCodeの規定値？）

```
$env:RUBY_DLL_PATH='C:/Program Files/PostgreSQL/13/bin/'
```

### コマンドプロンプトの場合

```
set RUBY_DLL_PATH=<your-path-to-postgresql>/bin
```

## 調べたこと

`RubyInstaller::Runtime::DllDirectory::WinApiError: AddDllDirectory failed for x64-mingw32` でぐぐると、
pg の公式GitHubのIssue（[Ruby 3 Windows 10 Gem load Error · Issue #365 · ged/ruby-pg](https://github.com/ged/ruby-pg/issues/365)）がでてきました。

そこで[コラボレーターさん](https://github.com/ged/ruby-pg/issues/365#issuecomment-758717354)が以下のようにコメントしていました（意訳）。

- Ruby3.0用のにアップデートしたいと思ってるよ
- それまでは以下の３つの回避方法があるよ
    1. install postgresql per pacman: ridk exec pacman -S mingw-w64-x86_64-postgresql and reinstall pg gem（よくわからなかったので原文）
    1. 実行前に `set RUBY_DLL_PATH=<your-path-to-postgresql>/bin` してね
    1. Ruby を 3.0 未満にしてね

自分は、あまり考えず 2. でやってみたところ、無事動いたのでこれで良しとしました。
なお、VSCodeのターミナルが PowerShell だったことを忘れていて30分ぐらい格闘してました泣
DB設計のセオリーである正規形を自分なりにまとめてみた

こんにちは、プレイライフ株式会社の熊﨑です！
最近DBの基礎を学習しようと思い、「おうちで学べるデータベースのきほん」を読んでいます。
その中で、正規系について学習したのでこちらでまとめてみました。

## 正規形とは
リレーショナルデータベースの世界で古くから定義されているDB設計のセオリー
第1正規形から第5正規形まで存在する。
本記事では、第1〜第3正規形までを解説する。（「おうちで学べるデータベースのきほん」では第３正規形まで押さえておけば実務としては充分なレベルと書いてあったため）

## 第１正規形
テーブルのセルにスカラ値（単一の値）以外を含まないテーブル

### 非第1正規形のテーブル

##### イベントテーブル

|イベントID  |イベント名  | イベントの主催者 |
|---|---|---|
|1  |バイクでツーリング  |田中さん  |
|2  |ボードゲーム大会  |（佐藤さん、鈴木さん） → 配列のような複合的な値 |

### 第1正規形のテーブル

##### イベントテーブル

|イベントID  |イベント名  |
|---|---|
|1  |バイクでツーリング  |
|2  |ボードゲーム大会  |

##### イベント主催者テーブル

|イベントの主催者ID|イベントID   | イベントの主催者 |
|---|---|---|
|1|1  |田中さん  |
|2|2  |佐藤さん  |
|3|2  |鈴木さん  |

このようにイベントテーブルとイベントの主催者テーブルを分けることで、無理なくどちらのテーブルも単一の値をセルに入れることができる。


#### これじゃダメなのか？

##### イベントテーブル

|イベントID  |イベント名  | イベントの主催者1 |イベントの主催者2 |
|---|---|---|---|
|1  |バイクでツーリング  |田中さん  |　Null |
|2  |ボードゲーム大会  |佐藤さん　| 鈴木さん |

第1正規形ではあるが、イベントの主催者が今後増えていった時にイベントの主催者カラムを増やしていく必要がある。
→変更に強くない。

### なぜリレーションデータベースでは複合的な値を入れてはいけないのか？
関数従属性（主キーから、他のカラムの値が一意に特定できること）が成立しないから。

さっきの非正規形のイベントテーブルの場合、
イベントidが２の時のイベントの主催者は佐藤さんか田中さんのどちらかになり、一意には定まらない。


|イベントID  |イベント名  | イベントの主催者 |
|---|---|---|
|1  |バイクでツーリング  |田中さん  |
|2  |ボードゲーム大会  |（佐藤さん、鈴木さん） |

## 第２正規形
第１正規形から、部分関数従属を取り除いたもの

### 非第2正規形

##### 注文テーブル
主キーは顧客IDと注文番号。（複合主キー）
顧客IDがわかると、顧客企業名と顧客企業規模は一意に特定できる。（部分関数従属）

|顧客ID  |注文番号  | 注文日 |顧客企業名 |顧客企業規模|
|---|---|---|---|---|
|1  | 1|2021-08-21  |　A株式会社 | 大規模
|2  | 2|2021-08-22  |　B株式会社 | 中規模
|1  | 2|2021-08-23  |　A株式会社 | 大規模

### 第２正規形

##### 顧客テーブル
|顧客ID  |顧客企業名 |顧客企業規模|
|---|---|---|
|1  |　A株式会社 | 大規模
|2  |　B株式会社 | 中規模

##### 注文テーブル
|顧客ID  |注文番号  | 注文日 |
|---|---|---|
|1  | 1|2021-08-21  |
|2  | 2|2021-08-22  |
|1  | 2|2021-08-23  |

### なんで第２正規形にする必要があるのか？
データを登録する際に、多くの情報を知っていないといけないから

|顧客ID  |注文番号  | 注文日 |顧客企業名 |顧客企業規模|
|---|---|---|---|---|
|1  | 1|2021-08-21  |　A株式会社 | 大規模
|2  | 2|2021-08-22  |　B株式会社 | 中規模
|1  | 2|2021-08-23  |　A株式会社 | 大規模

上のテーブルだと、データを登録する際に、何度も顧客企業名や顧客企業規模を登録する必要がある。
その際に、間違えてA株式会社を株式会社Aと登録してしまうリスクも起きる。（更新異常）

第２正規形にすることで、更新異常が起きにくく、かつ仮に企業名の変更があった際の変更箇所が１箇所で済むという利点がある。

## 第３正規形
第２正規形から推移関数従属を取り除いたもの

### 非第3正規形

##### イベントテーブル

|イベントID  |イベント名  | ジャンルコード| ジャンル名
|---|---|---|---|
|1  |バイクでツーリング  | 0001| ツーリング
|2  |ボードゲーム大会  | 0002| テーブルゲーム

### 何がまずいのか？
新しいイベントジャンルを先に登録しようと思っても、イベントIDやイベント名も入力しないといけない。
→ジャンル単体での管理が不可能

### どうしてこうなったのか？
推移関数従属が存在しているため

推移関数従属とは主キー以外のカラム間で関数従属ができてしまっている状態を指す。
なぜ推移と名が付くかというと、

`{主キー} → {ジャンルコード} → {ジャンル名}`
のように、２段階の関数従属が存在しているから

### 第３正規形

##### イベントテーブル

|イベントID  |イベント名  | ジャンルコード|
|---|---|---|
|1  |バイクでツーリング  | 0001|
|2  |ボードゲーム大会  | 0002|

##### ジャンルテーブル

| ジャンルコード| ジャンル名
|---|---|
| 0001| ツーリング
| 0002| テーブルゲーム

このように管理することで、ジャンル単体でのデータ管理が可能になった。

## まとめ
- 正規形はDB管理をやりやすくするためのセオリー
- 第１正規形はテーブルのセルにスカラ値以外を含まないテーブル
- 第2正規形は第１正規形から部分関数従属を取り除いたテーブル
- 第3正規形は第2正規形から推移関数従属を取り除いたテーブル
- 正規形に則ったテーブル設計を行うことで、変更に強いテーブル設計ができる。

## 参考文献
木村明治, おうちで学べるデータベースの基本, 翔泳社, 2015, p263-273
JavaScriptを基本からまとめてみた【16】【async / await】

##はじめに

####学習するに至った経緯
2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

##「async/await」とは
『async / await』とは、Promise系の処理を同期的な書き方で書ける画期的な構文。
要するに、『async / await』を使えば、記述がシンプルで、途中に非同期処理があっても上から下にコードが読めるようになり、直感的でわかりやすい。Promiseによる非同期処理をより簡潔に効率よく記述できるのが大きな特徴。最大の利点は、「for文やwhile文で利用できる」こと。従来の書き方では、繰り返し処理の非同期化のために再帰処理を施したりと、とても複雑なプログラムになりがちだったが改善された。

##「async/await」の使い方
・　非同期処理を伴う関数定義に async をつける
・　非同期処理を伴う関数実行時に await をつける
・　awaitはasync付き関数内でしか使えない

```sample.js
const asyncAwaitFunc = async() => {
  const hoge = await someAsynchronousFunc(() => {
//何かしらの非同期処理
 }).then(() => {
//非同期処理が成功した場合
　 return '成功!'
 }).catch(() => {
//非同期処理が失敗した場合
　 return '失敗!'
 })
}
```




##参考サイト
[【JavaScript入門】5分で理解！async / awaitの使い方と非同期処理の書き方]
(https://www.sejuku.net/blog/69618)
[JavaScriptのasync/await 理解してますか？ 説明できますか？ クイズに答えてもらって良いですか？]
(https://www.youtube.com/watch?v=T-_0Pc5P12U)
[非同期処理の完了を待つ方法！Promise＆async/await【分かりすぎて怖いJavaScript入門】]
(https://www.youtube.com/watch?v=Vhnz1V-v1cU&t=1364s)