OmniAICreator/Qiita-1.07M huggingface dataset:
WSL2 の Docker から Bind によるデータ永続化を行う場合のフォルダ指定

# 結論
WSL2 上のDockerコンテナでBind(バインド)させる場合、Windows上のフォルダをwsl形式のパスで指定すること

# 課題
WSL2 上のDockerコンテナ起動にて「--mount type=bind」でBind先を指定してコンテナを起動するが、
期待したフォルダをマウントしていない。コンテナは起動しているがBind先のフォルダが見えない。

# 実行方法
## BindするWindows環境

Windows上にBind先フォルダを作成する。
中にはhello1.txtを作成する。
 
```bat:BindさせるWindowsのパス
C:\dockerBind
  hello1.txt
```

wslコンソール上からwslpathコマンドで、wslが読み込める形式のパスが取れる。
/mnt/c配下にディレクトリは作成されます。
注意：ダブルクォーテーション忘れると失敗します


```bash:wslpathによるパスの読み替え
$ wslpath "C:\dockerBind"
/mnt/c/dockerBind
```

## Bind付きコンテナを実行

--mountをつけてsourceに`wslpath "C:\dockerBind"`を指定する。
バッククォートで囲むことで、バッククォート内の処理結果がコマンドに投入されます。

```bash:Bind指定をつけてコンテナを起動
$ docker container run --rm -d --name bct --mount type=bind,source=`wslpath "C:\do
ckerBind"`,target=/bindcont alpine:3.10.3 tail -f /dev/null
77d1027748fb32017fafc4ac8d41832ead720f48451f4af01f972eb5cc4c347a
```

## 動作検証

lsでbindされていることを確認

```bash:Bindされて、hello1.txtがコンテナから表示できることを確認
$ docker container exec bct ls -l /bindcont
total 0
-rwxrwxrwx    1 1000     1000             0 Sep 23 06:58 hello1.txt
```
touchでファイル生成ができることを確認

```
$ docker container exec bct touch /bindcont/hello2.txt
$ docker container exec bct ls -l /bindcont
total 0
-rwxrwxrwx    1 1000     1000             0 Sep 23 06:58 hello1.txt
-rwxrwxrwx    1 1000     1000             0 Sep 23 07:35 hello2.txt
```
docker container inspect で設定内容を確認

```
$ docker container inspect bct
[
  【前略】
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/mnt/c/dockerBind",
                "Destination": "/bindcont",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
  【後略】
]

```
# 理由

問題の理由はわかりません。

WSL上のDockerデーモンがWSL上のファイルを見ることができないのは、腑に落ちない。
コンテナとしてはネットワーク越しのmountをしているようなものなので、成功しそうに思うのだけど。

# 参考
https://qiita.com/gentaro/items/7dec88e663f59b472de6
AtCoderログ：0121 - 日立製作所 社会システム事業部 プログラミングコンテスト2020 B

# 問題

https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_b

## 問題文
> あなたは、冷蔵庫と電子レンジを買うために、とある家電量販店に来ました。
> この家電量販店では、 $A$ 種類の冷蔵庫と $B$ 種類の電子レンジが販売されています。$i$ 番目 $(1 \le i \le A)$ の冷蔵庫の値段は $a_i$円であり、$j$ 番目 $( 
 1 \le j \le B)$ の電子レンジの値段は $b_j$ 円です。
> また、あなたは $M$ 種類の割引券を所持しており、$i$ 番目 $(1 \le i \le M)$ の割引券では、$x_i$ 番目の冷蔵庫と $y_i$ 番目の電子レンジを同時に買うと、 支払総額が $c_i$ 円安くなります。ただし、複数の割引券を同時に使うことはできません。
> さて、あなたは冷蔵庫と電子レンジをちょうど $1$ 台ずつ買おうと思っています。かかる金額の最小値を求めてください。

## 制約
> ・入力は全て整数
> ・$1 \le A \le 10^5$ 
> ・$1 \le B \le 10^5$
> ・$1 \le M \le 10^5$
> ・$1 \le a_i,b_i,c_i \le 10^5$ 
> ・$1 \le x_i \le A$
> ・$1 \le y_i \le B$
> ・$c_i \le a_{x_i} + b_{y_i}$

## 収録されている問題セット
- [AtCoder Problems Boot camp for beginners Easy 100](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) [#024]

# 回答
## 回答1 (AC)
単純に考えると $A$ 種類の冷蔵庫と $B$ 種類の電子レンジの全ての組み合わせを調べたくなります。しかし、組み合わせは $AB \le 10^{10}$ 通りあるため、全てを調べると TLE になってしまいます。

割引券を使用しない場合、冷蔵庫と電子レンジも最も安い組み合わせは、最安値の冷蔵庫と最安値の冷蔵庫を買った場合です。このため、割引券を使用しない場合については、これ以外の組み合わせは必要ありません。

次に割引券を使用する場合、割引券は $M < 10^5$ 種類なので、それぞれの割引券を使った場合の合計金額を求めることが可能です。そこでそれぞれの合計金額を求めながら、最小値を調べていけば良いでしょう。コードは以下のようになりました。

```C++:hitachi2020b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int A, B, M;
  cin >> A >> B >> M;

  int amin = INT_MAX;
  vector<int> a(A);
  for ( int i=0; i<A; i++ ) {
    cin >> a.at(i);
    amin = min( amin, a.at(i) );
  }
  
  int bmin = INT_MAX;
  vector<int> b(B);
  for ( int j=0; j<B; j++ ) {
    cin >> b.at(j);
    bmin = min( bmin, b.at(j) );
  }

  int pmin = amin+bmin;
  int x, y, c;
  for ( int i=0; i<M; i++ ) {
    cin >> x >> y >> c;
    pmin = min( pmin, a.at(x-1)+b.at(y-1)-c );
  }

  cout << pmin << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/hitachi2020/tasks/hitachi2020_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/hitachi2020/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0120 - ABC 092 B](https://qiita.com/RoadLynton/items/60e3247a475e0f1a6c93)
[C#]System.Text.Jsonを使用してJSONを扱う

## System.Text.Jsonを使用するのに必要なもの

### .NET Core3.0以降を使っている場合
.NET Core3.0以降ではデフォルトで入っているので特に何も必要はありません。

### .NET Core3.0よりも古いフレームワークを使っている場合
NuGetを使用してSystem.Text.Jsonを導入する必要があります。
https://www.nuget.org/packages/System.Text.Json

## 基本的な使い方

シリアライズ・デシリアライズするクラスを作成します。

```Program.cs
class JSONSample
{
    public string ID { get; set; }
    public string Name { get; set; }
}
```
### シリアライズ(オブジェクトからJSON文字列を作成)

JsonSerializerのSerializeメソッドを使用してシリアライズすることができます。

```Program.cs
private void Serialize()
{
    var sample = new JSONSample() { ID = "001", Name = "Chikuwa" };
    string jsonString = JsonSerializer.Serialize(sample);
}
```

クラスを用意せずともDictionary型のオブジェクトもシリアライズすることができます。

```Program.cs
private void Serialize()
{
    Dictionary<string, string> dic = new Dictionary<string, string>();
    dic.Add("ID", "001");
    dic.Add("Name", "Chikuwa");
    string jsonString = JsonSerializer.Serialize(dic);
}
```
結果

```
{"ID":"001","Name":"Chikuwa"}
```

### デシリアライズ(JSON文字列からオブジェクトを生成)

JsonSerializerのDeserializeメソッドを使用してデシリアライズします。
Deserializeメソッドのジェネリックパラメータにオブジェクトのクラス名を指定します。

```Program.cs
private void Deserialize()
{
    //とりあえずstring変数にJSON文字列を・・・
    string json = "{\"ID\":\"001\",\"Name\":\"Chikuwa\"}";
    var sample = JsonSerializer.Deserialize<JSONSample>(json);
}
```

## シリアライズ処理についての補足
* シリアライズに使用する各クラスのプロパティはstring型,int型,DateTime型等でもシリアライズされます。

```Program.cs
class JSONSample
{
    public string ID { get; set; }
    public string Name { get; set; }
    public DateTime Birthday { get; set; }
    public int Age { get; set; }
}
```

```Program.cs
private void Serialize()
{
    var sample = new JSONSample() { ID="001", Name="Chikuwa", Birthday=DateTime.Now, Age=30 };
    string jsonString = JsonSerializer.Serialize(sample);
}
```
結果

```
{"ID":"001","Name":"Chikuwa","Birthday":"2021-09-23T16:28:31.4331997+09:00","Age":30}
```

* シリアライズされるフィールドは、publicなGetプロパティのみのようです。

```Program.cs
class JSONSample
{
    //publicなget,setプロパティ
    public string ID { get; set; }
    //publicなget,setプロパティ
    public string LastName { get; set; }
    //publicなフィールド
    public string FirstName;
    //privateなフィールド
    private string Age = "30";
    private string dept;
    //publicなsetプロパティ
    public string Dept
    {
        set { this.dept = value; }
    }
}
```

```Program.cs
private void Serialize()
{
    var sample = new JSONSample() { ID="001", LastName="Chikuwa", FirstName="Gohan", Dept="TestDept" };
    string jsonString = JsonSerializer.Serialize(sample);
}
```

結果

```
{"ID":"001","LastName":"Chikuwa"}
```
「ID」と「LastName」のみがJSON文字列に出力されます。

# 参考にした資料
https://docs.microsoft.com/ja-jp/dotnet/standard/serialization/system-text-json-overview?pivots=dotnet-5-0

https://docs.microsoft.com/ja-jp/dotnet/api/system.text.json?view=net-5.0
Google Fontsで書体を変える方法

#はじめに#
　文字の書体を変更する方法です。意外と書体が違うだけでアプリの印象が変わったりします。
色々方法はあるみたいですが、今回はGoogle Fontsを使って書体を変えていこうと思います。

#Google Fonts#
　まずは[GoogleFonts](https://fonts.google.com/)で検索します。無料で使うことができるのでありがたいです。
日本語のフォントを探している場合は、上部にあるLanguageのプルダウンメニューからJapaneseを選んでください。

![スクリーンショット 2021-09-23 16.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/89328b4a-3c00-3bee-fe01-12e2eb82f279.png)

　次に、使用したい書体をクリックしてそのページに飛びます。

![スクリーンショット 2021-09-23 16.37.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/13d106a8-1926-cf30-027f-fe14cc1264fb.png)

次に、書体の右部にある+ Select this styleをクリックしてください。
するとこのように右側にSelected familyというメニューが現れます。

![スクリーンショット 2021-09-23 16.39.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/1fb5f12d-65c6-8835-2ff6-0286fcd875d4.png)

Selected familyの真ん中あたりにHTMLへのlinkの記述とcssの要素が記述されています。
これをコピペしてそれぞれ貼り付けましょう。

```sample.html
<!DOCTYPE html>
<html lang="ja">
   <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <link rel="stylesheet" href="style.css">
       <link rel="preconnect" href="https://fonts.googleapis.com">
       <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
       <link href="https://fonts.googleapis.com/css2?family=Bonheur+Royale&display=swap" rel="stylesheet">

       <title>Document</title>
   </head>
   <body>
       <h1 class="title">GoogleFonts</h1>
   </body>
</html>
```

```style.css
.title{
    font-family: 'Bonheur Royale', cursive;
}
```

これでフォントを変えることができました！簡単ですね！

![スクリーンショット 2021-09-23 16.47.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1558223/c6c60180-329f-5b79-e4ce-e1dd58165344.png)
EC2 (Amazon Linux 2) で CloudWatch エージェントを使用して CloudWatch Logs にログ出力するまで

#やりたいこと

Session Manager 経由で、CloudWactch Agent をインストールして、messages を CloudWatch Logs に出力する


# 環境

・パブリックサブネットの Amazon Linux 2

# Session Manager からのアクセス許可設定
以下の通り、AWS 管理ポリシー [AmazonSSMManagedInstanceCore] を EC2 に付与する。
[AmazonEC2RoleforSSM] は非推奨になったみたい。

ステップ 2: Session Manager のアクセス許可を持つ IAM インスタンスプロファイルを確認または作成する
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started-instance-profile.html


# CloudWactch Agent のインストール
以下を参考に AWS Systems Manager の Run Command でコマンドドキュメント[AWS-ConfigureAWSPackage] を実行。
「Name」は [AmazonCloudWatchAgent] を指定すること。

パッケージの 1 回インストールまたは更新 (コンソール)
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/distributor-working-with-packages-deploy.html#distributor-deploy-pkg-console

# ポリシーの付与
以下の通り、AWS 管理ポリシー [CloudWatchAgentServerPolicy] を EC2 に付与する。
[AmazonSSMManagedInstanceCore] のみだと CloudWatch Logs にログ出力されない。

Amazon EC2 インスタンスの CloudWatch エージェントで使用する IAM ロールを作成する
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-iam-roles-for-cloudwatch-agent.html#create-iam-roles-for-cloudwatch-agent-roles


# CloudWactch Agent の設定

AWS Systems Manager のパラメータストアに以下のようなパラメータを登録。

```shell-session
{
    "logs": {
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/var/log/messages",
                        "log_group_name": "/var/log/messages",
                        "log_stream_name": "{instance_id}"
                    }
                ]
            }
        }
    }
}
```
上記の設定ファイルの詳細は以下を参照。

CloudWatch エージェント設定ファイルを手動で作成または編集する
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html


続いて AWS Systems Manager の Run Command でコマンドドキュメント[AmazonCloudWatch-ManageAgent] を実行。
「Optional Configuration Location」は上記のパラメータ名を指定すること。

以上で、messages が CloudWatch Logs の以下に出力される。



| パラメータ | 値 |
|:------------:|:------------:|
| ロググループ       | /var/log/messages |
| ログストリーム     |      インスタンスID |




出力先を変更する場合は上記の log_group_name と log_stream_name を変更すること。


# 参考資料
AmazonCloudWatch-ManageAgentドキュメントでCloudWatchエージェントを設定する際の挙動を確認した
https://dev.classmethod.jp/articles/amazoncloudwatch-manageagent-ssm-run-command/
[Android] お寿司屋で例えるAndroid Architecture Compoment ：Repository

# この記事は
前貫までで最終貫を迎えましたが、わたくしの技術力が至らずで上手く実装できていなかったので、続貫になります。
恐らく、永続的に続貫すると思いますｗ

https://qiita.com/LaO/items/45eb7b640fa81814246b

# 変更点
今までは、View層の事をお客さんと比喩していましたが、データの出力の責務があるという点でいまいちしっくりこないというフィードバックを頂きました。

確かになぁと思ったので、これからはView層は「お客さん」ではなく「カウンター」として例えていきます。
RemoteDataSource（海）から取得したデータ（魚）を最終的にViewModel（板前）で加工してView（カウンター）に提供するといった感じです。

# Repository編
前回は、RepositoryをDaoの事としていました。
今回は、しっかりとRepositoryクラスを作成して定義したいと思います。

とはいえ、Repositoryクラスはそんなに新しい知識は要らないです。
APIを叩いたり、データを保存したり、削除したりするメソッドをView層（カウンター）でもなく、ViewModel（板前）でもなく、Repository（漁師）で定義します。

### コードで
こちらで、定義して、、

```kotlin:SushiRepository
class SushiRepository @Inject constructor(
     private val sushiDao: SushiDao
) {
     suspend fun saveSushiData(sushi: Sushi) = withContext(Dispathcers.IO) {
          sushiDao.insertSushi(sushi)
     }

     suspend fun getAllSushiData() = withContext(Dispathers.IO) {
          sushiDao.getAll()
     }
}
```

こんな感じで呼び出します！

```kotlin:OrderViewModel
@HiltViewModel
class OrderViewModel: ViewModel @Inject constructor(
     private val sushiRepository: SushiRepository
)
     // 省略

    fun hoge() { 
         ViewModelScope.launch {
               sushiRepository.saveSushiData(
                    Sushi(
                         0,
                         _tunaCount.value,
                         calc(_tunaCount)
                    )
          }
     }


```

### Repositoryについて
Repositoryは、お寿司屋の中で漁師の役割があります。
APIデータを魚とした時に、それを取得し、保存したり、削除したりする役割です。

Repositoryで定義したメソッドの返り値が、withContextとなっていましたがこれはメインセーフティを実現するものです。メインセーフティとは、ここではこの関数をバックグラウンドで処理させて、UIの操作を止めないようにするものです。

つまり、コルーチンの実行をIOスレッドに移動させることで、UIの操作を止めることなく非同期処理をすることが出来ます。

# 終わりに
間違っていたら、ご指摘お願いします！
Factory Method (継承)の採用可否基準 


|関連記事のトップページ|
|:--|
|[[シリーズ] Python におけるデザインパターンの記録](https://qiita.com/robozushi10/items/3c1c0d1b1fbf7b38a33b)|

## 概要

基底クラスを継承をした構造 (Factory Method) の「採用可否の基準」と「実装例」.
引用元は下記書籍である.

ただし、内容について細かく記すと書籍の無断転載になるので大まかに記している.
また、コードは Ruby から Python に書き換えている.

|引用元情報|一言|
|:--|:--|
|[書籍 -- Rubyによるデザインパターン (Russ Olsen 著)](https://www.amazon.co.jp/Ruby%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Russ-Olsen/dp/4894712857)|[原書(英文)](https://www.amazon.com/gp/product/0321490452/ref=as_li_ss_tl?ie=UTF8&tag=eloqruby-20&linkCode=as2&camp=217145&creative=399349&creativeASIN=0321490452)|
|[GitHub -- 著者 Russ Olsen 氏](https://github.com/russolsen/design_patterns_in_ruby_code/tree/master/01)||


## 採用の基準

ここは独断もしくは私の解釈です.

採用基準は次を満すこと.
・**基底クラスの仕様が確定している状態にあること**

言い換えると次である.
・**具象クラスのために基底クラスを変更しない状態にあること**

上記が満せない場合は、Strategy Pattern を検討している.


## コード例

### ファイル構成

```bash
.
|-- ex3_vehicle.py
|-- ex4_car.py
`-- ex4_car_test.py
```

### クラス図

Vehicle を基底クラスとして採用する場合、
具象クラスは必ず次の 3つを持つことが条件となる.

・重量 (weight)
・エンジン稼働 (start_engine)
・エンジン停止 (stop_engine)

つまり、自転車、馬車などエンジンを持たない乗り物を具象クラスとしてはいけない、
ということである.

(逆に、自転車や馬車などエンジンを持たない乗り物に対応する確率があるなら、
[Strategy Pattern](https://qiita.com/robozushi10/items/a5fbc9dc9a6e5ba98ed3) を使わないといけない)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/cd104ef2-3680-6241-2f33-2a99a915d252.png)



### ./ex3_vehicle.py

基底クラス

```python
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

class Vehicle(object):
  def __init__(self, weight):
    self.weight = weight   #! 重さ
    print(f'This car weighs {self.weight}kg')

  def start_engine(self):  #! エンジン稼働
    print('start the engine')

  def stop_engine(self):   #! エンジン停止
    print('stop the engine')

```

### ./ex4_car.py

具象クラス

```python
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from ex3_vehicle import *

class Car(Vehicle):
  def sunday_drive(self):
    self.start_engine()
    self.stop_engine()

```

### ./ex4_car_test.py

テストドライバ

```python
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import unittest
from ex4_car import *

class CarTest(unittest.TestCase):
  def test_car(self):
    c = Car(weight=650)
    c.start_engine()
    c.stop_engine()
    c.sunday_driver()
```


## 実行例

```bash
$ python -m unittest ex4_car_test.py
This car weighs 650kg
start the engine
stop the engine
start the engine
stop the engine
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK
```
Mac+pyenvでバージョンがうまく切り替わらなくなった時の対処法

# 起こった現象
Mac(Big Sur)でpyenvを利用していたのですが、バージョン切り替えがうまくできなくなってしまいました。
具体的には以下のような挙動です。
OSのアップデートか、pyenvの再インストールか、どちらかが原因ではないかと思います。

```
$ pyenv global 3.8.5

# 3.8.5に切り替わっていることを確認
$ pyenv versions
  system
* 3.8.5 (set by /Users/【ユーザー名】/.pyenv/version)

# なぜか切り替わっていない
$ python -V
Python 2.7.16

# pythonのpathもpyenvの場所ではない
$ which python
/usr/bin/python
```

# 対処法
~/.zshrcと~/.zprofileに下記を追加することで解決しました。

###  ~/.zshrc
```
eval "$(pyenv init -)"
```

### ~/.zprofile
```
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
```
WordPress子テーマ作成

[子テーマディレクトリ作成](#子テーマディレクトリ作成)
[style.css作成](#style.css作成)
[functions.php作成](#functions.php作成)
[子テーマ有効化](#子テーマ有効化)
[参考記事](#参考記事)

# 子テーマディレクトリ作成

```
# mkdir /var/www/html/example.com/wp/wp-content/themes/example-child
```
# style.css作成

```:#&nbsp;vim&nbsp;/var/www/html/example.com/wp/wp-content/themes/example-child/style.css
/*
 Theme Name:   example-child
 Theme URI:    http://example.com/example-child/
 Description:  example-child Theme
 Author:       hoge
 Author URI:   http://example.com
 Template:     ＜親テーマ名＞
 Version:      1.0.0
 License:      GNU General Public License v2 or later
 License URI:  http://www.gnu.org/licenses/gpl-2.0.html
 Tags:         light, dark, two-columns, right-sidebar, responsive-layout, accessibility-ready
 Text Domain:  example-child
*/
```

# functions.php作成

```:#&nbsp;vim&nbsp;/var/www/html/example.com/wp/wp-content/themes/example-child/functions.php
<?php
add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {
  wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' );
  wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array('parent-style')
);
}
?>
```

# 子テーマ有効化

WordPressダッシュボード　＞　外観　＞　テーマ
`example-child`というテーマがあれば`有効化`

***
# 参考記事
`https://www.webcreatorbox.com/tech/wordpress-child-theme`
基本情報技術者試験合格までの道のり〜　ご挨拶と勉強の仕方を話す

はじめまして。
基本情報技術者試験合格に向けて、日々のアウトプット日記を始めてみました。
同じく試験合格を目指してる方、共に頑張っていけたらなと思います。

今回受ける試験自体は11月の下旬（午前も午後も）。
今回は初めての受験ということで、目標はとりあえず**午前試験合格**です。

現在2021年の9月23日なので、試験まで約2ヶ月という短さですが頑張ります。


将来、この記事（シリーズ）を読んで試験合格を目指す方が現れたときに僕がどのようにして
勉強していったのかを知れる手がかりになれば幸いです。

##基本情報技術者試験とは
まずは試験について。

「基本情報技術者試験」とは、経済産業大臣が行う国家試験である**「情報処理技術者試験」の区分の1つ**。
“IT業界の登竜門”とよく言われる、立派な**国家資格**です。

IT業界に携わりたい人がまず取得すべき資格です。
##取り組み方　知識問題
僕が実践しているのが、**「問題を読んだらすぐ答えを見る」**という勉強法です。

試験勉強の目的って、試験に合格することですよね。

問題を見て、悩んで、悩んで、悩んでもわからない。だから答えを見て納得する。
実はこれ、**かなり時間の無駄です。**

基本情報技術者試験は知識量が合否を決める試験なので、わからない知らない、そう思ったら
すぐ答えを見てインプットすべきです。

「エビングハウスの忘却線」って聞いたことありますか？
詳しくは下記を参照してもらいたいのですが、

https://ryugaku-kuchikomi.com/blog/ebbinghaus-the-forgetting-curve/

覚えたことって、その日はよく覚えていると思います。
しかしその翌日、翌々日となると7割近くは忘れてしまっているんですよね。

何が言いたいのかというと、基本情報技術者試験の勉強って、**スピード・カバー量が大事**なんです。

知識問題だけでも、覚えなくてはならないものがたくさんあります。なので、正直問題を読んで考えている
暇ってないと思うんですよね。

だから答えはすぐ見て、どんどん知識を入れていく。

さきほど「エビングハウスの忘却線」について話題にしました。
この試験は知識量勝負なので、「たくさんインプットすることが大事」と話しましたが、問題集を一周しただけでは
知識の土台は不安定です。

最低でも3周はしないと、せっかく頭に詰め込んだ知識も本番で思い出せないでしょう。というのも、一周しただけでは
知識は詰め込めてもまだ「理解」はできていないので、2周3周目は理解に努めるよう勉強するのが鉄則です。

##取り組み方　計算問題
計算問題をマスターするのには時間がかかります。
あと、冊子型の問題集を使って勉強するのなら、問題集は印刷物なので（印刷された数字は変えられないため）
一度答えを見てしまうと次回以降はあまり練習になりません。

計算方法や解き方を理解するためには、いろんな数字でトライする必要があります。

ネットに問題は大量にあるので、類似問題は解き方が自分の中にしっかり定着されるまでどんどん解きまくりましょう。

基本情報技術者試験を受ける方がみんな使っているこちらのサイトで力を伸ばしていってください。

https://www.fe-siken.com/fekakomon.php


##最後に
Qiitaで初の投稿となりましたが、少しでも参考になればなと思います。
これから自分が学習した知識のアウトプット記事を更新するので、気になる方はそちらもご覧ください。

:::note info
Twitter、ブログもやっています。
:::
- [x] Twitter：[@emiru_rn](https://twitter.com/emiru_rn)
- [x] ブログ：[Route Boy](https://routeboy.net/)

ありがとうございました。
【あべ塾 - 課題4 -】AWSAmplifyのチュートリアルでSNSアプリを作ってみた

# 作成したアプリについて
今回は、AWSAmplifyのチュートリアルを通して、SNSアプリを作ってみました。

# AWSAmplifyを通して使用したサービスについて（SNSアプリ：2つ以上）
### AWS Lambda
> AWS Lambdaは、AWSが提供するサーバレスコンピューティングサービスの１つです。活用することで、利用者はインフラ管理を気にすることなく、コード開発に集中できます。オペレーティングシステムなどのインフラストラクチャの管理が不要で、利用者はプログラムコードを準備し、Lambdaにアップロードするだけで実行できます。
サーバレスという言葉になっていますが、実際に稼働するサーバがないというわけではなく、AWS側で実行基盤が管理されるため利用者の管理するサーバが無いということになります。利用者はインフラ部分の管理をAWS側に任せられるため、ビジネスロジックに関わるコード開発に集中できます。

### AWS DynamoDB
> どんな規模にも対応する高速で柔軟なNoSQLデータベースサービス
> Amazon DynamoDBは、規模に関係なく数ミリ秒台のパフォーマンスを実現する、key-valueおよびドキュメントデータベースです。
Lyft, Airbnb, Redfinなどの世界で最も急速に成長しているビジネスや、Samsung, トヨタ、Capital Oneといった企業の多くは、ミッションクリティカルなワークロードをサポートするために、DynamoDBのスケールやパフォーマンスを重要視しています。
数十万ものAWSのお客様が、あらゆる規模で低レイテンシーなデータアクセスが必要なモバイル、ウェブ、ゲーム、広告技術ｍIoT、及びその他のアプリケーションのキー値とドキュメントのデータベースとして、DynamoDBを使用しています。アプリケーション用に新しいテーブルを作成すると、残りの処理はDynamoDBが行います。


# 自身が今回の課題をこなす上で苦労した点

### 1. ファイルの分離
前回のTodoアプリでは、一つのslice内で**state**や**ロジック**を管理していましたが、今回は`まずGraphQLデータをgetするApi用のファイル`を別に作成しました。

どのファイルにどのようにロジックを切り出せばいいのかが、最初はわかりませんでした。

### 2. GraphQL
GraphQLの`mutation`, `query`, `subscription`や、`amplify mock api`で起動する**GraphiQl**の使い方などが、最初はどのように仕組みで動いているのか「？」でした。

### 3. stateをReduxに置き換え
チュートリアル時に作成されている`state`を、ひとつずつ`Redux`での**グローバルなstate管理**に置き換えていく部分で、思うようにデータを取得できず困惑しました。

# 苦労した点をどのように克服したか
1. 一つのファイルやロジック単位で、`いろいろな作業をさせない`ように意識して、ロジックを組み立てていきました。

1. **GraphiQl**内で、`query`や`mutation`の各コマンドの挙動を確認しました。queryは**REST API**でいうところの`GET`、**mutation**は`POST`, `PUT`, `DELETE`だと認識しています。
1. なんだかんだここが一番苦労した箇所だと思います。**TypeScript**の`型エラー`や、`データが上手く渡せていなかった`りしました。
基本的には、**一箇所**（HOMEに関するコンポーネントなど）のロジックを作ることができたら、別コンポーネントにもその応用でロジックを組み立てて行くことができるので、**まずは１つ**完成させました。
あとは、どうしても分からない場合はあべさんのリポジトリを参考にロジックの意味を考えながら、とりあえず前に進みました。

また、エラーが発生した際にやみくもにエラーを検索するのではなく、まず**「エラー文の内容を理解する」**ように努めました。
そして、そこから**「何が原因でエラーが起きているのか」**などの**仮説**を立て、**検証**に移るようにしました。
やはり、解決できないエラーがある場合は、**そもそもエラー文を理解できておらず**、問題の内容を把握しきれていません。
どの課題でも言えることですが、やはり`console.log()`やReduxの`Dev Tools`を使って、stateの中身の確認などをひとつずつ行い、原因を特定する力が重要な気がします。


# 参考サイト

https://chott-works.com/tips/AWS/Amplify/Init

https://keizokuma.com/js-array-object-sort/

https://amplify-sns.workshop.aws/en/00_prerequisites.html

https://techtechmedia.com/unique-key-prop-react/

https://reactjs.org/docs/lists-and-keys.html#keys

https://codehero.jp/reactjs/55840294/how-to-fix-missing-dependency-warning-when-using-useeffect-react-hook

https://www.redhat.com/ja/topics/api/what-is-graphql

https://stackoverflow.com/questions/52644087/property-subscribe-does-not-exist-on-type-promisegraphqlresult-observable

https://teratail.com/questions/247984

https://aws.amazon.com/jp/blogs/mobile/configure-environment-variables-and-secrets-for-your-lambda-functions-with-amplify-cli/

https://qiita.com/shimi7o/items/452fb505f2415b907633

# まとめ
SNSチュートリアルの課題は、[Amplify SNS Workshop](https://amplify-sns.workshop.aws/ja/00_prerequisites.html)の内容に沿って進めていくのですが、一回通しただけでは全く理解出来ず、かつエラーに見舞われて全く進めない、という状況に何度も追い込まれました。

何度かお手上げ状態になり、**最初からやり直す**羽目になったのですが、その過程で、チュートリアルをしっかり読んでいく（読み飛ばさない）ことで少しずつ理解を深めていくことが出来ました（最初からしっかり読みなさい）。

一応課題を終えたのですが、正直理解できているとは言えない状態なので、引き続き勉強していきます。
「プログラムで定積分するだけ」を参考にWolframAlphaとSymPy Liveでやってみた。

オリジナル
今回は$f(x)=3x^2-6x+5$ を $0\\leq x\\leq3$で積分する。

https://qiita.com/JJ1LIS/items/dcf7fec09f05e03f19ed

#wolframalphaで

https://ja.wolframalpha.com/input/?i=integrate%283*x%5E2-6*x%2B5+%2C%28x%2C0%2C3%29%29

https://ja.wolframalpha.com/input/?i=%E5%AE%9A%E7%A9%8D%E5%88%86&assumption=%7B%22F%22%2C+%22Integral%22%2C+%22rangeend%22%7D+-%3E%223%22&assumption=%7B%22F%22%2C+%22Integral%22%2C+%22integrand%22%7D+-%3E%223*x%5E2-6*x%2B5+%22&assumption=%7B%22C%22%2C+%22%E5%AE%9A%E7%A9%8D%E5%88%86%22%7D+-%3E+%7B%22Calculator%22%7D&assumption=%7B%22F%22%2C+%22Integral%22%2C+%22rangestart%22%7D+-%3E%220%22

#SymPy Liveで

以下サイトに、ソースコードを貼り付けて、Evaluateです。

https://live.sympy.org/

```python
from sympy import *
var('x')
print("#",integrate(3*x**2-6*x+5 ,(x,0,3)))
# 15
```
LaravelでCSSが接続できない

基本的にhtmlからcssへリンクさせるときの記述は

```php:html
<link rel="stylesheet" href="繋ぎたいCSS">
```

ではあるが

Laravelでは

```
 <link rel="stylesheet" href="{{ asset('css/cssファイル') }}">
```

を用いる。

{{PHPの処理}}を書き込むとPHPの記述が適用されるけれど
その理由が下記のURLに記載されている。
https://biz.addisteria.com/laravel_escape/#toc2

これによって、publi配下のcssファイルが適用されるのである。
Mac+pyenvでconfigure: error: C compiler cannot create executablesが起こったときの対処法

# 起こった現象
Mac(Big Sur)でpyenv installを行おうとすると、下記エラーが発生しました
色々調べたところ、どうやらOSをアップデートしたことが原因のようです

```
BUILD FAILED (OS X 11.5.2 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/6j/sngymjzn5975q6dzn83231080000gn/T/python-build.20210923150353.1269
Results logged to /var/folders/6j/sngymjzn5975q6dzn83231080000gn/T/python-build.20210923150353.1269.log

Last 10 log lines:
checking for --enable-universalsdk... no
checking for --with-universal-archs... no
checking MACHDEP... checking for --without-gcc... no
checking for --with-icc... no
checking for gcc... clang
checking whether the C compiler works... no
configure: error: in `/var/folders/6j/sngymjzn5975q6dzn83231080000gn/T/python-build.20210923150353.1269/Python-3.7.8':
configure: error: C compiler cannot create executables
See `config.log' for more details
make: *** No targets specified and no makefile found.  Stop.
```
# 対処法
以下2つの対応を行って解消しました
## xcodeの再インストール
コンパイルがうまくいかないのは、主にxcodeが原因のようです。
荒業ですが、以下の手順で行いました

```
$ sudo rm -rf /Library/Developer/CommandLineTools
$ xcode-select --install
```

## venvの再インストール
念の為venvも再インストールしました

```
rm -rf /Users/【ユーザー名】/.pyenv/
brew uninstall pyenv
brew install pyenv
``` 

私の環境では以上の対応で解決しました！
arduinoでRGB LED その3

#概要

arduinoでRGB LEDやってみた。
wemos d1で、やってみた。

#配線

vcc - 5.0v
gnd - gnd
out - D9

#サンプルコード

7個が、ランダムに光る。

```
int l[30]; 
int b8[8] = {
	0b10000000,
	0b01000000,
	0b00100000,
	0b00010000,
	0b00001000,
	0b00000100,
	0b00000010,
	0b00000001,
};

void bit_off() {
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
}
void bit_on() {
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOS = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
	GPOC = 1 << 2;
}

void setup() {
	pinMode(2, OUTPUT);
}
void loop() {
	int on_off;
	int i;
	int  j;
	for (i = 0; i < 27; i++)
	{
		l[i] = random(32);
	}
	for (i = 0; i < 27; i++)
	{
		for (j = 0; j < 8; j++)
		{
			on_off = l[i] & b8[j];
			if (on_off == 0)
			{
				bit_off();
			}
			else
			{
				bit_on();
			}
		}
	}
	delay(100);
}





```

以上。
【JavaScript】オブジェクトを配列に変換（ {a: 1, b: 2}を[[a, 1], [b, 2]]に ）

## 実現したいこと
下記のようなオブジェクトを、

```
const OBJECT = {
    2021-09-01: 1, 
    2021-09-02: 1, 
    2021-09-03: 1, 
    2021-09-04: 1, 
    2021-09-05: 1, 
    2021-09-06: 1, 
    2021-09-07: 1
}
```

下記の配列に変換したい。

```
[
    ['2021-09-01', 1],
    ['2021-09-02', 1],
    ['2021-09-03', 1],
    ['2021-09-04', 1],
    ['2021-09-05', 1],
    ['2021-09-06', 1],
    ['2021-09-07', 1]
]
```

## 対応方法
Object.entries()メソッドを使う。

Object.entries()メソッドは、引数に与えたオブジェクトが持つ、文字列をキーとしたプロパティの組 [key, value] からなる配列を返す。

```
const RESULT = Object.entries(OBJECT);
```

## プロパティ名だけ取り出して、配列にする方法
Object.keys()メソッドを使う。

Object.keys()メソッドは、引数に与えたオブジェクトが持つプロパティの名前の配列を、通常のループで取得するのと同じ順序で返す。

```
const RESULT = Object.keys(OBJECT);
```

下記の配列が得られる。

```
[
    '2021-09-01', 
    '2021-09-02', 
    '2021-09-03', 
    '2021-09-04', 
    '2021-09-05', 
    '2021-09-06', 
    '2021-09-07'
]
```

## 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
iOSアプリの通信エラーをブレークポイントで起こす

# はじめに

一般的にiOSアプリで通信エラーを起こすには

* 機内モードをオンにする
* WiFiをオフにする
* Network Link Conditionerをオンにする
* 有線LANを抜く

などの方法がありますが、再接続に時間がかかったり、確認中はチャットやメールが使えないといった問題が起きます。
そこでXcodeのブレークポイントを用いた手法をおすすめします。

# 実例

APIリクエストを行う共通関数があるとします。

```
// 通信エラー時は completion の引数に nil が渡される
func requestApi(url: URL, completion: @escaping (Dictionary<String, Any>?) -> Void) {
    let request = URLRequest(url: url)
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        let json = try? JSONSerialization.jsonObject(with: data!, options: [])
        completion(json as? Dictionary<String, Any>)
    }
    task.resume()
}
```

その関数にブレークポイントを設定します。
![breakpoint.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/5201afb1-cddf-6e07-fbdc-4ed557e49e3c.png)
これでブレークポイントがオンの場合に通信エラーが起きます。

# 解説
ブレークポイントの`Debugger Command`でLLDBコマンドを2つ使っています。

* `po completion()`
    * 通信エラーを疑似的に起こすための処理
    * 今回の関数は通信エラー時に`nil`を渡す仕様なので、`completion()`としている
* `thread return`
    * 正規のレスポンスを使用させないための処理
    * swiftの`return`と同様に、関数内の残りの処理を実行せずに呼び出し元に戻る

`Automatically continue after evaluating actions`をオンにすることで、ブレークポイントで停止しないようにしています。
`po completion()`の箇所は実際の関数に合わせた実装が必要ですが、1度作れば使いまわせるため手間がかかるのは最初だけです。

この手法は以下メリットがあります。

* ブレークポイントなので、ワンクリックでオン・オフの切り替えが可能
* Mac・スマホの他の通信は遮断しないため、メールやチャットが使用できる
* 特定のAPIでのみ通信エラーを起こすことが可能（後述）

# 注意事項
この手法は開発中に使う時短テクニックです。
ブレークポイントを設定した通信処理のみエラーになるため、WebViewやFirebaseなどが行う通信はエラーになりません。
そのためテストではこの手法を使うべきではありません。

# 応用編

ブレークポイントを調整することで、特定APIでのみ通信エラーを起こしたり、通信エラー以外にも使えます。

## 応用編1.特定のAPIでのみ通信エラーを起こす

ブレークポイントのConditionに条件を設定することで、特定のAPIやパラメータの時のみ通信エラーを起こすことができます。
![condition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/85755482-0e8b-b2e5-4cab-718ecf572387.png)
Conditionに設定した条件`response?.url?.path == "/api/v2/items"`が`true`の場合に、`Debugger Command`が実行されて通信エラーになります。
この手法は特に以下ケースで有効です。

* ページネーションされたAPIの1ページ目のリクエストは成功させて、２ページ目のリクエストを失敗させる
* 同時にリクエストする2つのAPIのうち、片方だけ失敗させる

## 応用編2.レスポンスの改ざん

ブレークポイントでレスポンスを改ざんできます。
![limit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/06847328-1351-6be0-13fe-10cc014f1065.png)
`po result = ["type": "limit", "message": "limit"]`によりAPIレスポンス（`result`)を上書きしています。
この手法は特に以下ケースで有効です。

* APIのリクエスト回数超過エラーといった、起こすのに手間がかかるエラーケースの動作確認
* APIが未完成の状況下でアプリの動作確認
* APIサーバがメンテナンス中である場合を想定した動作確認

大きなレスポンスの改ざんはLLDBではやりづらいため、その場合は素直にCharlesなどを使いましょう。


## 応用編3：通信速度を遅くする

Network Link Conditionerを使って低速環境の再現をするケースが多いですが、ブレークポイントでもできます。
![sleep.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2055383/014f9afe-2da7-0a44-249e-f14b2b31bcec.png)
`po Thread.sleep(forTimeInterval: 10)`によりコールバックを遅延させています。
メインスレッドで`sleep()`を実行しないように、ブレークポイントの位置には注意が必要です。

この手法は特に以下ケースで有効です。

* 通信中にインジゲータが表示されているか確認
* 通信中にタップやサスペンドレジュームをしても問題が起きないか確認
[Rails]ログイン/新規登録機能とauthenticate_user!について

##初めに
####なぜこの記事を書きたかったのか
一度新しくアプリケーションを作るとき、deviseの存在は思い出せれるけど、どうやって使うのかど忘れるときがあるからメモしたい！

####環境
・Macbook Air (Retina, 13-inch,2019)
・プロセッサ 1.6GHz デュアルコアIntel Core i5
・メモリ　8GB 2133 Mhz LPDDR3
・MacOS Big Sur　バージョン 11.5.2

####記事の目次
**１）何ができるのか**
**２）前提条件**
**３）authenticate_user!とは？**
**４）authenticate_user!の使い方**
**５）最後に**

##何ができるのか
**=ログインしていないuserを感知して、強制的にログインページへ遷移させることができる**
**このメソッドが全部やってくれるので、自分でメソッド名を新たにつくって命令式を書かなくても自動でやってくれる！**

##前提条件:ログイン/新規登録の機能
####１）Gemfileの一番下にdeviseというgemを設定

```
gem 'devise'
```
####２）ターミナルで新たに記入したgemを導入する

```
bundle install
```

####３)devise関連のディレクトリーを追加する
 
```
（ターミナル）
rails g devise:install
```
####４)ログイン/新規登録用のviewの作成

```
(ターミナル)
rails g devise:views

＊ファイル名：registrationsは新規登録用
＊ファイル名：sessionsはログイン用
```
####5)userモデル作成後、usersテーブルの作成

```
(モデルの作成)
rails g devise user

(デーブルの作成)
rails  db:migrate
```
##※devise用のcontrollerはない
**application_controller.rb内にコードを書くと、すべてのコントローラにも適応されるを利用してdeviseの設定はここに書く！**

##authenticate_user！とは？
####ログイン/新規登録機能を使って、userがログイン状態でなければ、強制的にログインページへ遷移させるメソッド

##authenticate_user!の使い方
**下記で、userがログインしていない状態でなければ、強制的にログインへ遷移させられる！**
**これで知らないヒトがuserの個人ページへ遷移できなくなる！**

```
(コントローラー)
before_action :authenticate_user!
```

##最後に
ふと、思い返していると→ログイン/新規登録があるサイトをよく見かける！だから、authenticate_user!のメソッドが生まれたのかな？

ここまでよんでくれてありがとう！
EIP-1559まとめ

## Summary

EIP1559は手数料モデルを改変する提案。

1. GasFeeを**Base Fee (基本手数料)** + **Miner Tip(マイナー報酬)** をベースにしたオークションモデルへの変更
2. Base Feeのバーン.
    1. マイナーが人為的にネットワークを混雑させて、Base feeを高騰させておく金銭的動機を与えないようにするため.
    2. 一方、長期的な供給量のコントロールが不可能になるため、ネットワークに不安定さがもたらされる可能性がある.
3. 最大Gas limitを12.5 MGas → 25 MGasに倍増

## 効果

**ユーザー目線**

- 支払うべきGasPriceの設定が楽になる.

**マイナー目線**

- 報酬の量は減る.

**ネットワーク**

- 供給が減るのでデフレによる価値上昇の効果も受ける.
    - 小さいTxが多くなればなるほど供給量は減る.
    - Ropstenでの始動時は一日で88,400Ethがバーンされた.

## Objective

Tx Feeのボラティリティの高さを解消すること.

Gas Priceの予測をより簡単にすること.

### Base Fee (基本利用料)

ブロックに取り込まれるのに最低限必要な手数料.

Base Feeは毎ブロック上下する.

前のブロックのBlock sizeがターゲット(12.5MGas)からどれだけ離れているかで決定される.

Base Fee 👇 < 前のブロックのBlock sizeが50% < Base Fee👆

基本的には12.5MGasになるようにインセンティブが働く.

ブロック毎に最大±12.5%の調整幅で変化する.

Transaction feeをより予測可能にする

### Miner Tip

従来のGasPriceと同様に、Miner Tipが多ければ多いほど、マイナーに優先的に取り込んで貰える.

従来と同じで、EIP1559でも手数料による優先順位付けがバックアップ的に存在する.

![Screen_Shot_2021-07-24_at_12.36.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242159/d48fa661-e7f3-db4f-2eef-c11388702916.png)

予測不可能な形で、次のブロックでのGasPriceの平均が上がってしまい、結果取り込まれるまで時間がかかったりしてしまう.

## Fee Cap (Base Fee + Miner Tip)

Fee Capとはユーザーが支払える最大の手数料の合計で、Base FeeとMiner Tipの合計。

Base Feeは上下するので、Fee Capが不十分の場合は取り込める後続のブロックまで待つ形になる.

![Screen_Shot_2021-07-25_at_15.58.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242159/6fc9e3a3-7367-b0e3-a389-07e600350262.png)


## FAQ

## なぜBurnするのか?

A.マイナーが作為的にBase Feeの高騰させることで収益を上げるようなことを防ぐため.

## Alternatives

EIP1559の代替案として[EIP-2593](https://insights.deribit.com/market-research/analysis-of-eip-2593-escalator/)も提唱されている.

## Possible Attacks!


51%攻撃を使ったEIP-1559に対する攻撃例.

1. 51%のマイナーが空のブロックを作り続け、Base Feeを0にすることに同意する.
2. Base Feeが0になれば、もはやBase Feeは上がらなくなるので(?)、Miner Tipが重要になる. (= 従来に元通りになる.)
3. マイナーは従来の高い収益を上げる形になる.

## Refs.

[](https://finematics.com/ethereum-eip-1559-explained/)

[EIP 1559 FAQ - HackMD](https://notes.ethereum.org/@vbuterin/eip-1559-faq)

[Analysis of EIP-2593 (Escalator)](https://insights.deribit.com/market-research/analysis-of-eip-2593-escalator/)
PHP-CS-Fixerインストール出来ないエラーと解決方法

PHP-CS-Fixerのインストール時、エラーが出たのと解決方法が分かったので記載。ただし自身が学習中の初心者で内容が浅すぎるのと、ググっても同様のエラーが見当たらなかったため、もし相違あればコメント下さい。

#環境
|  | Ver |
|:-:|:-:|
| Mac OS  | 11.5.2  |
| PHP  | 7.3.24  |
| Laravel  | 8.37.0  |

#エラー内容
```
- Root composer.json requires friendsofphp/php-cs-fixer ^3.1 -> satisfiable by friendsofphp/php-cs-fixer[v3.1.0].
- friendsofphp/php-cs-fixer v3.1.0 requires symfony/polyfill-php72 ^1.23 -> found symfony/polyfill-php72[dev-main, v1.23.0, 1.23.x-dev (alias of dev-main)] but the package is fixed to v1.22.1 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
```

以下DeepL翻訳。
>ルートのcomposer.jsonにはfriendsofphp/php-cs-fixerが必要です
^3.1 -> friendsofphp/php-cs-fixer[v3.1.0]で満たします。
 
>friendsofphp/php-cs-fixer v3.1.0 requires symfony/polyfill-php72 ^1.23 -> symfony/polyfill-php72[dev-main, v1.23.0, 1.23.x-dev (dev-mainのエイリアス)]が見つかりましたが、パッケージは部分アップデートでv1.22.1(ロックファイルのバージョン)に修正されており、そのバージョンは一致しません。update コマンドの引数としてリストアップしていることを確認してください。

#解決方法
エラーログに載っていた。

```
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
```

>現在、特定のバージョンにロックされているパッケージのアップグレード、ダウングレード、削除を許可するには、--with-all-dependencies (-W) オプションを使用します。

よって次のコマンドを入力。

```
composer require --dev friendsofphp/php-cs-fixer --with-all-dependencies
```
【iOS アプリ開発】GUIの作り方

## まえがき

フロントエンドエンジニアとして 2,3 年やってきたが、今年 4 月突如として iOS エンジニアに転向することになったエンジニアによる技術メモです。
なお筆者が初学者のため内容の正しさは保証できません。不正確な情報、また間違い等ございましたらご指摘いただけると幸いです。

## GUI の作成方法

通常のWebアプリでは基本的には、HTML による構造化情報と、CSS によるスタイリングによって最終的に画面が作成されていきますが、
iOS アプリにおいてもこれと同じような構成により画面の生成が行われています。

### 登場する概念

具体的な話を始める前に、このあと登場する概念について先に紹介します。

#### XIB (Xcode Interface Builder) ファイル

**.xib ファイルはその略の通り、UI 作成に関するファイルです。**

一般に xib ファイルで再利用を目的として UI 作成を行うため、フロントエンドでいうコンポーネントに近いと思います。

#### Storyboard ファイル

**.storyboard ファイルは.xib の上位互換の立ち位置で、画面遷移情報も入れられます。**
なので、xib がコンポーネント的な使い道に対して、一つの画面の構成、または複数画面の構成とその遷移情報の管理として使用するのに適しています。

#### Interface Builder (以降、IB)

**IB とは、Xcode にビルトインされている、UI を視覚的に記述するエディターです。**
IB と通して、前述の xib、storyboard ファイルの記述を行います。

https://developer.apple.com/xcode/interface-builder/

#### Auto Layout

**Auto Layout とは、xib や storyboard にて定義・配置された View に対して、そのサイズや配置に関する制約を与えます。**

IB、またはコード上からこれらの制約を与えます。

CSS の属性 (e.g. `position`, `width`)というよりは、CSS そのものの概念に近いと（個人的に）思いますが、CSS ほど機能は豊富ではなく`display: flex`に近い機能に関しては`StackView`という UIView を使用するケースもあります。

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/index.html

### 主な作成パターン

UI の作成方法は主に以下の 3 パターンに別けられると思います。

1. IB で作成する方法
2. コード上で作成する方法
3. SwiftUI で作成する方法

これらは完全に独立したものではなく、例えば IB 上で UIView の配置と Auto Layout による制約を加えられますが、動的にこれらを追加・変更・削除したい場合は 2.のコード上でそれらの操作をすることもあります。

フロントエンドに馴染みのある方であれば、以下のイメージを持っていただければ十分かと思います。

"1. IB で作成する方法"は、HTML と CSS で GUI を作成するようなもので、より高度な使い方として`<template>`タグのように事前に情報を埋め込んでおいて JavaScript 上で動的に利用するといった事も、 IB 上の`opacity`や`isHidden`属性の切り替えによって実現可能です。

"2. コード上で作成する方法"は、JavaScript 上で`document.createElement('div')`などの API を駆使して HTML や CSS を動的に操作し作成するようなものです。

"3. SwiftUI で作成する方法"は、JSX 記法のような JavaScript 上で UI を比較的簡単に書けるようなものです。（あくまでもイメージなので、トランスパイルなどは SwiftUI 上では行われません。）

## あとがき

私がいざ初めてiOSアプリを開発する際には、特にGUIの作成方法についてよく理解できずにいました。（特にInterface Builderはアプリエンジニア以外にとっては新鮮？）
今回は詳細については触れず概念的なもののみに留めましたが、頭の中のざっくりとしたイメージを掴んで、今後の開発に役立てれば幸いです。
【C++】二分探索木の実装

# 概要
二分探索木の説明と、節点の挿入、探索、削除等の基本的な操作の実装を紹介します。
もし、間違い等ありましたらコメントで教えて頂けると助かりますm._.m

## 二分探索木とは?

### 種類
木構造 ⊇ 探索木 ⊇ 二分探索木

### 制約
任意の節点は最大2つまでの子を持ち、左の部分技の値 < ノードの値 < 右の部分技の値　を満たす

すなわち、以下の画像にある赤い節点は制約を満たしていないことになります。

### メリット
中間巡回順で探索すると昇順で値を得られる。

## 操作
### 節点の構造体
節点(Node)を以下の構造体として勧めていきます。

```cpp
struct Node {
    int key;
    Node *parent, *left, *right;
}
```

`int key`は、この節点の持っている値
`Node *parent`は、この節点を子として持つ節点のポインタ(字の如く親)
`Node *left, *right`は、この節点が子として持つ節点のポインタ

また、ヌルポインタを区別するため、グローバル変数に`NIL`を定義します。
これは、根の親など存在しない節点へのポインタのために使用します。

### 挿入

節点の挿入は、木の根から末端まで、挿入したい節点の値との大小関係の比較を行うことで可能。
キー`k`を持つ節点を挿入する場合、

```cpp
void insert(int k) {
    Node *x = root;     // xは比較する対象となる節点、初期値は根であり、kとの比較によってx->left や x->rightが新たに代入される
    Node *y = NIL;      // 新たに挿入される節点の親のポインタの保存目的
    Node *z = new Node; // 新たに挿入される節点

    // 節点の初期化
    z->val = k;
    z->left = NIL;
    z->right = NIL;

    while( x != NIL ) {
        y = x;
        if (x->val < z->val) {
            x = x->right; // 挿入する節点の値が、xの節点の値より大きい場合、xの右側へと進む
        } else {
            x = x->left;  // 挿入する節点の値が、xの節点の値より小さい場合、xの左側へと進む
        }
    }

    z->parent = y;
    if (y != NIL) { // y != NIL => zは親を持つ
        if (y->val < z->val) {
            y->right = z;
        } else {
            y->left = z;
        }
    } else {        // y == NIL => zは親を持たない => zは根である
        root = z;
    }
}
```


### 探索
特定の値`k`を持つ節点の探索は、根から探索を始め、大小関係からどちらの子へと探索を進めるかを決定します。
終了条件は、最下層まで到達した場合 || `k`を持つ節点を見つけた場合です。

```cpp
Node* find(Node* u, int k) {
    while(u != NIL && k != u->val) {
        if ( k < u->val ) u = u->left;
        else u = u->right;
    }
    return u;
}
```

ここでは、見つからなかった場合は、`NIL`へのポインタが返ってくる設計になっています。

### 削除
特定の節点を削除する場合、以下の3つのパターンに分けて考えます。

1. 削除対象の節点に子がない場合
2. 削除対象の節点に子が一つある場合
3. 削除対象の節点に子が2つある場合

手順
1. 単純にその節点の削除で完了します。
2. 削除対象の節点を、その子で置き換える完了します。
3. 削除対象の節点を、中間順巡回で次に訪問される節点で置き換えることで完了します。

```cpp
void del(Node *z) {
    Node* y; // 
    Node* x;

    if (z->left == NIL || z->right == NIL) y = z;
    else y = treeSuccessor(z);

    if (y->left != NIL) x = y->left;
    else x = y->right;

    if (x != NIL) x->parent = y->parent;

    if (y->parent == NIL) {
        root = x;
    } else {
        if (y == y->parent->left) y->parent->left = x;
        else y->parent->right = x;
    }

    if (y != z) z->val = y->val;

    delete y;
}
```
LaravelインストールからDB接続までのコマンド

#Laravel初心者がwebサイト立ち上げまで、コマンドまとめてみた
PHPを学習し、自分が作りたいwebサイト、アプリを実装するために記事を書きます。
初学者なので、間違っている可能性があるので、全てを鵜呑みにしないでください。ですが、誤記事にしないよう努めます。

早速ですがいってみましょう！！

##Laravelインストール

※初めに開発環境はMAMPを使っています。
※Laravelバージョンは6を指定しています。

MAMP/htdocsまでディレクトリを移動します。

1.Laravelインストール

```
htdocs$ composer create-project laravel/laravel フォルダ名 --prefer-dist "6.*"
```

--prefer-dist こちらのオプションはファイルの圧縮版をダウンロードすることで早くダウンロードすることができます。

2.サーバースタート

```
フォルダ名$ php artisan serve
```
サーバーを立ち上げることができました。
http://127.0.0.1:8000をurlで入力すると自分が作成したフォルダの中の
resources/views/welcome.blade.phpが見れます。

3.Laravel初期設定

タイムゾーンと言語設定が日本じゃないのでそれを設定します。

```config/app.php
'timezone' => 'Asia/Tokyo',
```
70行目あたりです。

```config/app.php
'locale' => 'ja',
```
83行目あたりです。

次にDB文字コードの設定です。

```config/database.php
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
```
55,6行目あたりです。'utf8mb4',元はこれになっているはずです。マルチバイトコード

4.デバッグバーのインストール
DBのやりとりを見るためにデバッグバーをインストールします。

```
フォルダ名$ composer require barryvdh/laravel-debugbar
```

##データベース設定
1.作成したフォルダ名>.env
接続したいDBの名前、user_name、passwordを設定する。

```.env
DB_DATABASE=hoge
DB_USERNAME=localhost
DB_PASSWORD=hogehoge
```
任意の名前に設定し、phpmyadminを立ち上げ、DB新規作成をクリック.envで記載したBD名を記載して、文字コードは
そのままにし作成。
作成したDBにアクセスできるユーザーを登録します。
権限をクリックし、ユーザーアカウントをクリック、ユーザー名とパスワードを記載して実行で完了です。

また次の設定も必要です。

```config/database.php
'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock',
```
を変更します。

2.データベース接続確認
Laravelをインストールした時にテーブルを作成する仕組みが備わっています。

```
フォルダ名% php artisan migrate
```
phpmyadminを見ると作成したデータベースにテーブルが作成できたと思います。
これでデータベースにアクセスできました。
compTIA Network＋受験記

compTIA Network＋
-
compTIA Network＋とは
・ネットワークの構築
・ネットワーク運用・保守(トラブルシューティング)
・ネットワーク接続の確立
等々に必要な知識とスキルを評価する資格試験になっております。

学習方法
-
私が使用したサイトや教材は以下になります！

・TACの模擬試験
大きな声で言えませんが、類似した問題がこちらから7割出ています。
有料ではありますが、確実に点数を稼ぎたい方は受講してみるのがオススメです。
https://www.tac-school.co.jp/kouza_it/it_crs_comptia_networkplus.html

・web上の無料問題集
こちらからも出題される類似の問題があります。
厄介なのが正解の選択肢が不正解になっていたり、不正解の選択肢が正解になっているなど、精度がちょっとガバガバな部分がありますので注意してください。
https://www.jpnshiken.com/exam/N10-007-comptia-network-n10-007-8787.html

・自社のイーラーニング
こちらはかなり限定的だと思います。
イーラーニングを設けている企業に勤めている方でしたら、絶対やるべきだと思います。
企業によっては問題の編集がガバガバなところもあるかと思います。
問題をコピペしてリリースしてる(うちの場合はそうでした（笑）)ケースもあるかもしれないです。

基本的にはTACの模擬問題を全て解けるレベルになれば合格点には届くと思います。

試験料
-
compTIAに限らずベンダー試験全般に言えることですが、デフォルトで激高です（笑）
一万以上がテンプレですが、Network＋だと￥42,408(compTIAストアでの税込価格)になります。(めちゃくちゃ高い)
https://jp-store.comptia.org/?location=japan
クッキーとセッションの違い

# クッキー 
RFC 6265で定義されているHTTPにおけるブラウザとサーバー間で状態を管理するプロトコル。
HTTPにおける通信ではステートレスなので同じユーザーからのリクエストだとしても１回目のリクエスト２回目のリクエストで区別することができない。そこで、ユーザーに関する情報（ユーザーID,パスワード）などをブラウザ内のクッキーにテキストファイルとして保存する。この保存された情報をリクエスト時にサーバーに送ることで、サーバー側はどのユーザーのリクエストかを判別することができる。
ここで重要なのは、ユーザー情報そのものをクッキーに保存している点である。

#　セッション
セッションとは通信の開始から終わりまでの一連のやり取りのこと。
セッションIDと呼ばれる識別子によってユーザーを判別する。クッキー との違いはユーザー情報そのものをユーザー識別として使うのではなく、セッションに紐づけられた識別子でユーザーを判別する。また、このセッションIDの保存場所はクッキーでもURLでも隠しinputフィールドでも良い。
また、セッションIDとそれに紐づくユーザー情報はウェブサーバーのメモリ上だったり、何らかのデータベースで保存される。

デフォルトでは、セッション管理にウェブサーバーのメモリが使用される。しかし、この方法だと負荷分散のためにウェブサーバーを複数台立てていた場合に共有することが難しい。そのため、Redisなどのデータベースを使用するのが好ましい。

# 参考記事
https://tech-blog.rakus.co.jp/entry/2017/10/17/111828
https://blog.takanabe.tokyo/2014/12/%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%81%AE%E5%91%A8%E8%BE%BA%E7%9F%A5%E8%AD%98%E3%81%BE%E3%81%A8%E3%82%81/
データベースのトランザクション処理について整理する（その1）

# はじめに

この記事はオライリーから出版されている「詳説データベース」から得られた知識を自分用にまとめるための記事です。自分なりの解釈を含みまとめるので、もしかすると誤りが含まれているかもしれません。

# トランザクション

データベース管理システムにおける動作の、分割不可能な単位。複数の操作をひとまとめにしたものである。
以下のACID特性を維持する必要がある。

1. 原子性（Atomicity）
  - 分割不可能であり、トランザクション内のすべてのステップが成功するか、しないかとなる。
    - 部分的にトランザクションを適用することはできない。
  - トランザクションは最終的にコミットかロールバックが行われる。
1. 一貫性（Consistency）
  - データベースのすべての特性（制約・参照整合性など）を維持したまま、データベースをある有効な状態から別の有効な状態へ変化する。
  - 別の言い方をすると、トランザクションの前後でデータの整合性が保たれる。
1. 分離性（Isolatiion）
  - 並列して実行される複数のトランザクションは互いに干渉を受けない。
  - 状態変更の可視化のタイミングや並行するトランザクションにどの変更を可視化するかを定義する。
1. 永続性（Durability）
  - 何らかの障害があっても、データベースのすべての変更をディスク上に永続化する。

これらを実現するための基本コンポーネントとして「トランザクションマネージャ」「ロックマネージャ」「ページキャッシュ」「ログマネージャ」が存在し、これらによってデータベースシステムが構成される。

## バッファ管理

大半のデータベースは、永続ストレージとメインメモリの2種類の記憶装置で構成される。永続ストレージへのアクセスは一般的に遅いので、アクセスする回数を減らすためにページをメモリ内にキャッシュする。

メモリにキャッシュされたページは、他のプロセスがディスク上のデータを変更していない、という前提のもとに利用できる。このアプローチは仮想ディスク（ページキャッシュまたはバッファプール）と呼ばれる。

### 用語まとめ

* ページイン
    * 未キャッシュのページがディスクから読み込まれること
* フラッシュ
    * キャッシュされたページに変更が加えられ、ディスクに書き戻すこと
* ダーティ
    * キャッシュされたページに変更が加えられたものの、フラッシュされていない状態

## キャッシュ

キャッシュの利用率を高めることで、永続ストレージにアクセスせずにより多くの読み取り、書き込みに対応できる。
ただし、ページキャッシュには容量に限りがあるので、古いページの退避が必要になる。ページの内容がディスクと同期済みであれば即座に退避できるが、そうでなければ（ダーティであれば）フラッシュする必要がある。

データベースがクラッシュした場合に、フラッシュされなかったデータはすべて失われてしまう。そのため、フラッシュはチェックポイントプロセスと協調して動作し、永続化されるようにする。
チェックポイントプロセスは、WAL（ログ先行書き込み）とページキャッシュを制御し、フラッシュ済みのキャッシュに関する操作のログのみ廃棄するように管理する。

ページキャッシュの容量限界に達したとき、古いページを退避させないと新しいページがロードできない。
退避させるためのルール（退避ポリシー・ページ置換ポリシー）に基づいて行われる。例は以下。

### ポリシー例

* FIFOとLRU
    * First In First Out（先入れ先出し）
        * 最も利用頻度が高いと想定されるページは真っ先にページインする。
        * このアルゴリズムではそれが最初に置換されてしまうので実用的でない。
    * Least Recently Used
        * 利用履歴による管理
* CLOCK
    * アクセスビットを利用してページ参照を管理
* LFU
    * Least Frequent Used
        * 利用頻度による管理

## リカバリ

ログ先行書き込み（WAL: Write Ahead Log またはコミットログ）はクラッシュ、リカバリに使用されるディスク上の構造。
キャッシュされた内容がディスクへのフラッシュで書き戻されるまでは、操作履歴を保持するディスク上のコピーはWALにだけ存在する。
WALは追記型なので、書き込まれた内容はイミュータブル。

すべての状態の変更は、更新前イメージと更新後イメージ、あるいはそれらに対するundoとredoにより表現できる。

* 更新前イメージに対するredo -> 更新後イメージ
* 更新後イメージに対するundo -> 更新前イメージ

物理ログと論理ログを使用することで、レコードやページをある状態から別の状態へ変化させることができる。
多くのデータベースシステムではこれらの物理ログ、論理ログ、undo、redoのアプローチを利用している。論理ログを使用して同時実行性とパフォーマンスのためにundoを実行し、物理ログを使用してリカバリ時間を改善するためにredoを実行する。

メモリ内で行われた変更をいつディスクにフラッシュすべきかの決定のため、stealポリシーとforceポリシーを定義する。

* stealポリシー
    * ページのフラッシュを、トランザクションがコミットされる前であっても許容する
* no-stealポリシー
    * コミットされていないトランザクションの内容をディスクにフラッシュすることを許容しない
* forceポリシー
    * トランザクションがコミットされる前に、変更されたすべてのページをディスクにフラッシュする
* no-forceポリシー
    * トランザクションの間に変更されたページの中に、まだフラッシュされていないページがあったとしてもコミットを許容する

undoはコミットされたトランザクションでforceされたページの更新をロールバックする。redoはコミットされたトランザクションで実行された変更をディスクに適用する。

no-stealポリシーを使用すると、redoのエントリのみを使用したリカバリの実装が可能になる。
forceポリシーを使用すると、クラッシュリカバリにおいて追加作業を行わなくてもコミット済みのトランザクションの結果を再構築できるが、必要なI/Oのためトランザクションに時間が比較的長くかかる。

## ARIES（Algorithm for Recovery and Isolation Exploiting Semantics）

ログ先行書き込みアルゴリズムの一つ。steal/no-forceを採用。
このシステムが論文で解説されたのは1992年であるが、概念やアプローチ、パラダイムは現在においても重要な意味を持っているので調べてみるのが良い。
【JavaScript】配列内部のオブジェクトのプロパティ名を変更（map関数）

## 実現したいこと
JavaScriptにjson形式で渡した配列に対して、オブジェクトのプロパティ名を変更して、特定のプロパティのみ取り出した配列を新たに作りたかった。

具体的には、JavaScriptで、下記のように元の配列から新しい配列を作りたい。

### 元の配列
```
[
    {status: 1, name: '新規受付', orders_count: 10},
    {status: 2, name: '入金待ち', orders_count: 5},
    {status: 3, name: 'キャンセル', orders_count: 5},
    {status: 4, name: '取り寄せ中', orders_count: 4},
    {status: 5, name: '発送済み', orders_count: 4},
    {status: 6, name: '入金済み', orders_count: 3},
    {status: 7, name: '決済処理中', orders_count: 2}
]
```

### 欲しい配列
```
[
    {name: '新規受付', y: 10},
    {name: '入金待ち', y: 5},
    {name: 'キャンセル', y: 5},
    {name: '取り寄せ中', y: 4},
    {name: '発送済み', y: 4},
    {name: '入金済み', y: 3},
    {name: '決済処理中', y: 2}
]
```

## 対応方法
元の配列、ORDERS_COUNT_STATUSES

```
ORDERS_COUNT_STATUSES = [
    {status: 1, name: '新規受付', orders_count: 10},
    {status: 2, name: '入金待ち', orders_count: 5},
    {status: 3, name: 'キャンセル', orders_count: 5},
    {status: 4, name: '取り寄せ中', orders_count: 4},
    {status: 5, name: '発送済み', orders_count: 4},
    {status: 6, name: '入金済み', orders_count: 3},
    {status: 7, name: '決済処理中', orders_count: 2}
]
```

map()関数を使って、必要なプロパティのみ取り出し、プロパティ名を変更して配列を作る。

```
// map()関数を使う
const RESULT = ORDERS_COUNT_STATUSES.map((item) => ({
    name: item['name'], 
    y: item['orders_count']
}));
```

## map()関数について
map()は元となる配列から新しい配列を作成する関数。

```
let array = [ 配列データ ]
array.map( コールバック関数, オブジェクト );
```

コールバック関数には3つの引数を与えることができる。

- currentValue：現在処理中の要素の値
- index：現在処理中の要素の配列内における添字（省略可）
- array：mapが実行されている配列（省略可）

第二引数

- thisArg：コールバック関数内のthisを指すオブジェクトをバインドする（省略可）

```
array.map(function callback( currentValue[, index[, array]]) {
    // 新しい配列の要素を返す
}[, thisArg])
```

コールバック関数はアロー関数を使って書いたほうがシンプルに記述できるので、今回はアロー関数で記述。

### 他の使用例
特定のプロパティのみを取り出した配列を作る場合、

```
const RESULT = ORDERS_COUNT_STATUSES.map(item => item.orders_count);
```

下記のような配列が作れる。

```
[10, 5, 5, 4, 4, 3, 2]
```

reduce()で合計値を求めることもできる

```
const SUM = RESULT.reduce( (a, b) => a + b );
```


## 参考
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map
CentOS8 リモートデスクトップ（XRDP）接続してみた

## 前提
・サーバ（GUI使用）でインストールされていること。※CentOS8のインストール手順については割愛。

## XRDP インストール
以下のコマンドでリモートデスクトップ接続するためのXRDPをインストールする。

```
# yum install epel-release
# yum install xrdp tigervnc-server
```

## サービス起動
以下のコマンドでサービスの起動と自動起動設定を行う。

```
# systemctl start xrdp
# systemctl enable xrdp
```

## ファイアウォール設定
以下のコマンドで3389(tcp)ポートを開放する。

```
# firewall-cmd --permanent --zone=public --add-port=3389/tcp
# firewall-cmd --reload
```

## 

## リモートデスクトップ接続確認
ローカル(Windows)からリモートデスクトップ接続する。以下のようなダイアログが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481749/13fcffef-462f-c02a-a162-a2cdb98e6187.png)

username、passwordを入力し、OKをクリックするとCentOSの画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481749/ad5d3085-6141-b3e7-637b-407cb63d3c6a.png)

## 最後に
基本はTeraTerm等で接続して作業することが多いですが、GUIの方が作業しやすい場合もあるので、リモートデスクトップ接続できると便利ですね。