OmniAICreator/Qiita-1.07M huggingface dataset:
「初心者向け」GitHub運用④：メンバーを招待！

# この記事はこんな方向けです！
**細かいことは置いといて**
・GitHubの基本的な使い方を知りたい!
・GitHubでのチケットベース開発を知りたい！
・Slackと連携の取り方を知りたい！

そんな方への**手っ取り早いハウツーな記事**です

# この記事を読み終えますと、

Project管理について
OrganizationのTeam単位で、権限を付与できるようになります。


# いくつか記事を分けます

本記事では**「他人を招待し、権限付与」**についてです。

基礎
1. [OrganizationとTeamを作ってみる](https://qiita.com/kotaro_bayashi/items/dd70fbf14b8bf43143a9)
2. [Projectを作ってみる](https://qiita.com/kotaro_bayashi/items/aa62989350c4367caa60)
3. [Issueを作ってみる](https://qiita.com/kotaro_bayashi/items/36d10f030c5dfbaaed1c)
4. **他人を招待し、権限付与**

応用
5. [Hubotを使ってみよう〜Heroku自動デプロイまで](https://qiita.com/kotaro_bayashi/items/f82db9620643d0430d0d)
6. [HubotとSlackを連携](https://qiita.com/kotaro_bayashi/items/26ec3ff24a41fa942190)

# 1 メンバーを招待

OrganizationのPeopleの画面から、invite
- 「invite member」をクリック
- 招待したいアカウントを指定
![toInvite1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/9cf4b5e5-1cd3-f915-4ea2-21dfbb775a76.jpeg)

# 2 招待する時の設定
- Roleは「Member」
- 参加Teamを選ぶ
- send invitaion

![toInvite2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/4909e021-86ee-676d-a6f4-ad59ed3fee6d.jpeg)

- 招待された側はjoin

実際に動作を確認されるのでしたら、知り合いに協力してもらうか、もしくはご自身でGitHubのアカウントを登録してやってみてください。

# 3 Teamの権限を操作

**TeamのメンバーがIssue管理とpushができるしたい**
- 作成したRepogitoryの設定画面を開く
- 「Manage Access」をクリック
- 作成したTeamの権限を「Read」から「Write」に変更
![change Role.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/50e62c5b-eb29-940a-8a2c-5267848788f9.jpeg)

# 4 Issueをメンバーに割り当てる

- Note作成
- NoteをIssueに変換。bodyに「- [ ] ~~~」とする。これでチェックボックスができます。
- Assigneesに、先ほど招待したアカウントを設定   [※詳しくはこちら]
![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/2432b890-014d-7bbd-ba29-ef3c03709af5.jpeg)


# 5 招待されたアカウントから、Issueを編集してみる

招待されたアカウントから操作しますと...
**Projectのダッシュボードのカラムからは編集できない。editボタンがないです汗**
![edit Issue1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/66c7eee5-0539-1d5d-b8fa-acca2b3783b4.jpeg)

**でも、右端のパネルから編集ができます。**
※「Got to issue for full details」のクリック先でもできます。

招待された人でも、チェックボックスをクリックしたり、編集ができます。

![edit issue2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534534/1c3c2fba-987e-5ee8-0f5f-e8c05ad3dae4.jpeg)


# まとめ

この記事を含めて、4つの記事を通して、GitHubの基本的な操作をお伝えしてきました。
組織管理(OrganizationとTeam)とチケットベース駆動(Project)といったことに役立つGitHub機能について、
紹介しました。

ここまででほぼほぼGitHub運用はできるようになっていると思います。

「もう少し先が知りたいよ！」という人の方のために

次回は、[HubotをHeroku上にデプロイしてみましょう！](https://qiita.com/kotaro_bayashi/items/f82db9620643d0430d0d)
ESP32で重複したBLEアドバタイズパケットを表示する方法

# はじめに
EnOcean BLE <a href="https://www.switch-science.com/catalog/6525/">環境センサー(STM550B)</a> と <a href="https://www.switch-science.com/catalog/6526/">スイッチ(PTM215B)</a> は BLE ブロードキャストモードでアドバタイズパケットにデータを含めて送信する仕様です。
環境センサー(STM550B)はデフォルトで1分毎にデータを送信(1回の送信毎に同じデータを3回送信)し、スイッチ(PTM215B)は押す/離す度に同じデータを2回(押す→離すの時間間隔が短い場合、押す操作のデータ送信が2回になる)、または、3回送信します。
セントラル側はアドバタイズパケットをスキャンすればデータを取得できますが、スキャン中に同じアドレスから受信したアドバタイズパケットを無視するケースがあるので、回避策を考える必要があります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a28caf7c-b50b-d218-4d95-d57f5c3babc1.png" width="75%">

### NGのケース
コネクトモードを前提としたツールは最初に受信したアドバタイズパケットしか表示されないため、基本的に使用することは難しいです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8eedead5-e027-9e52-60e9-e53e0be66fee.png" width="75%">

### OKのケース
- Bluefruit LE Snifferを使用してBLEパケットデータをキャプチャー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/1555ef3d-2755-0ee3-fb26-9e3d3c81f4a6.png" width="75%">

- Node-REDフロー (node-red-contrib-blebeacon-scannerノード)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/9ea0f784-29e6-6291-5884-bb03f29604f4.png" width="75%">

## ESP32でBLEアドバタイズパケットの重複を表示する方法

### ArduinoBLEライブラリのインストール
「スケッチ」→「ライブラリをインクルード」→「ライブラリ管理」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/3a5ea644-0ae2-a67b-74e5-deb0100a8bf8.png" width="50%">

「ArduinoBLE」を検索してインストールします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/d58a0fa7-83e2-26c1-d6fd-bfef1f8d41f4.png" width="75%">

### ESP32 BLE Arduinoサンプルコードの実行
「ファイル」→「スケッチ例」→「ESP32 BLE Arduino」→「BLE_scan」を選択します。
BLE_scanサンプルコードの一部を修正すれば重複したアドバタイズパケットを表示することが可能です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/305677ea-689f-3792-ffac-dd34a06c5b76.png" width="50%">

### 修正箇所
ライブラリのソースコード(ヘッダーファイル)BLEScan.hを見ると、BLEScanクラスのsetAdvertisedDeviceCallbacksオプションにwantDuplicatesフラグ(デフォルトはfalse)を立てれば良いことが分かります。

```c++:BLEScan.h
class BLEScan {
public:
        void           setAdvertisedDeviceCallbacks(
                                      BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
                                                                                bool wantDuplicates = false);
```

BLE_scan.inoサンプルコードではフラグの指定が省略されていますので、明示的にtrueを設定します。

```c++:BLE_scan.ino
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
↓
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks(), true);
```

### 結果
- <a href="https://www.switch-science.com/catalog/6525/">環境センサー(STM550B)</a>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/9005da99-00bf-d7e7-9c58-71afe8e96fef.png" width="75%">

- <a href="https://www.switch-science.com/catalog/6526/">スイッチ(PTM215B)</a>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/a638516d-3618-e2db-22c9-ef9f3ec3c6b7.png" width="75%">
ZBOX EN52060VにUbuntu20.04をクリーンインストールする際のメモ


クリーンインストールするたびにハマるのでメモ

---

### 初期設定
[NVIDIA GeForce RTX2080 入りPC（ZBOX EN52060V）にUbuntu18.04をインストールを試みた際にエラー出てインストールが進まない](https://qiita.com/seigot/items/687fa2f6a2ac274b236f)
[ZBOX EN52060V+ubuntu18.04環境に、Killer AX1650 wifiドライバをインストールする](https://qiita.com/seigot/items/68547acf7bc53b331a97)
[ZBOX EN52060V+ubuntu18.04環境に、NVIDIA GeForce RTX 2060ドライバをインストールする](https://qiita.com/seigot/items/e353443cb165846e1225)

### よく使うツールをインストール

```
sudo apt-get install terminator
sudo apt-get install emacs
```

### dockerインストール
[Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/)

### 日本語入力
[Ubuntu 18.04 LTSで日本語が入力できない！どうすればいい？](https://linuxfan.info/ubuntu-18-04-japanese-input)

### etcher
[etcher](https://www.balena.io/etcher/)

### その他、トラブルシューティング
[How to install the NVIDIA drivers on Ubuntu 20.04 Focal Fossa Linux](https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-20-04-focal-fossa-linux)
[Ubuntu20.04がログインループで立ち上がらなくなった場合の対処法](https://qiita.com/musaprg/items/51c8f7ee8a54c0ee207b)
WordPress管理画面から最新バージョンの追加機能を確認する方法

WordPressバージョンアップ完了後に一瞬表示される画面ありますよね。
追加機能がビジュアルで一覧できる便利なページ。
これがWordPress管理画面からいつでも確認できる方法を見つけたので共有します。

#WordPress管理画面から確認する方法

WordPressのインストールURLが `https://example.com/` の場合、
 `https://example.com/wp-admin/about.php` でインストールされているWordPressの最新バージョン追加機能が確認できます。
WordPressインストールディレクトリの `/wp-admin/about.php` にアクセスします。

内容はこちらの動画キャプチャを参照ください。
このようなページが存在するんですね、バージョンアップ機能を確認できて便利です〜😘

![Alt text](https://gyazo.com/654284cf2ae7216c8dcdd8b2872a47f5/raw)

#過去バージョンのリリース機能を確認したい

WordPress公式サイトで過去のリリース機能を確認できます。

過去のWordPressリリースマップ（英語）
https://ja.wordpress.org/about/history/
過去の機能リリースが確認できます。
日本語バージョンがほしい🥺

日本語はBlogのReleaseカテゴリから確認できます。
https://ja.wordpress.org/category/releases/
マイコンの始め

独自研究内容が含まれます。自分史的にマイコンいじり40周年のアニバーサリーイヤーなのでいろいろ昔の事を調べています。

一般的に始めてのマイコンは1975年にアメリカで発売されたAltairといわれています。Altairにはインテルの8080が使われていました。

インテルの8080のマニュアルにはインストラクション以外にマクロなどのアセンブラの仕様も書かれています。

今も昔も、新しいコンピューターは必ずクロスの開発で始まります。

いろいろ調べてみるとインテルはFortrun(66?)で書かれたクロスアセンブラを提供していたようです。多くのユーザーはそれをDEC社のミニコンPDP-10などで使っていたと思われます。おそらくその仕様がマニュアルに書かれてるのではないでしょうか。

マイクロソフトはおそらくこの環境を使い、1975年にリリースしたAltair BASICを作ったのではないかと想像されます。

創業間もないマイクロソフトが高価なPDP-10購入する事は不可能で、ハーバード大学にあった、マシンを使ったようです。

Altair BASICは紙テープで提供され、シリアル接続のビデオターミナルが入出力だったようです。

Altair BASICはかなり早い時期に実数すなわち浮動小数点とsinなどの関数のサポートが入りそれが成功につながったような気がします。

BASICは簡単に使える言語としてダートマス大学でミニコン用に開発されましたが、マイコンにとってのBASICはセルフで開発できる環境という側面も持つ事になりました。

その後CP/M用に提供されたMACRO-80もCP/MのASMを使ったのではなくAltair BASICと同じくクロスで作られたのでような気がします。

MACRO-80ができてからは徐々にセルフ開発に移っていたのではないでしょうか。

MACRO-80がASMなどとは違ったのはリロケータブルなオブジェクトファイルを作成しLINK-80で複数のオブジェクトファイルからバイナリを作る事ができたことです。この仕組みはBASICコンパイラなどのオブジェクトのリンクにも使われていたようです。大規模なソフトウエア開発に有効だったのではないかと考えられます。

CP/M上のMBASICはバージョン4.4で1977のメッセージが確認できAltair BASICバージョン4の入出力を変えただけなのではないかと思います。MBASICの最終バージョンは5.21だったようです。

いろいろ調べて見ると1977年にはMicrosoft Disk BASIが完成していて、これにはMS-DOSでもおなじみのFATが使われていたようです。

Altair BASICはマイクロソフトの始めてのプロダクトでMACRO-80は開発環境の始まりで、MS-DOSはOSの始まりだったと思います。

マイクロソフトの創業時の話はAltair BASICやMS-DOSの話がよく語られますが、MACRO-80も商業的にも自社開発にも非常に重要な役割を果たしたのではないでしょうか。

![EfLSo5SU4AALEq6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/7dc192f4-569a-6b34-ab99-04c61a4317c2.jpeg)

Altair BASICはビルゲイツが作ってMS-DOSは会社を買ったといわれていますが、MACRO-80は誰が作ったのでしょうかね？
Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile (LoadError)というエラーの解決法について

 Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile (LoadError)というエラーの解決法について


原因は、gemのlistenが開発環境にあることにある。
つまり、
gem 'listen'をdevelopmentだけではなく、全体に影響させればいいので、gemfileの最後に記述するとかして、bundle install bundle updateすれば、

解決するだろう。
vim で Markdown table をぺろっと整形する

## 背景

* Markdown の table の整形めんどい
* vim でぺろっと整形したい

Markdown での表の表現はいくつかりますが, ここでは `|` で表現する形式(qiita や github で採用されている形式?)を想定します.


## 方法

vim-easy-alignでvimmerへの道を極めよう
https://qiita.com/takuyanin/items/846cb2b3e541f79f0d54

Align GitHub-Flavored Markdown Tables in Vim
https://thoughtbot.com/blog/align-github-flavored-markdown-tables-in-vim

ありがとうございます! vim-easy-align 使います.

## Install

私の場合は NeoBundle でしたので, `~/.vimrc` の neobundle のところに

`NeoBundle 'junegunn/vim-easy-align'`

を追加し, vim 起動して

`:NeoBundleInstall` でいけました.


## 整形

table の領域を選択して, `:EasyAlign` で起動して, `*|` でいけます.


Align GitHub-Flavored Markdown Tables in Vim

を参考にして, ショートカットを登録しましょう.

```
au FileType markdown vmap <Leader><Bslash> :EasyAlign*<Bar><Enter>
```

を vimrc についかします.

デフォルト(Leader が設定されておらず `\` に割り当たっている)ですと, table 領域選択して `\\` でぺろっと整形できます! :tada:
[Java]SpringBoot + Doma2 + H2

公式チュートリアルやってみた。
https://github.com/domaframework/doma-spring-boot

```application.properties
doma.dialect=h2
```

```xml:pom.xml
<!-- h2追加-->
<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <scope>runtime</scope>
</dependency>

<!-- Doma関連追加-->
<dependency>
  <groupId>org.seasar.doma.boot</groupId>
  <artifactId>doma-spring-boot-starter</artifactId>
  <version>1.4.0</version>
  <exclusions>
    <exclusion>
      <groupId>org.seasar.doma</groupId>
      <artifactId>doma-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.seasar.doma</groupId>
  <artifactId>doma</artifactId>
  <version>2.29.0</version>
</dependency>
```

```java:Entity
import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;

@Entity
public class Reservation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer id;
    public String name;
}

```

```java:Dao
import java.util.List;

import org.seasar.doma.Dao;
import org.seasar.doma.Insert;
import org.seasar.doma.Select;
import org.seasar.doma.boot.ConfigAutowireable;
import org.springframework.transaction.annotation.Transactional;

@ConfigAutowireable
@Dao
public interface ReservationDao {
    @Select
    List<Reservation> selectAll();

    @Insert
    @Transactional
    int insert(Reservation reservation);
}
```


### エラーシューティング

ビルドエラーが発生した場合・・

参考：https://doma.readthedocs.io/en/2.5.0/build/
[Eclipse を使ったビルド]
・注釈処理の有効化
・Factory Path の設定
【学習記録】AWS VPCについて

# Amazon VPCとは？
VPCとは、Virtual Private Cloudの略です。Amazon VPCはAmazonが提供している仮想ネットワークのこと。
この仮想ネットワーク内で、AWSリソースを起動できる。

# VPCを学ぶ上で必要な知識
***アベイラビリティゾーン（AZ）***
>AWSの各リージョンに存在するデータセンターのこと。アベイラビリティゾーンにサブネットを配置する。

***リージョン***
>AWSの各サービスが提供されている地域のこと。AWSでサービスを利用するときは、まずリージョンを指定する。リージョンによって使えるサービスは異なる。

***サブネット***
>VPCを細かく区切ったネットワークのこと。VPCのIPアドレスの範囲。
例えば、Webサーバー（公開）とDBサーバー（非公開）を分けたいときVPC内でpabulicサブネットとprivateサブネットのように区切って使用する。

***ルーティング***
>どのデータをどこに送るか采配すること。VPCとインターネットをつなげたい場合は、このルーティングでインターネットゲートウェイとのルーティング設定を行わないとつながらない。

***ルートテーブル***
> ルーティングに関する設定が書かれたテーブル。１つのサブネットに１つルートテーブ
ルを用意できる。
宛先のIPアドレスと次のルーター（ターゲット）の２つを記載している。

***インターネットゲートウェイ***
> VPCをインターネット接続できるようにするコンポーネント。インターネットへの出入り口。


# 参考
書籍：Amazon Web Serviceのしくみと技術がこれ１冊でしっかりわかる教科書

講義：[ゼロから実践するAmazon Web Services。手を動かしながらインフラの基礎を習得](https://www.udemy.com/course/aws-and-infra/)
MPEG2のDICOMってどうすりゃいいの

LinacのEPIDで取得した動画をdicom形式でexportした。いつも通りにpydicomで解析してみる。

```
import pydicom
dicom_data = pydicom.dcmread(file_name)
```

すると、

```
(0002, 0010) Transfer Syntax UID                 UI: MPEG2 Main Profile / Main Level
```

なるほど、動画なんですね。
いつもの通り、

```
array = dicom_data.pixel_array
```

でpixel arrayを取得しようとすると、

```
NotImplementedError: Unable to decode pixel data with a transfer syntax UID of '1.2.840.10008.1.2.4.100' (MPEG2 Main Profile / Main Level) as there are no pixel data handlers available that support it. Please see the pydicom documentation for information on supported transfer syntaxes 
```
あれ、うまくいかない。
`dicom_data.PixelData`から解析するかと思いながら、めんどいな、もしかして普通に動画ファイルとして解析できちゃったりしないかな、なんて思って、

```
import cv2
cap = cv2.VideoCapture(file_name)
```
あれ、エラーでない。いけるのか？

```
frames = []
while True:
    ret, frame = cap.read()
    if ret == True:
        frame=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY) #Gray scaleにしてあるよ
        frames.append(frame)
    else:
        break
```
とかしてみたら無事に`frames`のリストができてる。
これを `np.array(frames).shape`とかすれば

```
(143, 576, 720)
```

なるほど、576 x 720 の画像が143枚入っているのがわかる。
あとは`plt.imshow(np.array(frames)[0,:,:])`として最初の画像が表示できた。

dicomファイルだからと身構えず普通に動画ファイルとしてopencvを使って解析できることがわかった。
コンマや△の入った数値を数値型に変換する。

#1　この記事は
有価証券報報告書に記載されている△や,の入った数値をpythonが扱える数値型に変換するコードを掲載します


#2 コード作成例

###パターン1
'△45,931'の場合

```python:test.py
moji='△45,931'

def conv(moji):
    moji=moji.replace('△', '-')
    moji=moji.split(' ')[-1]
    moji=moji.replace(',', '') 
    moji=int(moji)
    return moji

moji=conv(moji)
print(type(moji))  ##<class 'int'>
print(moji)        ##-45931
```







###パターン2
'※1 889,341'の場合


```python:test.py
moji='※1 889,341'
def conv(moji):
    moji=moji.replace('△', '-')
    moji=moji.split(' ')[-1]
    moji=moji.replace(',', '') 
    moji=int(moji)
    return moji

moji=conv(moji)
print(type(moji)) #<class 'int'>
print(moji) #889341
```
[Java]MinecraftのModを作成しよう 1.14.4【99. Modの出力】

（この記事は一連の解説記事の一つになります）

先頭記事：[入門編](https://qiita.com/koteko/items/7afadf8261eac49bacad)

# Modの出力
丹精込めて作ってきたModがいい感じになってきたならば、他の人が遊べるようにjarファイル(Java Archive)に出力してみましょう！

```
D:\projects\mc_example_mod
　├ src
　├ build.gradle
　├ gradlew
　├ gradlew.bat
　└ gradle
　 　└ wrapper
　 　　　└ gradle-wrapper.jar
　 　　　└ gradle-wrapper.properties
```
[入門編](https://qiita.com/koteko/items/7afadf8261eac49bacad)で同じようにセットアップしている場合、プロジェクトファイルはこのようになっていると思います。`build.gradle`を編集します。

```gradle:build.gradle
buildscript {
    repositories {
        maven { url = 'https://files.minecraftforge.net/maven' }
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
    }
}
apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

version = '1.0'
group = 'jp.koteko.example_mod' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'example_mod'

sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.

//...
```
16~18行目の`version``group``archivesBaseName`の項目を自分のModに合うよう書き換えます。そのほかの部分は必要ない記述も多い気がしますが、問題にはならないのでそのままでよいです。

書き換えたら、プロジェクトフォルダ(この例では`D:\projects\mc_example_mod`)でPowerSellを起動します(エクスプローラー上でShift+右クリック、あるいは普通に`cd`で移動)。
`.\gradlew.bat build`のコマンドを実行して10秒ほど待ちます。`BUILD SUCCESSFUL`の表示が出たら成功です。
`\build\libs`フォルダ内に`[archivesBaseName]_[version].jar`のファイルが生成されているはずです。これがいわゆるModとして配布されるファイルになります。

Modの導入に関しては~~めんd~~技術解説の範疇を超える(というか世に解説が溢れている)ので省略しますが、Forgeを導入してmodsフォルダに先ほどのjarファイルを配置し、ゲームを起動します。
タイトルからmods画面を開き、自分のModが認識されていれば成功です。不安であればゲーム内で実際に確認しましょう。

**長旅おつかれさまでした。**

# 余談
<details><summary>今後の記事について</summary>
まだまだ解説が足りていない部分や、触れられていない要素も数多くありますが、一旦Minecraft 1.14.4における解説記事を区切りにして、1.16.1の環境を立ててそちらで改めて開発をしていこうかなと考えております。Mod開発は、仕様の大幅変更や公式アプデ間隔などの理由から、いくつか主流なバージョンがあり、一つ前だと1.12.2がそれにあたります。1.14.4もある程度の数はあるようですが、1.12.2残留組、開発意欲の高い追従組のどちらと比べてもやや数が少なく、このバージョンでの開発を進めるデメリットが感じられたのでこのように判断しました。1.16.1がどれだけ多くのModが作られるバージョンになるかは不明ですが、2020年8月現在で最新版なので、将来性と情報の少なさという点からこちらの開拓を優先しようと思います。
</details>

# 参考
[Minecraft 1.12 modding with forge – 10 – Export Mod &#8211; suppergerrie2.com](https://suppergerrie2.com/minecraft-1-12-modding-with-forge-10-export-mod/)
GitHub ActionsのMatrixビルドであるJobがコケても他のJob(s)をcancelさせない方法

GitHub ActionsのMatrixビルドで複数Jobが並列で走ったとき、あるJobがfailするとデフォルトでは他のJobは途中でCancelされてしまう。もしそれら複数Jobが特に依存関係ない場合はCancelにしたくないのではないかと思う。これを実現するのが`fail-fast`オプション。

**jobs.\<job_id\>.strategy.fail-fast**
>When set to true, GitHub cancels all in-progress jobs if any matrix job fails. Default: true

ref: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast

Matrixビルドにおいて、fail-fastは特に指定しなければtrue、つまりあるJobがfailすると他のJobは途中であってもCancelする。これをfalseにすることでこの動きを止めることができる、つまりあるJobがfailしても他のJobはcancelされず最後まで処理が継続される。

```yaml
strategy:
  fail-fast: false
  matrix:
    node: [11, 12]
    os: [macos-latest, ubuntu-18.04]
```

以上、Happy GitHub Actions!
M5StackのLCDをMicroPythonから使ってみる(低速)

#免責
この記事に従って発生した如何なる損害も筆者は負うことができません。ご免なさい。

# 目的
[M5Stack Basic](https://www.switch-science.com/catalog/3647/)を買ったので、[Flash Download Tools](https://www.espressif.com/en/support/download/other-tools)で[本家のMicroPython](https://micropython.org/resources/firmware/esp32-idf4-20191220-v1.12.bin)を入れて液晶を使ってみます。pythonコードなので非常に低速です。

# ライブラリの用意
WebREPLなどを使って[ili9342c.py](https://raw.githubusercontent.com/tab4moji/M5StackCoreLCD/master/ili9342c.py)をM5Stackに転送してください。
MicroPythonの開発には[uPydev](https://github.com/Carglglz/upydev)が便利なので、[こちら](https://qiita.com/tab4moji/items/9ec96037412cbd550af2)も見てやってください。

# サンプルコード
ili9342c.pyが使えるようになったら、以下のように動かせます。

```python:MicroPython
>>> import ili9342c
>>> color565 = ili9342c.color565
>>> from machine import Pin, SPI
>>> spi = SPI(miso=Pin(19), mosi=Pin(23, Pin.OUT), sck=Pin(18, Pin.OUT))
>>> display = ili9342c.ILI934X(spi, cs=Pin(14), dc=Pin(27), rst=Pin(33), bl=Pin(32))
>>> display.fill(color565(0x00, 0x00, 0x00))
>>> 
>>> display.fill_rectangle(150, 150, 40, 10, color565(0x00, 0xff, 0x00))
>>> display.fill_rectangle(10, 10, 20, 60, color565(0x00, 0x00, 0xff))
>>> display.fill_rectangle(200, 70, 50, 50, color565(0xff, 0x00, 0x00))
>>> display.text('Hello,World!', 16, 128)
>>> display.scroll(8)
>>> display.scroll(8)
>>> 
>>> import sys
>>> del sys.modules['ili9342c']
>>> del sys
>>> 
```

# 参考
みなさまのおかげです。

### M5Stack CORE – BASIC Version (ILI9341 BL(backlight))
http://m5edu.com/Product/m5stack-core-basic-version/

### Flash Download Tools (ESP8266 & ESP32 & ESP32-S2)
https://www.espressif.com/en/support/download/other-tools

### Firmware with ESP-IDF v4.x (esp32-idf4-20191220-v1.12.bin)
https://micropython.org/download/esp32/

### micropython-ili9341
https://bitbucket.org/thesheep/micropython-ili9341/src/default/ili9341.py

### ILI9340/ILI9341 TFT Display
https://forum.micropython.org/viewtopic.php?t=1996&start=30#p41672

### ILI9342C Datasheet
https://logictechno.com/wp-content/uploads/2016/09/LTTD320240023-L1-V1.2-driver-IC_ILI9342C.pdf
IBM Cloudを用いたシステムのアーキテクチャを検討するときに役立つコンテンツ

# IBM Cloud Architecture Center

IBM Cloudを用いたシステムのアーキテクチャを検討する際、ゼロから検討するのではなく、既存の実績あるアーキテクチャを参考にすることで、より品質の高いアーキテクチャを実現できます。

AWSでは[AWSアーキテクチャーセンター](https://aws.amazon.com/jp/architecture/)として、AWSベースのシステムアーキテクチャのリファレンスが提供されていますが、IBM Cloudでも **[IBM Cloud Architecture Center](https://www.ibm.com/cloud/architecture)** として同様のものが提供されています。

残念ながら日本語版はなく英語のみですが、業種別、テクノロジー別に様々なアーキテクチャモデルが提供されており、非常に参考になります。


# IBM Cloudのアーキテクチャ図サンプル、アイコン集

また、アーキテクチャ図を描く際に便利なものとして、サンプルの図と、各種のサービスを表現するためのアイコンがあります。

IBM Cloudでは、**[Editable architecture diagram resources](https://www.ibm.com/cloud/architecture/architectures/edit)** において、図を作成する際の各種素材が提供されています。

PowerPointはもちろんのこと、Visio、OmniGraffle用の素材も提供されています。

さらに、[draw.io](https://www.draw.io/) でもIBM Cloudのサンプルの図、アイコンが提供されており、draw.io での図の描き方、アイコンの使用方法などを紹介した[動画](https://www.ibm.com/cloud/architecture/architectures/edit/draw)も提供されています。

なお、draw.ioでも描けるということで、VSCodeのdraw.io用エクステンションでもIBM Cloudのサンプル図、アイコンが利用できるようになっています。

参考：[VSCodeでDraw.ioが使えるようになったらしい！](https://qiita.com/riku-shiru/items/5ab7c5aecdfea323ec4e)


# 学習コンテンツ

IBM Cloud Architecture Centerでは、上記以外にも、各種の学習用コンテンツが提供されています。

[Courses and tutorials](https://www.ibm.com/cloud/architecture/courses)

IBM Cloud関連だけでなく、TDDやChatOpsといった設計・開発手法や、Docker、Kubernetesの基礎といったコンテンツもあるので、もし興味があれば探してみてください。全て英語のみなのが残念ですが...。
laravel SQLSTATE[HY000] [2002] Connection refused

###SQLSTATE[HY000] [2002] Connection refused (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')エラー対処

メモ

.envの修正もしたのに解決しなかった場合、下記コマンド実行したら解消しました。

```
php artisan key:generate
php artisan cache:clear
php artisan route:clear
php artisan config:clear 
php artisan view:clear 
```
Jupyter-lab + matplotlib でマウス位置の画像データのピクセル値を表示するメモ

## 背景

画像データ(RGB もだが, 物理データやテンソルデータの画像など)のピクセル値を Jupyter-lab でお手軽ぺろっとやりたい

## 方法

Jupyter notebook と Jupyter-lab とは仕組みが違うようで, notebook のやり方は使えません(`%matplotlib notebook`, `inline` もだめだった)

matplotlib の interactive plot は仕組みが違うらしく(JS 出力なものを使う必要がある?) 2020 年 8 月 11 日時点の jupyter-lab では以下の方法のみ使えました.


https://stackoverflow.com/a/56416229

ipympl と, jupyter-matplotlib 拡張をインストールが必要です.


```
$ jupyter labextension install @jupyter-widgets/jupyterlab-manager
$ jupyter labextension install jupyter-matplotlib
```
 
をします.

jupyterlab-manager は Jupyter-lab 上でも行えます. 

## sample

from stackoverflow

```
%matplotlib widget
import matplotlib.pyplot as plt
import numpy as np
import ipywidgets as wdg  # Using the ipython notebook widgets

# Create a random image
a = np.random.poisson(size=(12,15))
fig = plt.figure()
plt.imshow(a)

# Create and display textarea widget
txt = wdg.Textarea(
    value='',
    placeholder='',
    description='event:',
    disabled=False
)
display(txt)

# Define a callback function that will update the textarea
def onclick(event):
    txt.value = str(event)  # Dynamically update the text box above

# Create an hard reference to the callback not to be cleared by the garbage collector
ka = fig.canvas.mpl_connect('button_press_event', onclick)
```

![Screenshot from 2020-08-12 14-35-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/c43244d4-1b5a-d3ed-4dc7-38be67f0a92c.png)

Voila! :tada:

```
        @axlair/jupyterlab_vim v0.12.2  enabled  OK
        @jupyter-widgets/jupyterlab-manager v2.0.0  enabled  OK
        itkwidgets v0.27.0  enabled  OK
        jupyter-matplotlib v0.7.3  enabled  OK
```

## zoom

shift + 左ドラッグで zoom in できます.
右ドラッグで zoom out できるようですが, 使い勝ってがいまいちです.

## picker

picker のイベント登録で, いろいろ拡張できるでしょう.

jupyterlab で matplotlib のプロット図に picker を設定するメモ
https://qiita.com/syoyo/items/7644dbcd2f2cd84c02bb

picker などのイベントと組み合わせして, ユーザー指定した 4 角を colorchecker の枠に指定する, とかみたいな処理ができると想像できます.

## ipywidgets interact との組み合わせ

一応 interact と組み合わせできるの確認しました.

https://ipywidgets.readthedocs.io/en/latest/examples/Using%20Interact.html

しかし

```
# Create a random image
def bora(sx):
    a = np.random.poisson(size=(sx,15))
    fig = plt.figure()
    plt.imshow(a)

    # Create and display textarea widget
    txt = wdg.Textarea(
        value='',
        placeholder='',
        description='event:',
        disabled=False
    )
    display(txt)

    # Define a callback function that will update the textarea
    def onclick(event):
        txt.value = str(event)  # Dynamically update the text box above

    # Create an hard reference to the callback not to be cleared by the garbage collector
    ka = fig.canvas.mpl_connect('button_press_event', onclick)

interact(bora, sx=15)
```

な感じにすると, fig をたくさん開いているよ warning が出てしまいました.
適宜 close を呼ぶ必要がありそうです.
プランターの土壌温度をAmbient+シェルスクリプトで可視化してみた。

# 概要

データを簡単に可視化できるサービス「Ambient」にシェルスクリプトからデータを送信する方法を示します。（あまり需要はなさそうですが）

# 背景

ベランダのプランターでオクラとバジルを育て始めたので、自動で水やりをするシステムをRaspberry Pi Zero W(以下RPi)とポンプを使って作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189186/b05077f4-d026-9985-7953-f491963328fb.png)

ところで、「日中に水やりをすると、土の中の温度が上がり植物に良くない」とよく言われますが、「水を撒けば水そのものの温度や気化熱で、かえって温度は下がるのでは？」と疑問を持ったので、実際に測定してみることにしました。

ついでにRPiのCPUコア温度もモニタリングし、RPi自身の状態の参考にします。

# 使った機材

* Raspberry Pi Zero W
* DS18B20の温度計  
https://www.aliexpress.com/item/32676135779.html


# 方法

以下にシェルスクリプトを示します。

```bash
#!/bin/bash

# チャネルID
channelId="*****"
#ライトキー
writeKey="*****"

url="http://ambidata.io/api/v2/channels/${channelId}/dataarray"

# 1-Wire温度センサから温度を取得
soil_temp="$(grep -m1 "t=" /sys/bus/w1/devices/28*/w1_slave | sed -r 's/.*t=([0-9]{2})([0-9]+)$/\1\.\2/')"
# CPUコア温度を取得
cpu_temp="$(awk '{print $1 / 1000.0}' /sys/class/thermal/thermal_zone0/temp)"

data_text='[{"d1":"'${soil_temp}'","d2":"'${cpu_temp}'"}]'

curl -H 'Content-Type:application/json' \
-d '{"writeKey":"'${writeKey}'", "data":'${data_text}'}' \
${url}

```

処理の流れ：
1. `channelId`,`writeKey`,`url`を設定します。
2. 1-Wire接続の温度センサDS18B20から温度を取得して`soil_temp`に格納します。1-Wireのデバイスは`/sys/bus/w1/devices`以下にデバイス毎のディレクトリとして認識されますが、温度センサであればディレクトリ名は28から始まります。`grep`で28から始まるディレクトリにある、`w1_slave`中の`t=`の行を抜き出します。`-m1`は、結果が複数あっても１行だけ結果を返すオプションです。`sed`では`t=`以降の温度部分を抜き出しています。温度は５桁の整数で渡されるので、先頭2桁とそれ以降に分けて、間に`.`をつけることで擬似的に小数に変換しています。
3.CPU温度を取得して`cpu_temp`に格納します。awkコマンドで`/sys/class/thermal/thermal_zone0/temp`から取得したCPU温度を1000で割って小数にしています。
4.取得した`soil_temp`と`cpu_temp`をjsonフォーマットに整形して`data_text`に格納します。
5. curlコマンドでambient宛にデータをPOSTします。`writeKey`でライトキーを渡してやります。

# 実行した結果

以下で確認出来ます。
https://ambidata.io/bd/board.html?id=15241

上記のスクリプトをcronで定期実行しています。
ディレクトリ内のPSDファイルをPDFに一括変換

psdファイル（元データ）とpdfファイル（変換後）それぞれ用のディレクトリがある親ディレクトリで実施する前提

```bash

$ ls
psd_dir/ pdf_dir
```

ImageMagickを利用

```bash

for file in `ls psd_dir`; do
  # 拡張子削除
  base=`basename "${file}" .psd`
  # 変換
  convert -flatten -density 300 -compress zip psd_dir/"${base}".psd pdf_dir/"${base}".pdf; 
done
```

参考
- [ファイル名からディレクトリや拡張子を取り除くには](https://www.atmarkit.co.jp/flinux/rensai/linuxtips/437delfileext.html)
- [表紙の画像ファイルを PDFファイルに変換 解像度 350dpi](https://comicmall.jp/wiki.cgi?page=ImageMagick#p3)
【学習記録】PHP-FPMとは？

# はじめに
PHPの環境構築する際に、Apacheを使用していたのですがWebサーバーでNginxの使用率が上がっているということで、Nginxを使ってみることにしました。
参考記事：[Nginx系が増加し、Apache減少 - 8月Webサーバシェア](https://news.mynavi.jp/article/20200808-1198182/)

色々調べていくと、Nginxでは***PHP-FPM***というものを使用するらしい。そこでPHP-FPMについて調べてみた。

# PHP-FPMとは？
PHPのFastCGI実装の一つとのこと。FastCGI？？？また初めて聞く単語だ…

FastCGIとは？
> FastCGIとは、Webサーバー上でプログラムを動作させるためのインターフェース仕様の一つ。***CGI***の問題を解決するために開発された。

らしい。

CGIとは？
>CGIとは、Common Gateway Interfaceの略。
Webサーバー上でユーザープログラムを動作させるための仕組み。

CGIを理解する上で、Webサーバーについて確認してみる。
Webサーバープログラムの機能の主体としては、***あらかじめ用意された情報（静的な情報）をクライアントの要求に応じてレスポンスすること***。

→Webサーバープログラム単体では、動的コンテンツを生成してクライアントにレスポンスを返すことはできない。

そこで、Webサーバープログラムからほかのプログラムを呼び出し、その処理結果をクライアントに送信する方法が考案された。
このサーバープログラムと外部プログラムの連携法の取り決めがCGIである。

つまりCGIについてまとめると
> ***Webサーバー上でPHP（動的コンテンツを生成する言語）を動作させるための仕組み。***

FastCGIの説明で触れたように、***CGIには問題点がある***。
CGIはユーザーからの要求があるたびに、プロセスの生成と破棄を行う。そのため、大量の要求があるとその分だけ生成と破棄を行うため、パフォーマンスが悪くなる。

そこで、初回リクエスト時に起動したプロセスをメモリ上へ保持することでパフォーマンスの問題を解決したものがFastCGIである。

# ApacheでPHP-FPMは使っていないような…。
PHPには、モジュール版とCGI版の２種類がある。

Apacheはモジュール版を使用している。
ApacheはPHPをインストールした際に、自動的にPHPモジュールもインストールされる。
モジュール版は、CGI版の逆でWebサーバーのプロセスの中でPHPを実行する方法。
そのため、PHP-FPMを使用していない。

参考サイト：[nginx と PHP-FPM の仕組みをちゃんと理解しながら PHP の実行環境を構築する](https://qiita.com/kotarella1110/items/634f6fafeb33ae0f51dc)
↑こちらの記事大変分かりやすく、かなり参考にさせていただきました。

# モジュール版とCGI版の違い
***モジュール版***
先ほど述べたようにWebサーバーの中でPHPを実行する方法。そのため、Webサーバーを動かすユーザーでPHPが動作するためセキュリティ面で不安。また、Webサーバー内で実行するため処理速度は速い。

***CGI版***
Webサーバーとは別のプロセスで実行される。そのためセキュリティ面で安全。しかし、Webサーバーとは別で処理を行うため処理速度はモジュール版と比べておそくなる。
→この問題はFastCGIを用いることで対策できる。

参考サイト：[PHPのCGI版とモジュール版の違い](https://serverkurabe.com/php-cgi-module/)
過去LGTMした記事の一覧を見る方法

しょっちゅう忘れるので書いておく。以前教えてもらったのに…。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">マイページのプロフィール右上メニューからいけるかと！ <a href="https://t.co/846hXs2v2V">pic.twitter.com/846hXs2v2V</a></p>&mdash; なら (@narazoro) <a href="https://twitter.com/narazoro/status/1273902544113156097?ref_src=twsrc%5Etfw">June 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

マイページから…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25478/4ea7c165-f547-8d75-650c-e2553ca85e1b.png)

ここをクリックして…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25478/e6e7bab6-6197-5bb4-7170-ee2a8a36b5b8.png)

こうじゃ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25478/d6e1eae4-2a19-dac4-a901-e15318271cbc.png)


ストック一覧はワンクリックで到達できるのに…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25478/8f0da62e-c943-6f9a-626b-5ae2755c1a2c.png)

# まとめ

後から読み返すエントリがある場合はストックしたほうがいいです。
VSCodeのリモートエクスプローラー実行時に"プロセスが、存在しないパイプに書き込もうとしました。"と出た。

##状況
VSCodeのリモートエクスプローラーで接続したときに
以下のようなメッセージが表示された

```
> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
> IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
> Someone could be eavesdropping on you right now (man-in-the-middle attack)!     
> It is also possible that a host key has just been changed.
> The fingerprint for the ECDSA key sent by the remote host is
> SHA256:◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
> Please contact your system administrator.
> Add correct host key in C:\\Users\\◆◆◆/.ssh/known_hosts to get rid of this m
> essage.
> Offending ECDSA key in C:\\Users\\◆◆◆/.ssh/known_hosts:1
> ECDSA host key for localhost has changed and you have requested strict checking.
> Host key verification failed.
> プロセスが、存在しないパイプに書き込もうとしました。
```

##原因
既に設定されていたlocalhostへの接続用[SHA256](http://e-words.jp/w/SHA-256.html)の情報が異なっていたため
今まで使っていた仮想環境とは異なる環境を作成して既に使用していたlocalhostへの接続設定をそのまま使用していたのが問題でした。

##対処
logに記載されている
*C:\\Users\\◆◆◆/.ssh/known_hosts*のファイルに記載されている
**localhostの[SHA256]((http://e-words.jp/w/SHA-256.html))**の設定を初期化(削除する)
※ちなみにSHA256とは暗号化ハッシュ関数というものです。

##対処手順
①logに記載されているディレクトリにアクセスする

>C:\\Users\\◆◆◆/.ssh/
![説明画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159061/06afd5b6-b717-929e-d9dc-f0c30b50a6d8.png)


②安牌のためにファイルをコピーする
![説明画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159061/7bf482a8-99e8-fa0f-188c-da3e1cb31fd8.png)

③対象のファイルに登録されている該当接続先の情報を削除する
※サクラエディタで開いています
対象ファイル：known_hosts
該当接続先：localhost
![説明画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159061/997ddb3f-075b-6f67-05ac-c8a90e7311f9.png)
↓削除
![説明画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159061/55a019e8-d1f8-b0b8-363d-473243d87e69.png)

④ファイルをセーブしてVSCodeのリモートエクスプローラーを行う


##まとめ
・VSCodeにリモートエクスプローラーってSHA256使用しているんだなぁ……。
・localhost接続で楽をしなければこんなことにはならなかったが、仮想環境の固定IP設定って結構面倒なので仕方ない。
・chromeのページの表示を日本語にするとログに書かれていることをそのまましているということが判明します(苦笑)
・.ssh/フォルダが何者か気になった人はLinuxで暗号化キーを使用したssh接続などをググると幸せになるかもしれないです(ggrってもう死語かもしれない)
[javascript]カウントダウンタイマーを作成してみた。

## なぜ作ったか？
商品などを扱うサイトとかだとカウントダウンタイマー使ってるサイトがありますが、
実際に作ったことはなかったのでこの機会に作ってみました。

---

## コード

---

### html

---

```html
<div id="log"></div>
```

javascriptでタイマーを出すので表示させるためのdivを用意しておきます。

---

### javascript

---

```js
const totalTime = 10000;
const oldTime = Date.now();

const timeId = setInterval(() => {
  const currentTime = Date.now();

  // 差分を求める
  const diff = currentTime - oldTime;

  const diffSec = totalTime - diff;

  //ミリ秒を整数に変換
  const remainSec = Math.ceil(diffSec / 1000);

  let text = `残り${remainSec}秒`;

  // 0秒以下になったら
  if (diffSec <= 0) {
    clearInterval(timeId);

    // タイマー終了の文言を表示する
    text = "終了";
  }

  // 画面に表示する
  document.querySelector('#log').innerHTML = text;
})
```

---

少し解説するとまず
totalTimeで10秒のミリ秒を設定しています。
oldTimeには読み込まれたときの時間を取得しています。

const diffで読み込まれた時間とsetintervalの中のconst currentTimeで差分を計算し、
const diffSecでtotalTimeからdiffを引いた値を計算しています。

const remainSecでは
Math.ceil関数を使用して引数で与えた数を整数に変換しています。
diffSecはミリ秒単位なので/(割る)1000で秒単位にしています。

diffSecが0秒以下になったらclearIntervalでsetIntervalを止めています。

---

## まとめ

---

こんな感じでカウントダウンタイマーを作成できました。
ただ、これだけだと正直あまり使いどころはないので次回は期日を設けてその期日まで後何日かを表示するような使いどころが多そうなカウントダウンタイマーを作ってみたいと思います。
Input * of layer conv2d_* is incompatible with the layer: expected axis -3 of input shape to have value * but received input with shape [None,*,* ,*]のエラーについて

# エラーについて

Input * of layer conv2d_* is incompatible with the layer: expected axis -3 of input shape to have value * but received input with shape [None, *, *, *]

convレイヤーを使う際にNCHWとNHWCの差によって生まれるエラー。
「*」の値はmodelの設定によって変わる。

# 解決法

https://keras.io/ja/backend/
こちらにあるように.keras直下にあるkeras.jsonをエラーに合うように変更する。

+ NCHWにするならchannels_first
+ NWHCにするならchannels_last

バッチ、チャンネル、高さ、幅の並び順の問題は最初にぶつかる壁な気がします。
JavaScriptの制御構文(2)〜while/do...while命令〜

#はじめに
こんにちは。
今日は、昨日に引き続き、JavaScriptの文法の復習をしておりまして、こちらの方でまとめてみます。今回から複数回、繰り返し処理の構文について復習していきます。

繰り返し処理には、
* **while**
* **do…while**
* for
* for…in
* for…of
などがあります。
その中でも、今回は、while/do…while命令に焦点を当ててみます。

# While命令とdo...while命令
まずは、それぞれの命令の書き方について！
while命令

```
while (条件式) {
	条件式がtrueである間に繰り返す処理
}
```

do...while命令

```
do {
	条件式がtrueである間に繰り返される処理
} while (条件式); 
```
do...while命令において、最後のwhile(条件式)の後にセミコロンをつけるのを忘れない！

whileの位置が違うだけで、同じような処理に見えます。一体、どこが違うのでしょうか。

# while命令とdo...while命令の違い
whileの位置の違いが重要です。
whileの後に続く条件式を「いつ判断するのか」によって、処理結果が変わってきます。

while命令の場合
前置判断。
処理を実行する前に、条件式を判断し、trueであれば、実行する。falseであれば、実行しない。場合によっては、最初からfalseであれば、処理を全く実行しないこともありうる。

do...while命令の場合
後置判断。
最後にwhile(条件式)を配置していることからも、後から、条件式を判断し、falseが出てきたら終わり。falseであろうがなんであろうが、とにかく最低1回は処理を実行する。で、実行してからtrueかfalseか判断する。trueであれば、また処理を継続して、falseであれば、そこでストップする。

# 実際のコードで比較してみましょう！
while命令ver.

```
let x = 8;
while (x < 10) {
	console.log(x);
	x++;
}
// 結果
// 8
// 9
```

do...while命令ver.

```
let x = 8;
do {
	console.log(x);
	x++; 
} while (x < 10); // すでに1加算されたxと条件式を比較する事になる！

// 結果
// 8
// 9
```
後置判断でも、同じ挙動になったのは、do…while命令で、x=9になった時のループ処理で、最後にx++でx=10になり、その直後に条件判断をすると、x=10は、条件式x<10を満たさないからfalseになり、処理が終了するからです。

もし仮に、次のような、コードを実行するとどうなるのでしょうか。
while命令ver.

```
let x = 10;
while (x < 10) {
    console.log(x);
    x++;
}

// 結果
// 何も起こらない
```

do...while命令ver.

```
let x = 10;
do {
    console.log(x);
    x++;
} while (x < 10);

// 結果
// 10
```
上記のように、後置判断である、do…whileは最低でも1度はループ処理を実行するので、xの値が表示されるが、最後に条件式を判定してみると、falseになるので、処理は終了します。

しかし、前置判断である、while命令の場合は、初期値を判断するため、初期値がすでに条件式を満たさない10が来てfalseになったので、処理の実行には至らず、そこで、終了してしまったので、consoleには何も表示されませんでした。

復習していて、
どこで条件が判断されるのかだけに囚われず、どこで何がどう判断されるのか、処理の順番や細部に気を付けることが重要だなと感じました！

個人開発でも、あまり、while/do..while命令を利用することがなかったので、詳しく理解できていませんでしたが、これから何かの機会で利用できたらなと思います！！

理解不足による不備等ございましたら、コメントをお願い致します！

## 参考文献・資料
山田祥寛著『[改訂新版]JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで』(2018)
※第1刷は、2016年。

do...while命令の挙動の理解がきちんとできていなかったので、teratailにて、質問をさせて頂きました。
https://teratail.com/questions/284149
【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする！

# 【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする！

【Node.js 超入門】という参考書を読んで、Node.jsで実装した内容を備忘として書きます。

今回は、データベースを使って画面からユーザ情報を登録、更新などCRUD処理できるアプリケーションを作成します。
メインとしてNode.jsとExpressを使い、サーバサイドの処理を作ります。
データベースはMySQLを使います。



大まかな流れとしては、
・環境構築
・コード実装
・動作確認

続きはこちらの記事にまとめています！
<a href="https://masa-enjoy.com/nodejs-learning1" target="_blank">【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする！</a>
Azure DevOps Tips - Visual Studioで作成済みのソリューションをAzure Reposで管理する

#概要
[前回](https://qiita.com/yossihard/items/b8ee6baa764181234d8a)の続き。
既にあるソリューションを、Azure Reposで管理する手順です。

新規作成したソリューションもこの手順でAzure Reposで管理できるので、
こっちの手順だけ覚えておけばいい気がする・・・。

#やりたかったこと
前にVisual Studioで作ってた（変更管理していない）ソリューションを、
Azure Reposで管理する。

#事前準備
[前回](https://qiita.com/yossihard/items/b8ee6baa764181234d8a)の記事の事前準備を参照。
Azure DevOpsサービスでリポジトリを作っておきます。

#手順
①対象のソリューションをVisual Studioで開きます。
②まずは対象のソリューションをローカルリポジトリに追加します。
　ソリューションエクスプローラタブを開き、ソリューション名を右クリックし、
　メニューから「Create Git Repository...」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/8a646765-977e-5f86-b92a-58933227838c.png)

　このメニュー一つで、ローカルリポジトリが作成されて、
　ソリューションのファイルが全てローカルリポジトリに登録されるようです。

③次にチームエクスプローラタブを開き、同期を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/2f5ac682-aeec-204b-28d8-2aa8f449e412.png)

④以下のような画面が表示されるので、Azure DevOps Serviceへプッシュの中の「Gitリポジトリを公開」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/f1263cfb-effd-e283-886d-ace62eae66c8.png)
　※この段階で公開されるわけじゃないので安心してください。

⑤Microsoftアカウントと、組織、プロジェクト名を選択して、「リポジトリの公開」をクリックします。
　※プロジェクト名は、詳細設定をクリックすると表示されます。
　　なお、プロジェクト名はAzure DevOpsサービス上でのプロジェクト名です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/914c6d79-2d5a-0952-e912-295e1fcb660e.png)

⑥Azure DevOpsサービス側で、ソリューションのファイルが追加されていることが確認できます。

#余談
事前準備でAzure DevOpsサービス側にプロジェクトを作ってから、
手順の⑤でそのプロジェクト名を指定してプッシュしていますが・・・
事前に作らずにプッシュすることも可能でした
※その場合、リポジトリ名がプロジェクト名になってました。
　公開設定はprivate設定になっていたので、ちょっと安心。
機械学習を0から勉強し始めた人のメモ　#2

#Neural Network について
人間の脳の構造から頑張って作った柔軟で自由度の高いモデル
##学習の流れ
- 他のモデルとは異なって**学習回数**(=エポック数)がとても重要となる<br>→モデルが複雑だから
    - エポックはEarly Stoppingによって適度に打ち切る
        - **Early Stopping**<br>n回誤差が下がらなければ（＝精度が上がらなければ）打ち切る手法
    - バッチはデータセットによって決める
        - 基本的に$2^n$で適切なバッチサイズを決定する
        - データセットの件数が数百件であれば32や64を試し，数万件であれば1024や2048を試す．
- **活性化関数**<br>NNの各層において作用させる関数のこと．
    - 高い表現力を実現している．
    - 網羅的に活性化関数を試していくことが良かったりもする
    - 関数一覧は@kuroituさんの[コチラ](https://qiita.com/kuroitu/items/73cd401afd463a78115a#%E3%82%B7%E3%82%B0%E3%83%A2%E3%82%A4%E3%83%89%E9%96%A2%E6%95%B0sigmoid)がとてもわかりやすい
- 各層の重みの初期値について
    - ゼロで始めるのではなくある程度truncated_normal（切断正規分布）などでランダムな値を入れることで学習しやすい傾向がある
- **One-Hot表現**<br>Neural Networkで分類モデルを作る時，0と１で各分類を表現して出力ノードに割り当てるもの
- 損失(誤差）関数
    - 誤差が少なくなるようにするための関数？
    - @mine820さんの[コチラ](https://qiita.com/mine820/items/f8a8c03ef1a7b390e372)がわかりやすいです

---
#三大Neural Networkモデル
- Neural Network
- Convolutional Neural Network
    - @icoxfog417さんの[コチラ](https://qiita.com/icoxfog417/items/5fd55fad152231d706c2)がとてもわかりやすい
- **Recurrent Neural Network**
    - @kiminakaさんの[コチラ](https://qiita.com/kiminaka/items/87afd4a433dc655d8cfd) がとてもわかりやすい
    - 自然言語処理！！！

---
#データセットについて
- 異常値について
    - 人間やセンサーの記録ミスで，ありえない値を測定することがある．
    - 異常値をそのままモデルの作成に用いると質の低いモデルができてしまう．
- 欠損値について
    - 数値以外のデータが存在すると，機会が学習することができない
        - 欠損値が含まれるサンプルそのものを除去する
        - 欠損値の前後の値などの平均で補完（相関がある場合のみ）
- 質的変数のダミーについて
    - 機械学習では基本的に数値のみの値しか用いることができないことから，血液型などの文字の分類に対してダミー数値を用いて置換する必要がある．
- 正規化について
    - データのスケールを合わせる
        - 標準化を行う（平均：０，分散１）
    - クラスタリングやPCAには必須
    - 学習速度の向上が見込める
       
---
#参考
- [Code Base NAGOYA AI Learn UP](https://codebase.proto-g.co.jp/learnup/ai3)

---
この記事は私が勉強用に作っています．
間違いや古い内容で新しいことなどがあれば，ぜひご指摘いただきたいです．
RustでWebAssembly： Canvas2dでBallがたくさん動くアニメーション

# はじめに
[前回](https://qiita.com/mokemokechicken/items/8a5ee72c528639378961) は、Rustに状態を持たせたり、DOMを更新したりしてみました。
今回はなにかアニメーションみたいなのを作ってみようと思います。

Versionなどは前回と同じです。

## 作ったもの

なんとなく四角の中を赤いBallが大量に飛び回るものを作ってみます。

※ (clickでYoutubeに飛びます)
[![Demo](https://img.youtube.com/vi/isp4qD-G110/0.jpg)](https://www.youtube.com/watch?v=isp4qD-G110)

Ballが何個のときにFPSがどのくらいかなぁ、というのがちょっと気になるところです。

# 内容

[ソースコード全体](https://github.com/mokemokechicken/rust_wasm_example/tree/master/example3)

## 困ったこと
アニメーションさせるのに `requestAnimationFrame()` というBrowser側?のAPIを使うことが多いと思いますが、`requestAnimationFrame()` は `setInterval` とかと違って定期的に呼ばれるわけではないので、 `requestAnimationFrame()` の内部でもう一度 `requestAnimationFrame()` を呼ばないといけません。

最初は、Rustの `on_animation_frame()` みたいな method の中で 再び `requestAnimationFrame()` を呼ぶようにしようと思ったのですが、そこで closureを渡すのが尋常じゃなく上手くいかなくて、、、諦めました。(今ならなんとかできるかもしれないが、少し面倒そうなのはかわらない)。したがって、JS側でそのループを作って毎回 Rustの`on_animation_frame()` を call してもらうようにしました。まあ、こういうのも無くはないかな、と。

それ以外は、素直なRustプログラムになって、かなりコンパイラに怒られながらも動くものが作れました。

## コード
### Cargo.toml

- `rand = { version="0.7.3", features =["wasm-bindgen"] }` が追加。
    - このfeaturesを指定しないと、WASM内でrandが使えないようなので注意が必要
- web-sys feature: `CanvasRenderingContext2d`
    - Context2d使うので必要

### index.html
ちょっと妥協の産物ですが、これで毎回AnimationのFrameを更新するようにしています。

```javascript:type="module"
  import init, * as wasm from './pkg/rust_wasm_example.js';
  async function run() {
    await init();
    const myApp = wasm.MyApp.new({canvas_id: "canvas", initial_n_balls: 1000});
    myApp.init();
    function onAnimationFrame(t) {
      const ret = myApp.on_animation_frame(t);
      if (ret) {
        requestAnimationFrame(onAnimationFrame);
      }
    }
    requestAnimationFrame(onAnimationFrame);
  }
  run();
```

### 他
Animationをさせるためにコードは色々書きましたが特筆するようなところはないかな。
ちょっと工夫したのは、Ballに動きの尾ひれ(残像?残影?軌跡?)をつけるために、過去数フレームの位置を保存させて描画しているところかな。全体を保存(コピー)させているけど、Ball毎にVecとかで履歴を持たせたほうが良かったかな。そうすると、１本の線とかにもしやすかっただろうし。

まあ、ちょっと固まったRustのコードを書くいい練習にはなりました。

ちなみに今回requestAnimationFrame() を使うと、1frameあたりの処理が十分早ければちょうどFPS=60になるようでした。遅くなると60を切っていきます。

「衝突」「引力 or 斥力」を全Ball間でしているので、Ballの数が増えると計算量が結構あがっていきます。私のPCだと4~500個くらいで FPSが60を切ってしまうかな、という感じでした。
上記の計算をしない場合は、だいたいCanvasへの描画処理ばかりになるのでもうちょっとBallが多くてもFPS６０が維持されます。

# さいごに

なんか、仕様&動作確認的な実験的なものばかりだと飽きるので作ってみた他愛のないものですが、せっかくなので書き残しておきました。
[UE4] 列挙型の値から表示名を取得するノードの挙動がエディタとパッケージで違うことがある

# はじめに
* 検証環境 は UE4.25.3 です。

# 列挙型の値から表示名を取得するノードとは…？

これのことです。
![SnapCrab_NoName_2020-8-11_23-37-36_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43814/371c31d1-67e0-ba5b-ef57-5f3ecd01d9bb.png)
例えば、以下のような列挙型の定義があったとします。

```:c++
UENUM(BlueprintType)
enum class EEnumToStringElements : uint8
{
	Element_0 UMETA(DisplayName = "要素1"),
	Element_1 UMETA(DisplayName = "要素2"),
};
```

この場合、「要素1」「要素2」が表示名となります。
もし、以下のようにメタデータで「DisplayName」を指定していない場合…

```:c++
UENUM(BlueprintType)
enum class EEnumToStringElements2 : uint8
{
	Element_0,
	Element_1,
};
```

この場合は、「Element 1」「Element 2」が表示名となります。
（「アンダーバー」が「半角スペース」 に置き換えられるため。）

ちなみに、これを PrintString で表示するとこのようになります。
![SnapCrab_NoName_2020-8-11_23-47-4_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43814/54d05353-f6eb-f656-9e87-fc83374aaaa5.png)

# これをパッケージで見てみると…？

一見すると何も問題がないように見えますが、これをパッケージで見るとどうでしょうか？

実は、こうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43814/72b0e66e-8f92-8f5d-7dca-9f3b8dd8a6eb.png)

見ての通り、両方ともシンボル名になってました。
なので、必ず表示名が返されると思って処理を組んでいると、パッケージ化したときに痛い目を見ることになるので、気をつける必要があります。

# BP で列挙型を定義してみると…？

ただし、これは列挙型が C++ で定義されている場合です。BP で定義された列挙型の場合はまた挙動が違います。

試しに以下のような列挙型を BP で作ってみました。
![SnapCrab_EEnumToStringElements_BP_2020-8-12_0-5-9_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43814/c52fb8f9-8f1a-b8a9-7723-7bfdd1273715.png)
これを PrintString で表示してみてどうなったかというと、こうなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43814/ef50be8e-c8f0-9a36-6b0b-34cc19d80784.png)
この通り、こちらの場合はパッケージでも問題なく表示名が取得できていました。

# このノードを使いたくなるときは…？
以下のような状況が想定されます。

* デバッグ表示で列挙型の名前を表示したい。
* シンボル名を使いたい。

前者に関しては、DisplayName 未使用で、かつ、シンボル名さえわかればいい場合であれば、このノードを使って表示名を取得してもそれほど問題がないように思えます。
逆に DisplayName を使ってる、もしくは DisplayName で指定した別の文字列を使いたい場合は DisplyaName の文字列を使わず、別途用意した文字列を使う仕組みを用意したほうが無難に思えます。

後者に関しては、UEnum::GetNameStringByValue を使った関数やこれを用いた K2_Node を用意することで対応することができそうですが、重たい話になりそうなので別途検証が必要そうです。
VMサーバーをコンテナに移行する計画

これは**そろそろDockerを使えるようになりたい**筆者の試行錯誤の軌跡です。

# VMからコンテナへ
現在、完全に自分だけのためではありますが、複数サービス運用のためローカルマシンのVMで作ったサーバー3台を運用しています。

![Untitled(1) (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/3cace4d9-3e1d-0cec-08ae-044dbcfdfa7e.png)

* *Deploy*：コンテンツ配信用
* *Resource*：プライベートクラウドストレージ
* *Develop*：ソースコード管理

*Deploy*で配信するコンテンツには以下の種類があります。

* 通常通り`/var/www/html`配下にファイルを配置し配信するもの(以下、web root)
* 音楽や動画を配信するメディアストリーミング
* Djangoアプリケーション
* Node.jsアプリケーション

それらのうち、DjangoアプリケーションとNode.jsアプリケーションはバーチャルホストとしてサブドメインを割り当てています。
上記アプリケーションに加えて、*Resource*のowncloud、*Develop*のgitlabも、バーチャルホストとしてサブドメインで*Deploy*から配信しています。

これらをDockerに移植していこうという計画を立てます。
理由は単純で、**そろそろDockerを使えるようになりたい**からです。
探り探りではありますが、少しずつ進めていきたいので、その軌跡を残そうという記事です。

以下のような完成形をイメージしています。
(コンテナ初心者です。構成の甘さとかベストプラクティスとかあればご教示ください。)

![Untitled(2) (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/6d6e7a2b-40fc-3024-a61a-cc90fd4a899e.png)

よくある「プロセス単位でコンテナを作成」っていう説明がなかなか理解できなかったのですが、
具体的にどう切り分ければコンテナとして扱いやすいかを考えると、すんなり理解できました。

# とりあえずDockerを準備
一気にやってしまう時間を確保するのが難しいので、少しずつ進められるようにとりあえずDockerを使えるようにし、VMと共存させます。
Docker起動に必要なHyper-VとVirtualBoxが共存できない問題がありましたが、VirtualBoxを6.1系にアップデートすると共存できました。
以下のような構成が当面の目標です。

![Untitled(3) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227222/8ad9e6ae-c7c3-6f5e-83e0-185d389dca6f.png)

画像のようにnginxのコンテナを起動し、VMにリバースプロキシするよう設定し、http系のアクセスがVMからコンテナに向くよう変更しました。
が、つながりませんでした。
ブラウザには`ERR_SSL_PROTOCOL_ERROR`と表示されており、コンテナのnginxは文字化けしていて解読できませんでした。

移行計画、不穏な幕開けです。

次回：[DockerでVMへのリバースプロキシ](https://qiita.com/F_clef/items/e0bbf371398772edc1f7)
LDAPとは

#LDAP(Lightweight Directory Access Protocol)とは
## この記事の趣旨
LDAPを初めて聞いた筆者が備忘録のため語句の意味についてざっくりと備忘録として書く。
大まかな説明のため間違っている点、厳密には違う点があると思われる。
## ざっくりとした説明
複数のパソコンのユーザー名、IDを共有、統一するための機構

## どのような場面で使うのか
筆者のいる研究室ではNAS（Network Attached Storage）を実現するために、ファイルの所有者、ファイルグループ等を複数のパソコンで統一する必要が出てきた。

## LDAP導入後のざっくりとした仕組みの説明
あるパソコンがLDAPを入れて、他のパソコンはLDAPクライアントを入れる。
ログイン時にLDAPクライアントはLDAPが入っているサーバにID passwordを問い合わせてログインする。
IBM Cloud Internet Servicesを使ってサイト全体にベーシック認証をかける

# 目的

IBM Cloud Internet Services（CIS）は、Cloudflareを利用したCDNやWAF機能を提供するサービスです。そのEnterpriseプラン（Enterprise Usage、Enterprise Packageなど）では、Edge Functionsという機能を使って、スクリプト処理をリクエストの前後に挟むことができます。

> Edge FunctionsはCloudflareではCloudflare Workersと呼ばれる機能です

さて、公開サイトを非公開にするためにベーシック認証を使いたい場合があると思いますが、このときにWebサーバで1つ1つ設定するのは手間です。今回はCISのEdge Functionsを使ってBasic認証をかけてみます。

# 検証

## 前提

* CISの無料トライアル以外の有料プランがオーダー済であること
* 対象となるWebサーバへのGLBは設定済であること

## パスワードの生成

Basic認証のパスワードは``ID:パスワード``をBase64エンコードしたものです。今回はIDを``user1``、パスワードを``hogehoge``とし、次のようにBase64エンコード文字列を生成します。

```
$ echo -n "user1:hogehoge" | base64
dXNlcjE6aG9nZWhvZ2U=
```

## アクションの登録

コンソールから作成を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/2d9c2a93-6fc9-0d32-7a1c-9dcfc6d684d3.png)

次のようなコードを設定します。``Basic ～``のところは先ほど生成したBase64エンコード文字列にします。

```
addEventListener('fetch', event => {
    event.respondWith(fetchAndApply(event.request));
});

async function fetchAndApply(request) {
    if (request.headers.get('authorization') != 'Basic dXNlcjE6aG9nZWhvZ2U=') {
        response = new Response('', { status: 401, statusText: 'Unauthorized' });
        response.headers.set('WWW-Authenticate', 'Basic realm="Authentication Required"');
        return response;
    }
    
    return fetch(request);
}
```

これにbasic-authという名前をつけて保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/acd7755e-3636-9f17-0cde-23752d197ddf.png)

次にこれを適用するURLを指定します。トリガータブからトリガーの追加を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/2c2aeb4c-93fe-1611-8df8-45f2d4a925f4.png)

トリガーURLはサイト全体ならFQDNでよいです。アクションにbasic-authを選択し保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/558e631d-8dcf-b740-65db-0133306a8755.png)

## 動作確認

ブラウザでサイトにアクセスします。ベーシック認証のダイアログが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241424/2db1b0ef-8e8c-b802-8b5a-4332e59c7849.png)

これで、先ほど指定したIDとパスワードでログインできることを確認してください。

以上