OmniAICreator/Qiita-1.07M huggingface dataset:
[Linux]VirtualBoxの仮想マシンにCentOS 7を実装する時に発生する不具合

#環境
ホストOS
・macOS Catalina 10.15.7
ゲストOS
・CentOS　7
https://www.centos.org/
仮想化ソフトウェア
・VirtualBox 6.1.14
https://www.oracle.com/jp/virtualization/technologies/vm/downloads/virtualbox-downloads.html

##1.インストールエラー

起動の度にCentOSのインストールを求められる不具合です。
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790862/c37c8bd6-e03c-8d0c-03fa-fba5c5fdd782.png">
本来ならば最初の設定の時だけに出てくるはずなのですが、これが起動の度に出現します
###対策
Cancelで進んでもInstall選択画面が出てきてしまい明らかに宜しくない挙動なので解決していきます
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790862/09b7536e-e651-7c44-de2f-02f89d6e9af0.png">


このエラーへの対応はVirtualBoxマネージャーの[設定]>[システム]で上記の画面に遷移し
[起動順序]のハードディスクを光学よりも上に配置する事で解決します
起動の時点でディスクを読み込む設定になってしまっているため、そこからOS情報が得られないため発生するエラーだと思われます

##2.予期しない終了
もう一つは起動時にエラー文が表示され、[再度開く]を選択するとさらにエラー文が表示される不具合です
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790862/3df163d2-e77a-f165-3e03-2591976c04b1.png">
上記の画面が出てきて
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790862/b32267f7-590b-a526-1cb2-7460a96f5eb1.png">
再度開くを選ぶとさらにエラー文が表示され、仮想マシンが全く起動できない

###対策
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790862/efb7bb1c-5123-03e2-a6c3-9add114db3b3.png">
このエラーはVirtualBoxマネージャー>[設定]>[オーディオ]で
上記の画面に遷移し[オーディオを有効化]を**オフ**にして起動するとエラーを回避する事ができます

#参考記事
**インストール不具合**
https://qiita.com/tochisuke221/items/0ff216d9eb9ab7783129

**起動不具合**
https://forums.virtualbox.org/viewtopic.php?f=8&t=99762
Github 二段階認証＋トークン発行

# 誰が必要なの？
Githubユーザ全員が行う必要があります。
> 2021 年 8 月 13 日以降、GitHub.com で Git 操作を認証する際にアカウント パスワードを受け付けなくなります。

https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/

# 何が必要なの？
* Github側で二段階認証の設定
* スマホ等で二段階認証アプリを利用（SMSによる認証も可）
* （スクリプト等でgithubリポジトリにアクセスする際自分のアカウントを使っている場合）トークンの発行

### 二段階認証設定
![two factor1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255401/682758fb-24d5-a2eb-96f4-1c0ead60cd3c.png)

1. Settings > Account Security > Two-factor Authentication > Enable two-factor authentication
2. 二段階認証アプリの利用かSMSか選択
  * この記事は二段階認証アプリを利用した記事です
3. 回復コード表示、保存
  * 何かあった時、なんとかするためのコード。超大事。
  * 例えばスマホが突然壊れた！買い替えて二段階認証アプリを入れた！といったとき、前のスマホで二段階認証アプリの情報を削除出来ないと基本駄目だったりする。
  * https://docs.github.com/ja/github/authenticating-to-github/securing-your-account-with-two-factor-authentication-2fa/recovering-your-account-if-you-lose-your-2fa-credentials
4. QRコード表示、二段階認証アプリでスキャンしてコード入力
  * 一般的なスマホの二段階認証アプリ、何でもよい。
  * この記事ではGoogle authenticatorを利用。Microsoftの方がメジャーかも。
5. 完了！

### ログインしてみる
一般的な二段階認証同様、普通にユーザIDとパスワード入力した後、二段階認証アプリで表示される6桁の数字を入れてログイン。SMS認証だと毎回SMSに認証コードが届くのだろうか・・・？
![verify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255401/b6d9fd6f-e06f-a1cb-f91d-c0f1b5c1c33f.png)

### トークン発行
二段階認証設定後、スクリプトからのgitへのアクセスは全てこうなってる。
> stderr: remote: Invalid username or password.
fatal: Authentication failed for 'xxxxxx'

1. Settings > Developer Settings > Personal access tokens > Generate new token
2. 操作に必要な権限を付与
3. tokenを保存、スクリプトのpasswordにtokenをそのまま設定

通るようになりました。

![personal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255401/9b1a466d-1a84-b53d-7cb2-bcf8edc48485.png)
【Sharepoint Online】"対象ユーザー設定の有効化" するとフォームが強制的にクラシック表示になる [改善済] => "従来の対象ユーザー設定の有効化"

# 挙動

モダンサイトのカスタムリストの設定で、[全般設定] > [対象ユーザーの設定] の [対象ユーザー設定の有効化] のチェックを ON にすると...。

![image-20210611094552187.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/b37a7313-802b-adb3-9622-3d6f979f5a86.png)


リストのアイテムをフォーム (DispForm, EditForm) で表示しようとすると、モダン表示に設定していても**強制的にクラシック表示**になってしまいます。(2021/06/10 現在)

- リンクのコピーなどで取得したURL
- リスト Web パーツで埋め込んだリストの項目を開く
- URL による直リンク

```
/sites/{サイト名}/Lists/{リスト名}/DispForm.aspx?ID={ID 番号}
/sites/{サイト名}/Lists/{リスト名}/EditForm.aspx?ID={ID 番号}
```

Microsoft 365 サポートに問い合わせたところ以下の回答が来ました。

> [回答内容]
>
> \----------
>
> 本日 6 月 10 日にお電話にてご連絡をいたしましたが、あいにくご不在のようでしたのでメールにてご連絡させていただきます。
>
> このたびはお問い合わせいただき誠にありがとうございます。
>
> 本件につきまして、モダンサイトのカスタムリストにて、"対象ユーザー設定の有効化" のチェックをオンにしている場合、アイテムのフォームを表示した際にクラシック表示となる動作は、現状の想定された動作となります。
>
> 恐れ入りますが、現時点の動作として何卒ご理解賜りますようお願い申し上げます。

「現時点の・・・」ということなので改善されることを祈ります。


# 改善

[対象ユーザー設定の有効化] が改善されていました！(2022/01 確認)
カスタムリストのアイテムもモダン Web パーツに対応したようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/49cf154b-0a4b-2065-34c6-824dc8f0c8ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111975/e44621c2-1b32-2969-fcb6-f8f42a0522b3.png)


[対象ユーザー設定の有効化] と [従来の対象ユーザー設定の有効化] に分かれていました。クラシックの Web パーツだけでなく、モダン Web パーツに対応した模様。

[従来の対象ユーザー設定の有効化] にチェックを入れると上記の現象は再現してクラシックなフォームに遷移しますが、[対象ユーザー設定の有効化] だけをチェックしていた場合には、モダンなフォームに遷移します。
CloudFrontがバケットポリシーでアクセス制御されたS3を見に行く時にまれに403エラーになる（未解決）

## 概要
CloudFrontを使ってS3のファイルを配信する時に[S3のバケットポリシーとCloudFrontのオリジンアクセスアイデンティティ（OAI）を使ってS3へのアクセスを厳格に制御する](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)方法があり、これを使うと「たまに403になる」現象に遭遇した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82888/4a6cf06c-b59d-8c43-c01b-a9acde29698a.png)

結論、未解決なので別の方法でアクセス制御を行ったのですが該当の現象に関してがググっても見つからなかったのでトラブルシューティングの履歴だけ書いておきます。

## CloudTrailでS3のgetObjectに関する詳細ログを見る
403を返してるのはCloudFrontですが、実際にどこで403が発生するかというとS3なのでCloudTrailログでS3の該当バケットに対するイベントログをCloudWatch Logsから見れる状態にする。
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/cloudtrail-logging.html

```
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AWSAccount",
        "principalId": "",
        "accountId": "ANONYMOUS_PRINCIPAL"
    },
    ...略...
    "userAgent": "[Amazon CloudFront]",
    "errorCode": "AccessDenied",
    "errorMessage": "Access Denied",
    ...略...
}
```

CloudTrailでS3に関するgetObjectのログを見ると確かに `userIdentity.accountId` の箇所が `ANONYMOUS_PRINCIPAL` になってる。

```
 "userIdentity": {
        "type": "AWSAccount",
        "principalId": "xxxxxxxxxxxxxxxxxxx",
        "accountId": "CloudFront"
    },
```
正常に処理された場合はちゃんとprincipalIdが乗る。 `userAgent` は間違いなく両者ともCloudFrontからのリクエストであることを証明しているのでCloudFrontの動きが怪しい、という所にアタリを付ける。

## わかっていること
 - 再現が難しい
   - 数百～数千リクエストに1回程度の頻度で、トラフィックのスパイクも関係なく起こる。
 - 「OAIがリクエストに乗らない」という現象を制御するための方法が無い

## 取った対応
 - CloudFront Distributionの再作成
   - CloudFrontのよくわからないエラーに関しても「作り直したら治った」という例がいくつかあるので、再生成して様子見
   - →ダメでした…
 - Origin Custom Headersで適当なヘッダーをS3に送るようにして、バケットポリシーでゆるく制御する
   - CloudFrontからS3に送られるヘッダーはCloudFrontやS3の設定値を見られない限り漏れないので適当なハッシュを乗せる。（予定）
 - サポートに連絡
   - そもそもこれバグじゃない？っていう報告はしています。
VSCodeをPhpStormっぽく使う方法

みなさんエディター・IDEは何を使っていますか？
結構使っている言語や昔からの慣れなどで使い慣れたエディターってありますよね。
しかし、転職などで今まで使用していた有償ライセンスのエディターが使えなくなった(エディターぐらい好きに選ばして欲しい)などありますね！たぶん。

今回、無料で使えるVScodeを個人的に好きなPhpStormっぽくできるかプラグイン等入れて試してみたので、まとめです。

# intelliJ IDEA Keybindingsを入れる
1. ```shift + command + X```を押して拡張機能のInstall画面に遷移して、「intelliJ IDEA Keybindings」と検索欄に入力する。
2. Install後、拡張機能を有効にする(有効になっていない場合) 

これでコマンドショートカットなどがintelliJ IDEA風になります。
個人的に```option + ↑```でブロック選択するのが強力なショートカットだと思っているので、これ使えるようになるので嬉しい。
あとは、```command + shift + [　or　control + ←``` or ```command + shift + [　or　control + →```でタブを移動できるのもよく使います。

# PHP Intelephenseを入れる
1. ```shift + command + X```を押して拡張機能のInstall画面に遷移して、「PHP Intelephense」と検索欄に入力する。
2. Install後、拡張機能を有効にする(有効になっていない場合) 
こちらは未定義の変数をグレーアウトしてくれたり、入力補完をしてくれる拡張機能です。また少しPHPStormに近づいた。

# PHP DocBlockerを入れる
1. ```shift + command + X```を押して拡張機能のInstall画面に遷移して、「PHP DocBlocker」と検索欄に入力する。
2. Install後、拡張機能を有効にする(有効になっていない場合) 
こちらのプラグインは```/**```を入力してエンター押すとPHPDocを挿入してくれれます。

# まとめ
VSCodeにも便利なプラグインは用意されているので、色々入れていけばPhpStormっぽくは使えるのですが、やっぱりPHPStormに慣れているとどうしても痒いところに手が届かない感が出てしまします。
有償ライセンス買おうかなー。。
twilio taskrouterのworkflowをstudioから呼び出そうと思ったけど、表示されなかった話

twilio taskrouterのworkflowをstudioのwidgetから呼び出そうと思ったけど、なぜか表示されなかったのでそのときのメモ書き

# 事象
taskrouter内で複数のworkspaceを作成し、それぞれのworkspace内にworkflowを作成した。
しかし、studioの[send-to-flex](https://jp.twilio.com/docs/studio/widget-library/send-flex)のworkflowにはコンソールの[workspace](https://jp.twilio.com/console/taskrouter/workspaces)画面を開いた時に、一番最初に表示されるworkspaceのworkflowしか表示されなかった。

# 調査
[send-to-flex](https://jp.twilio.com/docs/studio/widget-library/send-flex)のworkflow欄にはどのworkspaceが選択できるか特に記載はなかった。

# 多分？
send-to-flexウィジェットはFlexで利用されることを想定されているため、一つのTwilioプロジェクトにworkspaceは1つしかない想定なのかも。

# 結論
複数のworkspaceを作って運用したいときは、TwiMLを使って実装する。
studioを使いたいときは、一番上に使いたいworkspaceが来るように運用する。（作った後にworkspaceの順番は入れ替えはできない）
【Google Cloud Day '21】「激化する競争を勝ち抜くために企業が取るべきクラウド戦略と NTTデータのソリューション」を視聴して

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/4cbef2a3-237f-2333-58e4-d72023e0a293.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/7aace9ff-e6f2-8144-f148-73f4262bd644.png)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/3df3149f-6118-36a0-a743-83dd7640738b.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/edf3ffb5-823a-7931-65c1-52f0decf539a.png)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8fb20db9-df8a-bc69-a2b8-6dbd1350306d.png)
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8fa628d2-8234-f567-5324-4ca4ed54f9e3.png)
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/5d1a6ab4-670a-756a-8819-e1ad901839a1.png)
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/bbd96de2-08e2-ab91-194c-e318055748db.png)

技術力の高さをメリットに出していた
C++のTupleがあればPythonみたいな便利な書き方ができる

# 概要

C++11以降に追加された機能にTupleがあります。

https://cpprefjp.github.io/reference/tuple/tuple.html

これはPythonなどのプログラミング言語でおなじみなのですが、TupleによってC++でもPythonのような書き方ができるようになりました。

# 関数の複数戻り値

```C++
#include <iostream>
#include <tuple>

std::tuple<int, int> add_and_sub(int a, int b)
{
    return {a + b, a - b};
}

int main()
{
    auto [aa, bb] = add_and_sub(20, 10);
    std::cout << aa << " " << bb << std::endl;
    return 0;
}
```

表示は `30 10` となります。Tupleを使用することで複数の戻り値を返すことができます。そしてそれを[構造化束縛](https://cpprefjp.github.io/lang/cpp17/structured_bindings.html)を用いて複数の変数で受け取るという流れです。Pythonで書けば以下のようになります。

```py
def add_and_sub(a, b):
    return (a + b, a - b)

aa, bb = add_and_sub(20, 10)
```

# 範囲for

```c++
#include <iostream>
#include <tuple>
#include <vector>

int main()
{
    std::vector<std::tuple<int, int>> v{
        {10, 20},
        {2, 2},
        {4, 1}
    };

    for (auto [aa, bb] : v){
        std::cout << aa << " " << bb << std::endl;
    }

    return 0;
}
```

構造化束縛は範囲forとも相性が抜群です。TupleのVectorに対するループは上記のように書けます。Pythonで書くと以下のようになります。

```py
v = [(10, 20), (2, 2), (4, 1)]
for (aa, bb) in v:
    print(aa, bb)
```

# 構造体のソート

C++のTupleはPythonのと同様にprimitive型のみを含んでいればそのままソートすることができます。これを利用することで構造体のソートロジックを簡単に実装することができます。またラムダ関数とも相性が抜群です。

```c++
#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

struct Data
{
    int a;
    int b;
};

int main()
{
    std::vector<Data> v{
        {5, 6},
        {1, 2},
        {3, 4}
    };

    std::sort(v.begin(), v.end(), [](const auto &lhs, const auto &rhs){
                  auto lt = std::make_tuple(lhs.a, lhs.b);
                  auto rt = std::make_tuple(rhs.a, rhs.b);
                  return lt < rt;
              });

    for (auto [aa, bb] : v){
        std::cout << "Data[" << aa << "," << bb << "]" << std::endl;
    }

    return 0;
}
```

そう、実は構造化束縛はTuple以外の構造体にも使えるんです。Pythonで書くとこう。

```py
import dataclasses


@dataclasses.dataclass
class Data:
    a: int
    b: int


v = [
  Data(5, 6),
  Data(1, 2),
  Data(3, 4)
]

v.sort(key=lambda d: (d.a, d.b))

for d in v:
    print(d)
```

-------

auto, Tuple, 構造体束縛, 範囲for, lambda関数などをうまく使えばC++もPythonと同様に簡単に書けますね!
ループが絡むトランザクション

```sample_transaction.vb
Try

    ' SQLServerに接続する
    Dim con As New SqlConnection(
    "Data Source=hoge\SQLEXPRESS;" +
    "Initial Catalog=hoge;" +
    "Integrated Security=True")
    Dim cmd As New SqlCommand
    Dim sql As New StringBuilder
    con.Open()
    cmd.Connection = con

    'トランザクション
    Dim tran As SqlTransaction
    tran = con.BeginTransaction

    Try

        sql.AppendLine("INSERT INTO dbo.EMPLOYEES ")
        sql.AppendLine("( ")
        sql.AppendLine("  id, name ")
        sql.AppendLine(") VALUES ( ")
        sql.AppendLine("  @id, @name ")
        sql.AppendLine("); ")

        cmd.CommandType = CommandType.Text
        cmd.CommandText = sql.ToString()

        For i As Integer = 0 To dt.Rows.Count - 1

            cmd.Parameters.Clear()
            cmd.Parameters.Add("@id", SqlDbType.Int).Value = dt.Rows(i).Item(0)
            cmd.Parameters.Add("@name", SqlDbType.VarChar).Value = dt.Rows(i).Item(1)

            'プロシージャの実行
            cmd.Transaction = tran
            cmd.ExecuteNonQuery()

        Next i

        'コミット
        tran.Commit()

    Catch ex As Exception

        'ロールバック
        tran.Rollback()

    End Try

Catch ex As Exception
    MsgBox(ex.ToString)
End Try

```
RansackでRuby2.6未満も対応する

RubyonRailsの検索用のGem・Ransackですが、Ruby2.5以下の環境だと普通にGemfileにインストールすると

```
Gem::RuntimeRequirementNotMetError: ransack requires Ruby version >= 2.6. The current ruby version
is 2.5.0.
An error occurred while installing ransack (2.4.2), and Bundler cannot continue.
Make sure that `gem install ransack -v '2.4.2'` succeeds before bundling.

In Gemfile:
  ransack
```
となってしまうかと思います（2021年6月時点）。

これに対応するためGemfileに以下のように変更します。

```ruby:Gemfile
# Ransack
gem "ransack"
```

```ruby:Gemfile
# Ransack(For ruby2.3 - 2.5)
gem 'ransack', '2.4.1'
```

で

```
$ bundle update ransack
```

とします。これでRansackに関連する箇所だけ更新されます。
Thanks to： https://stackoverflow.com/questions/67917260/ransack-with-ruby-2-5/67917783#67917783
CakePHP3のクエリービルダーでUSE INDEXを使いたい


#前提
- CakePHP 3系
- MySQL 5.7

CakePHPのクエリービルダーを使ってSQLに USE INDEX (カラム名) を追加したい。
公式ドキュメントを確認したがクエリビルダーのページに記載はなかった。

#対応方法
from句に記載する

```php:SampleController.php
$articles = $this->Articles->find()
->from('articles Articles USE INDEX (category)') //'テーブル名 モデル名 USE INDEX (INDEX名)'
->where(['category' => 'test'])
->toArray();
```

以下のようなSQLが発行されます。

```sql:use_index.sql
SELECT Articles.id AS `Articles__id`, 
FROM articles Articles USE INDEX (category)
WHERE Articles.category = test
```

#参考

https://stackoverflow.com/questions/47394117/force-index-in-cakephp-3-3-query

CakePHP2より前のバージョンではまた別の方法を使っていたようです。

https://qiita.com/yKanazawa/items/0b0e65f2e03057294b3e
「テレワーク時代に求められるゼロトラスト・セキュリティーとは? ID・アクセス管理を徹底解説　」を視聴して

NISTはどこでも使ってる
https://www.pwc.com/jp/ja/knowledge/column/awareness-cyber-security/zero-trust-architecture-jp.html
アクセス権限はセッションごとに動的に制御される
ゼロトラストは流行ではなく、時代の流れが主な要因
ビジネスモデルやシステムが変わったことにより必要になった
＝＝
エンドポイントが自社で買ったのか、エンジニアが買ったものか？
エンジニアが買ったなら、ポリシーにもとづいてるか
＝＝＝
IBMのSSO製品A2：あくまでIAMにこだわっているところ
セキュリティのルール作成が大変
トラスティアというAIでポリシーを随時書き換えていく
最初の設定をしてくれれば、あとのリスク判定はA2でやる
マウスの動作もみてくれる
パスワードコピペとかしてたらブロックできる

※
IAMにフォーカスしているが、認証できることはいろいろあるので、非常に面白い機能だった
MS関連の機能とも連携できるようだし、使いやすそう
導入も簡単なら使いたい企業は多そう
気になるのは費用
セキュリティ事故の大きなものを調べる
日経新聞にもゼロトラストのワードがでてきた

![ibm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/d409a661-255d-70aa-dd30-bfb0de7f9667.png)
![ibm3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ccbb3968-49fe-f5e4-1508-93de365a0e92.png)
![ibm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/131884cd-35ae-3a1a-7df3-ff02fe3cfcd2.png)
![ibm4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/8c6ef1f1-d91c-338a-5a48-1fdda837fd20.png)
![ibm5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/ad207faf-bd44-0845-66da-46df4ed844e5.png)
![ibm6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/813fbfae-2e83-9a7b-8c36-2b32cb4bbbab.png)
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/0dc925f6-1e0d-12fd-b776-692ab3d47613.png)
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/556084/591f3db5-b7a3-9329-64a0-f20bb7526b96.png)
[Linux]grepコマンドと正規表現

#はじめに
"新しいLinuxの教科書"にてLinuxの勉強をしています！！
せっかくなので、こちらにアウトプットしながら勉強を進めていきます！

#grepコマンド

grepコマンドはファイル名から検索パターンに一致する**行**を出力する。

```:terminal
% grep [オプション] <検索パターン>　<ファイル名>
```

オプションには以下のようなものがある。

|オプション|意味|
|----|----|
|-n |行番号付きで表示する|
|-i|大文字小文字の区別なく検索する|
|-v|指定した検索パターンを含まない行を検索する|

#基本正規表現

正規表現とは、条件に合致する文字列集合を表現するための記法。

##^,*(ワイルドカード)

^は行の先頭を意味する。*は任意の文字列を示す。なお、正規表現を使用の際は、基本的には''で囲んで指定する。

```:terminal
% grep '^test-*' score.txt
  test-subject
  test-score
  test-averagescore
```

##.(ドット)
.（ドット）は任意の一文字にマッチする。

```:terminal
% grep 't.st' example.txt
  test.japanese
  test.math
```
また、これを組み合わせると、以下のような検索の仕方も可能となる

```
% grep 't..t' example.txt
  test
  toet
  taat 
```

ちなみに、.orgを検索パターンに置いた場合は、borgもヒットするし、~.orgもヒットする。つまり、単純なドットとしてもカウントされて、検索結果が表示される。それではうっとおしいため、単純に、「.org」という文字列のみ検索したい場合は、直前に\を置いて、エスケープさせてやります。

```:terminal
% grep '\.org' example.txt
```

##[]で特定文字の指定

[]を使用すると特定の文字が使用できる

```
% grep 't[ef]st' example.txt
  test
  tfst
```

[^]を使用する場合は、[]に含まれない一文字がマッチします

```:terminal
% grep 'mail[^13]' example.txt
  mail13以外がヒット
```

##^,$で位置を示す

^は行頭を示し、$は行末を示す。

```:terminal
% grep '^net' example.txt 
  netapp.cpm
  netshop.txt
```


```:terminal
% grep 'net$' example.txt
  qiita.net
  trend.net
```

##繰り返しの*

繰り返しの*は、直前の文字が0回以上存在するときマッチする。

```:grep
% grep 'B[ea]*r' drink.net
  Br
  Beeeeer
  Baaaaar
  Beaeear
```

#拡張正規表現

-Eオプションを使用すると、拡張正規表現として解釈されます。

##+
+は＊に似てますが、直前の文字が0文字の場合は許容しません。つまり、直前の文字が1回以上繰り返される場合に使います。

##?

?は直前の文字が0回または1回の繰り返しのとき、マッチします。

```:terminal
% grep -E 'Wine ?Wine' drink.txt
  WineWine
  Wine Wine
  
```

##{m,n}で繰り返しを指定

{m,n}は、m回以上n回以下の繰り返しを意味します。

```:terminal
% grep -E 'Be{1,2}r' example.txt
  Ber
  Beer
  BeerBeer
  BerBeerBer
```

こんな使い方もあります。
（Beerをもつ文字列のみ欲しいとき）

```:terminal
% grep -E 'Be{2}r' drink.txt
  Beer
  BeerBeer
```

ちなみに、{4,}とすると4回以上の繰り返しにマッチします。

##()で正規表現をグループ化

Wineとう単語の繰り返し文字列を探したいとき、以下のようにします。

```:terminal
% grep -E '(Wine){2,}' drink.txt
  WineWine
  WineWineWine
```
##|でOR表現

どちらかに当てはまらせるときはこんな感じです

```:terminal
% grep -E 'My (Wine|Vodka){2,}' drink.txt
  My Wine
  My Vodka
```

#おわりに

正規表現について感簡単にまとめてみました。
もっと応用部分についても学習しないといけませんね！！
Cloudflare Pages使ってみた！

# はじめに
こんにちは。サンリオのキャラクター、**シナモロール**を**シナモンロール**だと思ってました:bow: この場を借りて謝罪します、すみませんでした:bow: 筆者です。

さて、もう利用できるようになって結構経ってますが、**Cloudflare Pages**を使ってみたので、その設定の仕方を記事にしようと思います。

# Cloudflare Pagesとは
Netlify等と同様な静的サイトのホスティングサービスです！

無料プランで以下ができます！！
1. **月500回**のデプロイ
2. **20,000**ファイル
3. **10**カスタムドメイン
4. 最大**25MB**のファイルサイズ
5. **無制限**のユーザー数
6. **無制限**のプレビューデプロイ

# 前提
1. Cloudflareに会員登録済み.
1. プロジェクトはGitHubで管理している.
1. CloudflareにGitHubアカウント紐づけ済み.

# Cloudflare Pages使ってみた！


## 1. Cloudflare Pages画面でプロジェクトを作成.
![Pages-Account-Cloudflare-Web-Performance-Security.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/788ee16c-ee20-e992-4d4f-cbfe3cef346f.png)


## 2. GitHubから当該プロジェクトのリポジトリを選択.
![Pages-Account-Cloudflare-Web-Performance-Security (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/040cc662-b48b-0bb7-cbd0-508c7524eb05.png)

## 3. ビルドとデプロイをセットアップ.
設定するのは以下の項目.

1. プロジェクト名(サブドメインに使用されます).
1. フレームワークプリセット(自分はGatsbyを使用してます).
1. ビルドコマンド(2を選択すると自動入力されます, 異なる場合やオプション等ある場合は編集してください).
1. ビルド出力ディレクトリ(2を選択すると自動入力されます, 異なる場合は編集してください).
1. 環境変数(自分はContentfulやGoogleAdSense, GoogleAnalytics等をビルド時に必要な値があるので渡しています.).

![Pages-Account-Cloudflare-Web-Performance-Security (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86984/c98347c8-5a82-0a60-04dd-24923da0dbca.png)

## 4. ビルドとデプロイをセットアップができたら、保存してデプロイする.
自分はここで5分くらい待ちました:pray:

正常に完了すればサイトにアクセスできるようになります:ok_hand:

# おわりに
意外と簡単にできました！
ちょっとデプロイに時間がかかります。

1回設定してしまえば、ブランチにプッシュするたびにデプロイされるのが楽でいいですねー。
今度Contentfulからhockできる方法をちょっと探したいと思います。

それでは:bow:
Android10以上でError inflating class androidx.appcompat.widget.FitWindowsLinearLayoutと出てクラッシュする対策

こんにちは。[もぐめっと](https://mogmet.com)です。

本日は表題のようなエラーが出てActivityが立ち上がらずcrashしていたのでその対策について記載します。

## どんなエラー？

こんなエラーが発生していました。

```
Caused by java.lang.NullPointerException
Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Field.get(java.lang.Object)' on a null object reference
uk.co.chrisjenx.calligraphy.ReflectionUtils.getValue (ReflectionUtils.java:29)
uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.createCustomViewInternal (CalligraphyLayoutInflater.java:203)
uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.access$000 (CalligraphyLayoutInflater.java:20)
uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater$PrivateWrapperFactory2.onCreateView (CalligraphyLayoutInflater.java:302)
android.view.LayoutInflater$FactoryMerger.onCreateView (LayoutInflater.java:239)
android.view.LayoutInflater.inflate (LayoutInflater.java:659)
uk.co.chrisjenx.calligraphy.CalligraphyLayoutInflater.inflate (CalligraphyLayoutInflater.java:60)
android.view.LayoutInflater.inflate (LayoutInflater.java:534)
androidx.appcompat.app.AppCompatActivity.setContentView (AppCompatActivity.java:195)
...

```

具体的な原因はこのエラーの模様

```
Caused by android.view.InflateException
Binary XML file line #23 in com.hoge:layout/abc_screen_simple: Error inflating class androidx.appcompat.widget.FitWindowsLinearLayout

```

最近アプリをアップデートする際に一気にライブラリなどもアップグレードしたのですが、それをえいやとリリースしたらAndroid10以上で発生していました（自分の端末はAndroid8だったため気づかなかった）

## 対策

ぐぐったら下記に答えがありました。

https://stackoverflow.com/questions/56524914/crash-on-android-10-inflateexception-in-layout-abc-screen-simple-line-17

> More specifically, both Calligraphy and ViewPump need to be updated:

```
implementation 'io.github.inflationx:calligraphy3:3.1.1'
implementation 'io.github.inflationx:viewpump:2.0.3'
```

calligraphyをアップデートしろってことですね

これにアップデートすると書き方も新しく書き直さないと行けないです。

Install

```Activity.kt
@Override
public void onCreate() {
    super.onCreate();
    ViewPump.init(ViewPump.builder()
        .addInterceptor(new CalligraphyInterceptor(
                new CalligraphyConfig.Builder()
                    .setDefaultFontPath("fonts/Roboto-RobotoRegular.ttf")
                    .setFontAttrId(R.attr.fontPath)
                    .build()))
        .build());
    //....
}
```

Inject

```Activity.kt
@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(ViewPumpContextWrapper.wrap(newBase));
}
```

これで無事に治ります。

## 再発防止策

ではどうすれば起きてなかったというところを考えると、FirebaseのTest Labを使ったり、Play Consoleのリリース前レポートをちゃんと確認していれば早期に発見できていたかもしれません。
あとは、10%リリースなどちょっとずつリリースすることによってユーザへの被害も最小限に抑えられたかもしれませんね。

## まとめ

ライブラリをアップデートした時は慎重にリリースしよう！

最後に、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/
[2021年] rails6 + active_admin + active_storageでドチャクソハマった件

掲題の件、
備忘として書きます。

# 環境

[DB] 
postgresql

[rails]
6.1.3.2

[active_admin]
2.9.0

# 何にハマったか

active_storageを使ってmodelに

```
has_one_attached :image1
has_one_attached :image2
```

みたいな実装をしていた。
ところがふとした拍子に、きっかけは不明なものの、(Heriokuにデプロイしたあとくらいから出てコードを戻したりしても解決しなかった)
そのテーブルのnewのぺージにアクセスすると下記のエラーが表示された。
エラー内容が意味不明な上に出るようになったきっかけも不明だったため(元はnewで画像の登録も出来ていた)
非常に困惑したがどうにか無理やり解決したのでその方法。

```
   Rendered vendor/bundle/ruby/2.7.0/gems/activeadmin-2.9.0/app/views/active_admin/resource/new.html.arb (Duration: 53.2ms | Allocations: 11450)
 Completed 500 Internal Server Error in 139ms (ActiveRecord: 19.3ms | Allocations: 19748)

 ActionView::Template::Error (undefined method `persisted?' for #<Genre::ActiveRecord_Relation:0x00007f16023dbef8>):
     1: insert_tag renderer_for(:new)
```

# 結果

active_adminのソースを読みながらnewページにアクセスしたときに何が起こるのか読み砕いてデフォルトの挙動をオーバーライドしたことにより解決出来た。

そのサンプルがこちら

`app/admin/user.rb` みたいなテーブルだったとして

```ruby
ActiveAdmin.register User do
  controller do
    def get_resource_ivar
      return super if super.try(:persisted?)

      id = permitted_params[:id]

      resource = User
        .with_attached_image1
        .with_attached_image2

      if id.present?
        resource.find(id)
      else
        resource.new
      end
    end
  end
end
```

こう書く。まずsuperのメソッドで `persisted?` が呼べるなら問題ない。スルーする。
次にどうやらnewやeditに行ったときにactive_storageのrelationが悪さをしているようなので、
リレーションを追加してやる。

このとき、editとnewではidがある無しの違いがあるのでそこも考慮しないとどっちかでコケる。
結果、こう書いて動くようになったが正解かどうかはわからない。

あともっと他にいい書き方がありそうな気もするがコーディング規約的な話になってくるのでそこはよしなにやってほしい。
この記事が誰かの助けになったら幸いだ。
【Rails】ファビコンの設定

# 目的
Railsで作成したアプリにファビコンを設定する。

# 開発環境
macOS: *Big Sur*
Rubyバージョン: *2.6.5*
Railsバージョン: *6.0.0*

# 前提

- `アプリ`が作成されている。
[【Rails】簡単な投稿アプリの作成](https://qiita.com/oak1331/items/18a4f3a3386aab0fa354)

# 手順

1. [はじめに](#はじめに)
1. [画像の作成](#画像の作成)
1. [画像の編集](#画像の編集)
1. [画像のファビコン化](#画像のファビコン化)
1. [ファビコンの設定](#ファビコンの設定)
1. [確認](#確認)

# はじめに

今回はファビコンの設置を行っていきます。
ファビコン作成から設定まで簡単な方法で行っていきます。

# 画像の作成

まずは画像を作成していきます。

[canva](https://www.canva.com/)

こちらのサイトから`ロゴ作成`を選択し、ファビコンとなるデザインを作成していきます。
会員登録は必要ですが、無料で使えます。

![canva.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1337030/75a3c28e-efff-60bb-9a3d-a3b0db2cd5ab.png)

作成できたら画像をダウンロードして次へ進みます。


# 画像の編集

次に画像の編集を行います。（画像の編集が必要ない方は飛ばして頂いて構いません。あくまで見た目の修正です。）
今のままですと、ピン角になっているため、角Rを付けます。
[BANNERKOUBOU](https://www.bannerkoubou.com/)
こちらのサイトから画像を加工します!
加工が完了したらダウンロードしてください。

# 画像のファビコン化

先程ダウンロードした画像をファビコン化していきます。
[Favicon ジェネレーター](https://favicon-generator.mintsu-dev.com/)
こちらのサイトから画像サイズを選択し、画像拡張子を`「.ico」`に変更します！

今回は`「16x16」`と`「32x32」`を選択しました。

# ファビコンの設定

最後に作成したファビコンをアプリに設定していきます。

まず先程ダウンロードしたファビコンをアプリ`imagesフォルダー`下に配置します。

```
assets/assets/images/favicon.ico
```

次に配置したファビコンを読み込ませます。

```html:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
<!-- 省略 -->
    <%= favicon_link_tag('favicon.ico') %>
<!-- 省略 -->
  </head>
<!-- 省略 -->
```

これで、ファビコンの設定ができました！

# 確認

以上で設置できたはずなので、サーバーを起動し確認してみてください！

# 最後に

以上でファビコンの設定は完了です。
簡単に設定できるので、ぜひ試してみてください。
では。
JaveScriptのテスト「jest」を使ってみたい

# どうも、駆け出しエンジニアです

よくわからないことをとりあえずの備忘録で書いてます

今日はjsのテストをjestでやってみよう

今回はvueでモデルとしてjsを書いたのでそれのテストをしていきます

## まずはjestの追加

yarnでjestを追加していきましょー
その他諸々も

```
yarn add jest babel-jest babel-core@^7.0.0-bridge.0 @babel/core @babel/preset-env
yarn add @babel/plugin-transform-modules-commonjs
```

`.babelrc`を作成。以下を追加

```
{
  "env": {
    "test": {
      "plugins": [ "@babel/plugin-transform-modules-commonjs" ]
    }
  }
}
```


最前面に`__tests__`フォルダ作成
その中にテスト関数を作っていきましょ

その前にchokidarでテストを保存したら自動で実行できるようにする

```
chokidar "__tests__/*.js" "*.js" -c "yarn jest"
```



## 今回するテスト

今回やっていくテストはvueでwebサイトを作ってるんですけど、

GASを使用して、google spread sheetからデータを持ってくるときのテストです

```
/* eslint-disable no-alert, no-console, no-undef */

import { User } from "../src/model/user";

describe("gasTest", () => {
  test("findByNum", async () => {
    let user = await User.makeUser("hogehoge");
    expect(user.id).toBe("hogehoge");
    expect(user.name).toBe("hoge");
  });
});
```

一応user.jsとbase.jsも乗っけておく

```
user.js

import { Base } from "./base";

export class User {
  constructor(array) {
    this.id = array[0];
    this.name = array[1];
    this.pass = array[2];
    this.ticket = parseInt(array[3]);
  }

  static makeUser(id) {
    return Base.findOne(id).then((array) => {
      return new User(array);
    });
  }
}
```

```
base.js

import fetch from "node-fetch";

export class Base {
  static URL() {
    return "https://script.google.com  //gasのurl";
  }

  static findOne(id) {
    return fetch(this.URL() + "?id=" + id)
      .then((response) => {
        return response.json();
      })
      .then((json) => {
        return json.flat();
        //返ってきたJsonファイルの各値を、表示するために代入。
      })
      .catch((err) => {
        console.log(err);
      });
  }
}
```

これで動いたし！！大丈夫そうかな！！


よし、寝るか！！
できるだけ理屈でデザインを説明する - 大きなテキストと小さなテキストを並べる際のマージンの取り方

## これは何

- 「感覚」とか「センス」で語られがちなデザインをできるだけ理屈に基づいて説明してみる試みの記事
- 対象読者
    - これからデザインにも手を出してみたいエンジニア
    - 既にデザインもやっているけど、良い悪いの判断に自信が持てないエンジニア
- また、記事投稿イベント「[3000文字Tips - 知ると便利なTipsをみんなへ届けよう](https://qiita.com/official-events/d523df99d6479293ffa7)」への投稿記事でもあります

## 大きなテキストと小さなテキストを並べる際のマージンの取り方

ページのメインビジュアルで、なんとなくこんなレイアウトを見る機会は多いのではないでしょうか。

![Good.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/1723834d-5856-8d97-ce85-695c913bf111.jpeg)

それっぽさを出すために多少飾り付けの要素もつけていますが、説明するのは中央にある以下の2文のマージンの取り方です。

- `大きなテキスト、続く小さなテキスト。`
    - 以下`大テキスト`と表記します
- `ふたつを並べる際のマージンの取り方`
    - 以下`小テキスト`と表記します

### 結論

`大テキストの行間 < 大テキストと小テキストの間の余白`

になるようにレイアウトすると収まりが良い場合が多いです。
以下に2つの違いを示していますが、右はなんとなくしっくりこないのではありませんか？

| 大テキストの行間 < 大テキストと小テキストの間の余白 | 大テキストの行間 > 大テキストと小テキストの間の余白 |
| --- | --- |
| ![Good.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/09ee88a1-a30b-8922-6fd8-e6bf987c533f.jpeg) | ![Not so good.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/c74122fe-7f3e-bc70-23bf-bb808b40b6cc.jpeg) |


次から詳しく説明していきます。

### ゲシュタルトの法則（近接）

ゲシュタルトの法則とは、人間がものを見るときの見方についての法則です。
無意識のうちにかかるバイアスのようなもので色々な種類があります。

今回マージンを理解するには`近接`の法則が鍵を握ります。

近接とは「距離が近いものは同じグループに感じる」仕組み。
逆に言えば、距離が遠いと違うグループに感じてしまいます。

上で示していた大テキストは、1文で1つの意味の塊です。当たり前ですね。
ですが「1つの意味の塊」であるはずの大テキストの行間の高さよりも、大テキストと小テキストの距離が近いと「見た目上のグループと意味上のグループ」が食い違ってしまいます。

そのため`大テキストの行間 < 大テキストと小テキストの間の余白`となるように余白をとってあげるとしっくり来る場合が多いです。

### 具体的な計算

行間を求める式は以下です。

```
(font-size * line-height) - font-size
```

例で出したものはfont-sizeが96pxでline-heightが1.4なので、行間の高さは38.4pxです。

```
(96 * 1.4) - 96 = 38.4
```

というわけで、大テキストと小テキストの余白は39px以上に設定してあげるとおよそ良い具合になります。

この数値が分かれば小テキストに`margin-top: 40px`とでもつけてあげれば、フォントや文字数が違ってもそれなりにしっくり来る見た目になるはずです。[^1]

[^1]: 厳密に言えば大テキストはline-heightがかかっている分余白を持っているため、馬鹿正直に`margin-top: 40px`をかけると実測では50~60pxくらいの距離の余白ができてしまいます（実測値はフォントによって変わる）。ですが、`大テキストの行間 < 大テキストと小テキストの間の余白`になっているので大きく気にする必要はありません。
vueのeslintとかprettierの設定をしよう！！

vueでwebサイトを作っていくよ

備忘録としてだから、気にせず書いていこう


## まずはvueをcreateするよ

```
vue create hoge
```

その後の設定は以下

```
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Linter
? Use history mode for router? (Requires proper server setup for index fallback 
in production) Yes
? Pick a linter / formatter config: Prettier
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In package.json
? Save this as a preset for future projects? No
```


## eslintとかの設定を頑張ろう

eslintの設定を変えていく

```
yarn eslint --init

yarn run v1.22.10
? How would you like to use ESLint? To check syntax and find problems
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? Vue.js
? Does your project use TypeScript? No
? Where does your code run? Browser
? What format do you want your config file to be in? JavaScript
The config that you've selected requires the following dependencies:

eslint-plugin-vue@latest
? Would you like to install them now with npm? Yes
```

よくわからなかったけど、下の記事を参考にしました
最初の初期設定でpackage.jsonに設定を書く。みたいな設定にしちゃったけど大丈夫かな笑
[PrettierとESLintをVSCodeで使う（Vue）](https://qiita.com/kokogento/items/b939fc3664d46b724d3e)

記事通り.eslintrc.jsに追加
ちょっとエラー出ちゃったので、そこだけ変えました

```
module.exports = {
    env: {
        browser: true,
        es6: true,
    },
    extends: [
        "eslint:recommended",
        "plugin:vue/essential",
        "plugin:prettier/recommended",
    ],
    globals: {
        Atomics: "readonly",
        SharedArrayBuffer: "readonly",
    },
    parserOptions: {
        ecmaVersion: 2018,
        sourceType: "module",
    },
    plugins: ["vue", "prettier"],
    rules: {
        "prettier/prettier": "error",
    },
};

```


記事ではprettierrcにも追加しているけど、今回はしない


.vscodeのsetting.jsonに以下を追加

```
{
    "workbench.colorTheme": "Default Light+", //ワークベンチのテーマ デフォルトの白
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true,
        "source.organizeImports": true,
        "source.fixAll": true
    },
    "editor.formatOnPaste": false,
    "editor.formatOnSave": false,
    "editor.formatOnType": true,
    "eslint.validate": ["javascript", "javascriptreact", "vue", "typescript"],
    "vetur.format.defaultFormatter.css": "prettier",
    "vetur.format.defaultFormatter.scss": "prettier",
    "vetur.format.defaultFormatter.html": "prettier",
    "vetur.format.defaultFormatter.js": "prettier-eslint",
    "vetur.format.defaultFormatter.ts": "vscode-typescript",
    "vetur.validation.template": false
}
```



## 設定完了！！

おお、、これらをやったらいい感じにeslintも動くし、色とかもいい感じだ！！
あとは、eslintignoreとか今度作ろうかな
WSLを有効化して docker run hello-world のエラーを解消した 

# 経緯
先日、「Docker-Desktop」をインストールした際に、初歩の初歩である「docker run hello-world」コマンドでエラーが発生し、先に進めなくなってしまいました。

当時の自分と同じくパニックになった方や、自分への備忘録のためとして残しておきたいと思います。
# エラーの内容
```
> docker run hello-world
docker: error during connect: This error may indicate that the docker daemon is not running.: Post "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/create": open //./pipe/docker_engine: The system cannot find the file specified.
```

# 【原因】WSLの有効化がされていない

端的に自分の場合の原因は、「WSLが有効化されていないこと」でした。
お急ぎの方は下のリンクから参照ください。

* [WSLの有効化手順](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#manual-installation-steps)

# WSL とは
WSL とは「Windows Subsystem for Linux」の略称で、
大雑把に言えば`「Windows上で動くLinux」`のことのようです。

# WSL有効化の手順 ①PowerShellでコマンド実行
WSLを有効化するためには PowerShell でコマンドを実行する必要があります。
「<font color="Lime">Ctrlキー</font>」と「<font color="Lime">Rキー</font>」を同時に押してください。

![スクリーンショット (46).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1631699/79f2fc95-ba09-0b64-4b78-de0073782dc6.png)

「名前(O):」のところに`「powershell」`と入力して OK を押します。

PowerShellの青い画面が開いたら、以下のコマンドを実行してください。

```
PS> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

続けて、以下のコマンドを実行してください。

```
PS> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```


※ここでエラーが発生すると、<font color="Red">バージョンがWSLに対応していない可能性</font>があります。
[こちら](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-2---check-requirements-for-running-wsl-2)のサイトで確認をしてください。

# WSL有効化の手順 ②最新のパッケージをダウンロード
以下のリンク先から最新のパッケージをダウンロードします。
ダウンロードしたら、パッケージをダブルクリックして実行してください。

* [x64 マシン用 WSL2 Linux カーネル更新プログラム パッケージ](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package)

# WSL有効化の手順 ③WSL2を既定のバージョンとして設定する
PowerShellで以下のコマンドを実行してください。

```
PS> wsl --set-default-version 2
```

# WSL有効化の手順 ④docker run hello-worldの実行
お気に入りのターミナルで以下のコマンドを実行してください。

```
> docker run hello-world
```

`「Hello from Docker!」と表示されれば成功です！

# その他の原因
「docker-users」というユーザがwindowsに登録されていないからという場合もあるようです。
参考サイトを併せて記載します

* [Docker for WindowsをWindows10Proにインストールする](https://blog.saboh.net/dockerforwindows/)

# おわりに
Docker を入れるだけ入れてみようと考えたら、エラー対処に相当時間を食われました...。
しかもHello-World...。

落ち込んでいる暇があれば共有して同じ失敗を減らそうと考えて投稿させていただきました。
誰かの助けに少しでもなれば幸いです。
読んでいただき、ありがとうございました。
Twitter ( [ITの虫](https://twitter.com/IT_no_mushi) ) のフォローもぜひよろしくお願い致します。

# 参考文献
* [Windows 10 用 Windows Subsystem for Linux のインストール ガイド](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#manual-installation-steps)
paypal-WooCommerceについて


# paypalとWooCommerceの構成について

基本は公式ページを見て最新を確認する必要がある。

Paypalは本番とテスト環境がある。

テスト環境はsandboxという。
設定したらお金持ちになれる。
Seller側のアカウントとBuyer側のアカウントを作れば、色んなテストができる。
Stripeも同じようなことができるが、Square決済ゲートウェイはテストの機能がない。


Create Accountの部分をクリックしたらテスト用のアカウントを作る画面へ遷移できる。
基本は英語だし、検索にひっかりにくいようなドキュメントになってる。GCPも似たような感じ。
公式ページをしっかり、ゆっくり読むのが大事。
https://developer.paypal.com/docs/api-basics/sandbox/accounts/

APIキーとPayPal ID トークンは設定すること。
登録しないと一発で支払い完了しないで、支払い承認待ち(保留)のステータスで止まる。
https://japacart.com/documentation/wc-settings/woocommerce-checkout/paypal/settings/
UIButtonの重複タップを回避する

##UIButtonを連打
UIButtonを連打すると処理を複数回行ってしまう事象が発生してしまいました。
ユーザーに重複タップさせたくない。。。

結論から言うと一回押したら押せなくしてしまえばよいです。

```
ボタンをタップした
↓
処理を行う
```

の流れを

```
ボタンをタップした
↓
ボタンをタップできなくする
↓
処理を行う
```
にすればよいです
isEnabledでボタンを非活性化してあげます
なので

```swift
@IBOutlet weak var Button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tapButton(_ sender: Any) {
        Button.isEnabled = false
        //処理を記述
        }
    }
```
上のようにすればボタンタップ後、すぐにボタンが非活性化しているので
連打して重複処理が起こらずに済みます。

しかし、タップ後他画面へ遷移していれば良いですが
同じ画面表示だといつまで経ってもボタンがタップできないままになってしまいます。

一定時間経過後にボタンを活性化させてあげます。

```swift
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    Button.isEnabled = true
}
```
これは「1秒後にボタンを活性化する」という処理になります。
最終的に

```swift
@IBOutlet weak var Button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func tapButton(_ sender: Any) {
        Button.isEnabled = false
        //処理を記述
        DispatchQueue.main.asyncAfter(deadline: .now() + 1){
           Button.isEnabled = true
        }
    }
```
これで、ボタン連打で重複処理してしまうことを回避できます。
Lambdaトリガー「Kinesis」にある再試行(Retry attempts) パラメタ が「-1」の場合どういう挙動をするか

## 内容

Lambda関数のトリガーの1つに「Kinesis」がある.

「Kinesis」を選択した場合, 関数がエラーを返すときに再試行する最大回数を指定する "再試行(Retry attempts) パラメタ" を指定することが出来る.

このパラメタを明示的に設定しない場合,「-1」が設定される.

「-1」が設定された際の挙動が知りたい.

![スクリーンショット 2021-06-11 011645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277804/72a76b57-bc47-bf4e-75e9-23c0ad7afd9b.png)


## 結論

レコードの期限が切れるまで無限回再試行される.

> (Streams only) Discard records after the specified number of retries. The default value is infinite (-1). When set to infinite (-1), failed records are retried until the record expires.

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-eventsourcemapping.html#cfn-lambda-eventsourcemapping-maximumretryattempts
replaceAll()がJSに実装されてたのに、自分のバージョンが上がってなかったことに気付いた話

# はじめに
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll

JavaだとreplaceAllがあったので、特に困ったことがなかったですが
JavaScriptにはなかったので、文字列内で該当する全てを置換する際、ヒトクセ必要でした。

最近になってES12でreplaceAll()が使える様になったことを知ったので試してみました。
初投稿なので、優しくしてください。

とりあえず、私の環境(Mac:Chrome, FireFox, Safari どれもさっき更新しました。 と Node.js v15.14.0)は元気に↓動いてます。

# やってみた。
### 古の技術
<pre>
let str = 'いっぱい置換しろ〜〜〜なんとしても置換しろ〜〜〜頑張って置換しろ〜〜〜';
str = str.split('しろ〜〜〜').join('してくれてありがと♪♪♪');

console.log(str);
 => いっぱい置換してくれてありがと♪♪♪なんとしても置換してくれてありがと♪♪♪頑張って置換してくれてありがと♪♪♪
</pre>

### lodashで同じこと書いてみる。
<pre>
let str = 'いっぱい置換しろ〜〜〜なんとしても置換しろ〜〜〜頑張って置換しろ〜〜〜';
str = _.join(_.split(str, 'しろ〜〜〜'),'してくれてありがと♪♪♪')

console.log(str);
 => いっぱい置換してくれてありがと♪♪♪なんとしても置換してくれてありがと♪♪♪頑張って置換してくれてありがと♪♪♪
</pre>

### ES12
<pre>
let str = 'いっぱい置換しろ〜〜〜なんとしても置換しろ〜〜〜頑張って置換しろ〜〜〜';
str = str.replaceAll('しろ〜〜〜', 'してくれてありがと♪♪♪');

console.log(str);
 => いっぱい置換してくれてありがと♪♪♪なんとしても置換してくれてありがと♪♪♪頑張って置換してくれてありがと♪♪♪
</pre>

### 正規表現もいける口(どうせ中身は呪文なので一切使わない。)
<pre>
let str = 'いっぱい置換しろ〜〜〜なんとしても置換しろ〜〜〜頑張って置換しろ〜〜〜';
str = str.replaceAll(/しろ〜〜〜/g, 'してくれてありがと♪♪♪');

console.log(str);
 => いっぱい置換してくれてありがと♪♪♪なんとしても置換してくれてありがと♪♪♪頑張って置換してくれてありがと♪♪♪
</pre>

~~いつも通りIEは置き去りの様でした。~~

# おしまい
ちなみに「え？いつから？」ってなったので、こちらのページにリンクを貼ったGitHubのドキュメント更新履歴追いました。
結果ボリュームが多かったので、そんな細かいことは気にしたら負けだな。という結論に至ってます。

とても小さなことですが`split + join`で、えっとコレで分けて繋げて・・・
ってコードから`replaceAll`で、あ〜全置換ね。と言葉として直感的に理解しやすくなるんじゃないかと思います。

ただ、フロントエンドで上記の様な文字列操作を行うことは個人的にはあまり好きではないので
できればバックエンドに実装したいです。 ^ ^

## 追記 6/13
@ij9tf様よりコメントをいただきましたので、修正しました。
御覧の通り私は正規表現が苦手です。
Pythonでdatetimeをimportするスタイルについて調査した

# はじめに
Pythonでdatetimeモジュールをインポートする際に、Webで調べてみると様々なスタイルでインポートされていることが分かります。

```python:様々なスタイルでのdatetimeモジュールのインポート例
import datetime
import datetime as dt
from datetime import datetime, timedelta, ...
from datetime import datetime as dt
```

これは、

- `import numpy as np`や`import pandas as pd`のように、datetimeをdtと省略したい
- datetime.datetime を直接インポートしたい

といった考えによって生まれたスタイルだと思われます。

厳密には datetime と datetime.datetime は別物ですが、datetime.datetime しか使わない場合には下2行のスタイルが使われることも多いかと思います。

しかし、自身でスタイルが統一されていないと、datetime という文字を見たときに、datetime と datetime.datetime のどちらなのかややこしくなるでしょう。

そこで、自身のプロダクト開発においてdatetimeのインポートスタイルを統一したいと考え、githubの有名OSSを調べることで、一般的にどのスタイルが多く使われているのか調べてみることにしました。

# 各OSSの調査方法

今回は、githubでスター数の多いPythonレポジトリを参考にして、それぞれどのようなスタイルでdatetimeをインポートしているのか確認していきます。

https://github.com/search?l=Python&q=stars%3A%3E1&s=stars&type=Repositories
こちらのページの上からそれぞれのレポジトリで `import datetime` で検索して確認していきます。

# 調査結果

datetimeをインポートしているOSSについて、そのスタイルをまとめました。
ついでに、Python公式Docsについても調べてみました。

| | import datetime | import datetime as dt | from datetime import datetime | from datetime import datetime as dt |
| --- | --- | --- | --- | --- |
| [docs.python.org](https://docs.python.org/ja/3/library/datetime.html?highlight=import%20datetime#datetime.datetime.isoformat) |||◯||
|[TheAlgorithms/Python](https://github.com/TheAlgorithms/Python/search?q=import+datetime)|||◯||
|[jackfrued/Python-100-Days](https://github.com/jackfrued/Python-100-Days/search?q=import+datetime)|◯||◯||
|[ytdl-org/youtube-dl](https://github.com/ytdl-org/youtube-dl/search?q=import+datetime)|◯||||
|[tensorflow/models](https://github.com/tensorflow/models/search?q=import+datetime)|◯||◯||
|[nvbn/thefuck](https://github.com/nvbn/thefuck/search?q=import+datetime)|||◯||
|[django/django](https://github.com/django/django/search?q=import+datetime)|◯||◯||
|[pallets/flask](https://github.com/pallets/flask/search?q=import+datetime)|◯||◯||
|[httpie/httpie](https://github.com/httpie/httpie/search?q=import+datetime)|||◯||
|[ansible/ansible](https://github.com/ansible/ansible/search?q=import+datetime)|◯||◯||
|[huggingface/transformers](https://github.com/huggingface/transformers/search?q=import+datetime)|◯||◯||
|[scikit-learn/scikit-learn](https://github.com/scikit-learn/scikit-learn/search?q=import+datetime)|||◯||

# 学んだこと
実際にOSSを調べてみたことで、以下の点について学ぶことができました。

- ほとんどのOSSが `from datetime import datetime` を採用している
- - Python公式Docs、scikit-learnなどは `from datetime import datetime` の形式のみを採用している
- `import datetime` と `from datetime import datetime` が混在しているOSSも多い
- `as dt` は使われていない

そこで、私自身の結論として、

- 基本的には `from datetime import datetime` のスタイルを採用する
- どうしても必要になったときには `import datetime` を使用することとする

というスタイルを採用しようと思います。

# おわりに

githubの有名OSSを調査することで、datetimeが一般的にどのようなスタイルでインポートされているか確認できました。

この調査が皆さんのプロダクト開発のお役に立てれば幸いです。
以上です。ありがとうございました。
【Php】PDOでdatabaseに接続する(3)

# 初めに
PDOについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事：
https://qiita.com/redrabbit1104/items/2668e56d4c058221388e
https://qiita.com/redrabbit1104/items/8c5bb2b364347915a0f1

# ユーザーがフォームなどを通じて入力した場合を想定
前回と同様、sql文を使ってデータベースに接続しますが、今回はユーザーがフォームからデータを入力した場合を考えます。

# sql文のplace holder
ユーザーが何を入力するか分からないので、sql文のwhere句にはplace holderを利用します。place holderには２種類があり、①名前付きplace holderと②疑問符place holderがあります。

#①名前付きplace holderを使う
sql文で「:」の後ろにplace holderとして使う名前を指定します。

```php
$sql = 'select * from accounts where user_id = :id';  //名前付きplace holder
```
それから、sql文を実行する準備をするprepare関数を使います。戻り値はステートメントになります。

```php
$stmt = $pdo -> prepare($sql);     //sql文を実行する準備を行う。戻り値はPDOStatement
```
PDOStatementのbindValue関数を使い、place holderと値を紐付けます。
3番目の引数にはPDO::PARAM_INTのように値の型を指定します。こちらはPHPで予め用意されている定数を使います。

https://www.php.net/manual/ja/pdo.constants.php

```php
$stmt -> bindValue('id', 4, PDO::PARAM_INT); 
```
紐付けの方法にはこの他にbindParam関数を使う方法もあります。

https://www.php.net/manual/ja/pdo.constants.php
最後にexecute()関数を使って実行します。

```php
$stmt -> execute(); //実行
```
結果を表示させるためにfetchall()関数で該当するデータを全て取得します。

```php
$result = $stmt -> fetchall();
```
連想配列という形で格納されているので、var_dump()で中身を確認できます。

```php
var_dump($result);
```
![スクリーンショット 2021-06-10 7.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/c45c06c7-8f33-3efc-fada-b80afdbbf726.png)

#②疑問符place holderを使う
基本的には名前付きplace holderと同じですが、place holderとして「?」を使います。

```php
$sql = 'select * from accounts where user_id = ?'; //疑問符place holder
```
また、bindValue()関数を使う際に、第一引数として1から始まる番号を振ります。今回はwhere句でuser_idしかカラムがないので、そのまま1を代入します。

```php
$stmt -> bindValue(1, 1, PDO::PARAM_INT);   //値の紐付け
```
その他は名前付きplace holderと同じなので割愛します。
![スクリーンショット 2021-06-10 7.43.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/6e05816d-8688-e776-87aa-46b1d37fe0de.png)

# 参考サイト
https://www.php.net/manual/ja/class.pdo.php
https://www.php.net/manual/ja/pdo.prepare.php
https://www.php.net/manual/ja/pdostatement.bindvalue.php
https://www.php.net/manual/ja/pdostatement.bindparam.php
https://www.php.net/manual/ja/pdostatement.fetchall.php
https://www.php.net/manual/ja/pdostatement.execute.php
https://qiita.com/mpyw/items/b00b72c5c95aac573b71
Docker 環境で動作する Vue に Vuetify のアルファ版を追加する

この記事の執筆時点で、Vue 3 に対応した Vuetify はまだアルファ版です。
https://vuetifyjs.com/ja/introduction/roadmap/

リリース目標は 2021 年の Q3 らしいですが、待ちきれないので、現時点で公開されているアルファ版を入れてみました。

# 単純に add するだけ
すでに vue-cli で Vue 3 のプロジェクトがある前提で、次のコマンドを実行します。

```
$ docker-compose run vue vue add vuetify
```

ちなみに、上記コマンドの意味は**「docker-compose.yml でサービス名が『vue』と定義されたコンテナに『vue add vuetify』というコマンドを実行させる」**です。
（なので「vue vue」と重複しているのは typo ではありません）

実行すると「どの vuetify を入れるんだよ😒」と聞かれるので「V3 (alpha)」を選択します。

すると、、、

```
? Choose a preset: V3 (alpha)

🚀  Invoking generator for vue-cli-plugin-vuetify...
📦  Installing additional dependencies...


added 3 packages in 8s
⚓  Running completion hooks...

✔  Successfully invoked generator for plugin: vue-cli-plugin-vuetify
 vuetify  Discord community: https://community.vuetifyjs.com
 vuetify  Github: https://github.com/vuetifyjs/vuetify
 vuetify  Support Vuetify: https://github.com/sponsors/johnleider
```

……と追加完了します。

# 確認

```package.json``` を確認すると、vuetify 3 のアルファ版が追加されています。

```package.json
  "dependencies": {
    "@mdi/font": "5.9.55",
    "core-js": "^3.6.5",
    "roboto-fontface": "*",
    "vue": "^3.0.0",
    "vue-router": "^4.0.0-0",
    "vuetify": "^3.0.0-alpha.0",  // ←追加されてる
    "vuex": "^4.0.0-0"
  },
```

それから、ちょいちょいファイルが書き変わってますね。
こんな感じで。

```javascript:main.js
import { createApp } from 'vue'
import vuetify from './plugins/vuetify'  // ←追加
import App from './App.vue'
import router from './router'
import store from './store'

const app = createApp(App)
app.use(router)
app.use(store)
app.use(vuetify)  // ←追加

app.mount('#app')
```

うーん、それにしても、入れたはいいが使い方がよく分からん😂
HTML、CSS学び始めメモ

#学習の経緯
非web系のシステム開発がメインだったが、昨年からsalesforceを始める。
Platform Developer Iの資格はとれたもののフロントエンド側はサッパリ
LWC（Lightning Web コンポーネント）に興味がでてきたが、
それを理解する為の前提となるjavascriptも解らないし、htmlも解らない。
そのため基礎の基礎を学習するに至る

###現状の知識レベル
**html**
h1タグは見出しで使う、pタグは何かメッセージ書くとき使う。
frameタグやtableタグは知っている。
アクセスカウンターとかキリ番ゲットとかの時代止まり…

**css**
デザインセンスが必要で極めるとお洒落なサイトを作れるモノ。
###今回のゴール
htmlとcssを使ったwebサイトの構成の触り理解する。

###HTMLでわかったこと
<dl>
<dt>div</dt>
<dd>
区切りタグ<br>
画面構成の枠として使用し要素をまとめて構造化する。
これ自体が何かすることは無く、構造化のための目印的な使い方をする。
</dd>
</dl>
<dl>
<dt>ul</dt>
<dd>
リストタグ<br>
cssのfloatと組み合わせて要素を横並びに表示する時にたくさん使う。<br>
テキスト以外にこの中にdivタグで囲った構成要素を作り、左に画像、右にテキストといったレイアウトを作ったりできる。<br>
デフォルトでは中点が表示されるので、list-style-type属性にnoneを設定し中点を非表示にすることで只の箇条書き用のタグが素敵デザインのためのタグになる。
</dd>
</dl>

```html:ulタグの使用例
<ul>
  <li>文章１</li>
  <li>文章２</li>
</ul>
```

<dl>
<dt>dl</dt>
<dd>
説明タグ<br>
前述のulタグと異なり子要素タグの、用語「dt」とその説明「dd」の組み合わせで使う。<br>
ulタグ同様にlist-style-type属性にnoneを設定して使う。</dd>
</dl>

```html:dlタグの使用例
<dl>
  <dt>概要１</dt>
  <dd>説明文</dd>
  <dt>概要２</dt>
  <dd>説明文</dd>
</dl>
```

<dl>
<dt>img</dt>
<dd>
画像タグ<br>
画像を表示する時に使用する。<br>
ファイルの指定は相対パス。<br>
alt属性は画像が表示出来ない場合に設定したテキストを表示するのに使われる。<br>
自動読み上げソフトで読まれる場合があるので適切な内容にすることが望ましい。</dd>
</dl>
<dl>
<dt>h1～h6</dt>
<dd>見出しタグ<br>
それぞれ文字の大きさが異なり、h1が一番大きくh6が一番小さい。</dd>
</dl>
<dl>
<dt>p</dt>
<dd>パラグラフ（段落）タグ<br>
文章の段落の纏まりを表す。<br>
pタグの前後には1行改行が自動で入る
</dd>
</dl>

###CSSでわかったこと
cssは、htmlで作られた骨組みを彩る装飾品
文章（html）と装飾（css）に分離する方がデータ構造的に何かと都合がよい

**書き方１**
`要素{プロパティ名:値;}`
htmlタグに対して定義した内容は、そのcssファイルを参照するhtmlファイル内全てに作用する。
これによりタグに対し同じ内容の設定を個々にするより外部化した定義を参照する方が効率的となる。

```css:タグに対する定義例
ul, dt, dd {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
```

**書き方２**
`.クラス名{プロパティ名:値;}`
クラス名として定義すると、そのクラスを指定した箇所のみに作用する。
定義する時は、先頭にピリオド「.」を付ける。

```css:クラスとしての定義例
.content{
  width: 900px;
  float: left;
}
```

```html:指定方法
<ul class="content">
  <li>テキストメッセージ１</li>
  <li>テキストメッセージ１</li>
</ul>
```

###終わりに
今回は道具とその使い方が（なんとなく）解った。
次回はもう少し踏み込んで学ぼうと思う。