OmniAICreator/Qiita-1.07M huggingface dataset:
[SwiftUI] iOS13でObservableObjectをインスタンス化する方法

# Problem

iOS14からは `@StateObject` が使えるので、Viewの中でObservableObjectをインスタンス化させることができます。

```LibraryView.swift
struct LibraryView: View {
    @StateObject var book = Book()
    
    var body: some View {
        BookView(book: book)
    }
}
```

参考: [Instantiate a Model Object in a View](https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app)

ただ、iOS13では`@StateObject`が使えないので、別の方法を考える必要があります。

# Solution

Stackoverflowに解決策を書いている人がいました。
https://stackoverflow.com/a/62007843


親のView(LibraryView)で `@State` でObservableObjectをインスタンス化し、子View(LibraryViewImpl)に渡すようにすれば良さそうです。


```LibraryView.swift
struct LibraryView: View {
    @State var book = Book()

    var body: some View {
        LibraryViewImpl(book: book)
    }
}

private struct LibraryViewImpl: View {
    @ObservedObject var book: Book

    var body: some View {
        BookView(book: book)
    }
}
```

# 参考

- [SwiftUIのデータ管理 Property Wrapper編
](https://blog.personal-factory.com/2021/01/23/how-to-use-propertywrapper-in-swiftui/)
【GitHub】error: failed to push some refs to "URL"の対処法

#プログラミング勉強日記
2021年3月18日

#エラー内容
　GitHubにpushしようとしたときに以下のエラーが出た。

```
$ git push origin ブランチ名
To https:///githubのURL
[rejected]develop -> develop (non-fast-forward)error: failed to push some refs to 'https://githubのURL'

hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

#原因
　調べてみると、コミットする前にREADMEの変更を行っていたのが原因だった。前に一度リモートにpushした整合性がとれずにずれているのが原因みたいだった。


#解決方法

```
$ git fetch
$ git merge origin/master
```


#参考文献
[【git】error: failed to push some refs to "URL"のエラー対処法](https://qiita.com/chiaki-kjwr/items/118a5b3237c78d720582)
[git push 時の　error: failed to push some refs to](https://qiita.com/yoshixj/items/6441ab2cd6bc367e607d)
FlaskでMarkdownを表示する方法

# コード内に埋め込み
- server.py

```
from flask import Flask, render_template, Markup
from markdown import markdown

app = Flask(__name__)

@app.route('/index')
def show_md():
  md = '#Hoge'
  md = Markup(markdown(md))
  return render_template('index.html', md=md)

if __name__ == '__main__':
  app.run(host='127.0.0.1', port=5500, debug=True)
```
- index.html

```
<body>
  {{ md }}
</body>
```
- markdownモジュールと`Markup`オブジェクト組み合わせることでhtmlにレンダリングできます。

# Markdownファイルから読み込み
- main.md

```
# Hoge
- piyo
```
- server.py

```
from flask import Flask, render_template, Markup
from markdown import markdown

def read_md() -> str:
  with open('./main.md', mode='r') as mdfile:
    mdcontent = mdfile.read()

  return Markup(markdown(mdcontent))

@app.route('/')
def index():
  content = read_md()
  return render_template('index.html', md=md)

if __name__ == '__main__':
  app.run(host='127.0.0.1', port=5500, debug=True)
```
- index.html

```
<body>
  {{ md }}
</body>
```
- `read_md`メソッドでmarkdownファイルの文字列を読み取り、`Markup`オブジェクトでhtmlにレンダリングするようにします。
[入門]PHPの文法メモ

初めてPHPに触れてみたのでメモを残しておきます。

```php
<?php
// Your code here!
    $var = "abc";
    var_dump($var);//型を調べることができる
    $a = [
        'a' => 'apple',
        'b' => 'banana'
    ];
    echo $a['b'].PHP_EOL;
    
    $arr = [1, 2, 3, 4];//配列
    $x = count($arr);//要素数を返す
    echo (string)$x.PHP_EOL;
    
    $z = add(1, 2);//関数本体が下にあっても実行可能
    echo (string)$z.PHP_EOL;
    function add($x, $y)
    {
        $z = $x + $y;
        return $z;
    }
    
    class Car {
        private $name;
        private $speed;
        
        public function __construct($name, $speed) { //デフォルトのコンストラクタの上書き
            $this->name = $name;
            $this->speed = $speed;
        }
        
        public function move() {
            echo "{$this->name}は{$this->speed}キロで走ります".PHP_EOL; 
        }
    }
    $car = new Car('prius', '60');//コンストラクタの呼び出し
    $car->move();//メソッド呼び出し
?>
```

```
(出力)
string(3) "abc"
banana
4
3
priusは60キロで走ります
```

・変数には'$'をつける
``$var = 1``

・デバッグ用に型を調べられるvar_dump()がある
``var_dump($var)``

・文字列の結合は'.'でできる
``'文字列１'.'文字列2'``

・連想配列の例
``$array = ['apple' => 'りんご', 'banana' => 'バナナ'];``

・添字配列の例
``$array = [1, 2, 3, 4];``

・クラスについては他の言語と似たような使い方


参考：https://youtu.be/HNHjpmdPFNU
circleci/mysql:5.7.33 を動かす

# MySQLが動かない...!
ある昼下がり、ジョブが失敗している。。。
MySQLの起動に失敗したようだ。

手元で起動してみると確かに動かない。

```bash
docker run -it --shm-size=1gb -e MYSQL_ROOT_PASSWORD=secret circleci/mysql:5.7.33
#2021-03-18 10:06:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.33-#1debian10 started.
#2021-03-18 10:06:33+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
#2021-03-18 10:06:33+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.33-1debian10 started.
#2021-03-18 10:06:33+00:00 [ERROR] [Entrypoint]: MYSQL_USER="root", MYSQL_PASSWORD cannot be #used for the root user
#    Use one of the following to control the root user password:
#    - MYSQL_ROOT_PASSWORD
#    - MYSQL_ALLOW_EMPTY_PASSWORD
#    - MYSQL_RANDOM_ROOT_PASSWORD
```

# 実験
## 公式のイメージを動かしてみる

```bash
docker run -it --shm-size=1gb -e MYSQL_ROOT_PASSWORD=secret mysql:5.7.33
```

動いた。rootでも疎通できる。

## 環境変数を比べる
どうやら公式は　`MYSQL_USER=root` を使わずとも root を作成するらしい。
そして、 `circleci/mysql` は勝手に `MYUSQL_USER=root` を行っているようだ。

```bash
docker run -it --shm-size=1gb  mysql:5.7.33 env
#MYSQL_MAJOR=5.7
#HOSTNAME=c8102f95becf
#PWD=/
#HOME=/root
#MYSQL_VERSION=5.7.33-1debian10
#GOSU_VERSION=1.12
#TERM=xterm
#SHLVL=0
#PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

```bash
docker run -it --shm-size=1gb  circleci/mysql:5.7.33 env
#MYSQL_MAJOR=5.7
#MYSQL_ALLOW_EMPTY_PASSWORD=true
#HOSTNAME=7ab057cc816f
#PWD=/
#MYSQL_USER=root
#HOME=/root
#MYSQL_VERSION=5.7.33-1debian10
#GOSU_VERSION=1.12
#MYSQL_HOST=127.0.0.1
#TERM=xterm
#MYSQL_ROOT_HOST=%
#SHLVL=0
#MYSQL_DATABASE=circle_test
```

## `MYSQL_USER=root` がユーザ作成のコンフリクトを起こしている説
以下を実行すると `cicrcleci/mysql` と同様の事象が起きた。
TODO: error ログを読む。
 
```bash
docker run -it --shm-size=1gb -e MYSQL_USER=root -e MYSQL_ROOT_PASSWORD=secret mysql:5.7.33
```

## `MYSQL_USER` を空にすれば回避できるのでは...?
動いた...!

```bash
docker run -it --shm-size=1gb -e MYSQL_USER=  -e MYSQL_ROOT_PASSWORD=secret circleci/mysql:5.7.33
```


# おわり
`MYSQL_USER` を空にしたら動きますね。
【基礎】Salesforceについて

#**まずSalesforceを学ぶ前に知っておくべき３つのこと**
○クラウドサービス
○CRM
○プラットフォーム

##**クラウドサービスについて**
インターネットを通じてサービスを提供しているシステムのこと。
「クラウド」を和訳すると「雲」となりますが、インターネット上には色々なサービスが浮いていて、そのサービス達を雲と称し「クラウドサービス」と呼んでいる。
※個人的なイメージです。

代表的なサービスといえば「gmail」「Office365」「iCloud」「オンラインゲーム」...etc
今回メインとなる「Salesforce」もこの中の一員だと考えます。

##**CRMについて**
消費者のニーズに合わせたサービスを提供する経営コンセプトのこと。
フルネームで「Customer（顧客） Relationship（関係） Management（管理）」
一般的に「顧客管理」と呼ばれている。<br>
例えばどのようなサービスがあるか・・・
・顧客情報を管理しニーズを把握する
・自動送信メールやランク付け等などの顧客へのアクション
・顧客獲得のためのやりとりなどを履歴に残し常に確認できるようにする...etc

##**プラットフォームについて**
システムを利用するための環境のこと。※「platform」を和訳すると「プラットホーム」となりますがここではどちらの呼び方が正しいとかは気にしないで進めます。

基本的には「共通の土台（基盤）となる標準環境」を指すようです。

例えばソシャゲやりたい！と思ったとき、その為には「iOS」や「Android OS」といった環境が必要です。その「OS」こそが「プラットフォーム」だというイメージです。

##**セールスフォースとは結局なにか**
上記で知っておくべきこと３つ学びましたが、まさにその３つを掛け合わせたものであり
__「インターネット上で利用でき、CRMのプラットフォームを提供するクラウドサービス」__
のこと

##参考元##
全体的に

https://keneloper.com/what-is-salesforce-2/#Salesforce


https://trailhead.salesforce.com/ja/content/learn/modules/admin_intro_crm_basics/admin_intro_getstart_crm_basics?trail_id=getting_started_crm_basics

クラウドサービス

https://kigyolog.com/article.php?id=426#2-1

CRM

https://mba.globis.ac.jp/about_mba/glossary/detail-11629.html

プラットフォーム

https://www.keyence.co.jp/ss/general/iot-glossary/platform.jsp

そもそもOSって何

https://www.4900.co.jp/smarticle/7128/
npx create-react-app ができない！

## npx create-react-appができなくて困った

久しぶりにreactを使って、アプリを作ろうと思い、
```npx create-react-app .
```

を実行すると、
```error An unexpected error occurred: "パス名/package.json: Unexpected end of JSON input".
```

上記のエラーが発生。

### 解決策
package.jsonがディレクトリ内にあったのが問題だった。
完全に見落としていました。
Git~バージョン管理~

それでは、Gitを使ってバージョン管理をしていきましょ！
ちょ、Gitどうやってアカウント作るのって方は公式をみて作ってみてください😅👍
▶https://git-scm.com/book/ja/v2/GitHub-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E6%BA%96%E5%82%99%E3%81%A8%E8%A8%AD%E5%AE%9A

では、バージョン管理をしてきましょう！！
まず最初に、フォルダを作っていきます。CUIを使って作って行きたいとおもいます。わからない方は▶https://qiita.com/akari_0618/items/f2e8dd1deacd330cdf66

```
% mkdir app_practice　フォルダを作ります。
% cd  app_practice　　移動します。
% vim lebel3.html　　　ファイルを作ります。
% cat lebel3.html    中身をみます。
```
フアイルの内容は今回適当に書いたとします。
![スクリーンショット 2021-03-18 18.36.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/ddb66d03-506a-9b92-8d14-fd77487009ab.png)
*vim index.htmlをコマンドで打ったあと
![スクリーンショット 2021-03-18 18.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033397/22495ecb-0bad-e263-5c78-ac546741d3af.png)
こーゆー画面になります。え、打てないよ。。って思いますがesc押して、:wqを押すと保存されます。

ここまでが第1段階です👍

次が第２段階になります。

```
% git add lebel3.html ステージングエリアに上げるコマンドです。
% git commit　　　　　　追加、変更をしたファイルをGitに上げるコマンドです。
% git log　　　　　　　　履歴をみます。保存されました。
```
が一連の流れです。
ただし、ここではまだGitにPushしなければなりません😅
選択式メニューの作成

初めましてshoです。
シェルスクリプトの学習、練習メモです。

内容***「選択式メニューの作成」***
詳細　
　・実行したら以下のメニューが表示されるようにする
　　　１）list file
　　　２）current directory
　　　３）exit
　・番号選択したらそのまま実行（Enter押さなくても実行される）
　・入力内容は非表示

（※学習記録やメモ書き目的で始めました。ほぼ初学者レベルなので理解が浅いところや誤りがあるかと思いますがよろしくお願いします。またアドバイス等コメントいただけるとすっごく嬉しいです。）

#使用コマンド
***read***　＝標準入力で受け取った内容を１行単位で変数に入れられるコマンド

###オプション
***-s*** ＝入力内容を表示させない
***-n [数字]***　＝指定した文字数分の入力を受け取ったら次の処理へ進む

→「read -s -n 1　・・・・」と記述して表示されたメニュー番号を入力したらそのままその番号が実行され、入力した番号は非表示にする


#スクリプト

```

#!/bin/sh


echo "1)list file"
echo "2)current directory "
echo "3)exit"
   
while :
 do
   read -s -n 1 var
   case "$var" in
 
  1) ls -l ;;
  2) pwd ;;
  3) exit ;;
  4) echo no found ;;

    esac
done


```

#実行結果

```

# t-menu.sh
1)list file
2)current directory 
3)exit

１を入力
↓
合計 16
-rw-r--r-- 1 root root 826  3月 16 03:08 20210316.zip
drwxr-xr-x 2 root root  19  3月 11 19:40 dir1
drwxr-xr-x 2 root root  32  3月 11 19:40 dir2
drwxr-xr-x 2 root root  19  3月 11 19:19 dir3
-rw-r--r-- 1 root root   0  3月 12 02:00 file1
-rw-r--r-- 1 root root   0  3月 12 02:00 file2
-rw-r--r-- 1 root root   0  3月 12 02:00 file3
-rw-r--r-- 1 root root 116  3月 15 03:19 ip.txt
-rw-r--r-- 1 root root 337  3月 15 01:51 ip_sample.txt
-rw-r--r-- 1 root root   3  3月 15 23:04 sshfailed
drwxr-xr-x 4 root root  53  3月 16 02:20 test2


２を入力
↓
/root/test

３を入力
↓
#　（exitを選択）
```


書いていて気がついたのですが、

シェルスクリプトでメニュー作成と検索すると「select」コマンドを使用するのが多いのですね。


簡単ではありますが、以上です！



#参照サイト

https://www.atmarkit.co.jp/ait/articles/1811/28/news003.html

https://linuxcommand.net/read/
エヴァの用語が多すぎて覚えられないので、エヴァ用語辞典Linebot作った

#概要

現在絶賛公開中の映画「シン・エヴァンゲリオン」話題になってますね。
私も劇場で二回観てきました。

映画の内容はまあ置いといて、あまりエヴァに詳しくない友人と観に行ってきたのですが、
あまりにもエヴァンゲリオンの用語が多すぎて、内容があまりわからず混乱していました。

確かにエヴァってしっかり全作観ている人でも「これってどういう意味？」と聞かれたら、
なかなか答えることが難しい作品です。（というか作品の中でもしっかり言語化されていないことも多い）

そんなエヴァンゲリオン初心者の方、もしくはエヴァンゲリオン大好きな方でもパッと用語を調べられるLineBotを作成しました。

#前提
この記事にはシン・エヴァンゲリオンのネタバレはありませんが、
開発したLinebotにはQまでのネタバレの内容も含まれております。
また、シン・エヴァンゲリオンで初めて出てきた用語については取り上げておりません。

LineBotの作り方等、技術についてはこの記事では触れません。

#内容
##QRコード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/b1528a4f-faa3-66c0-76da-9ddf514d084b.png)

こちらを読み込んでいただければ使うことができます。

##開発環境
GoogleAppsScript
GoogleSpreadSheet

サーバーレスで作りたかったのでGASを使用しました。

##機能要件
###検索機能
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/3f7cda35-5e85-5c1c-6c59-9850074f4b23.gif" width="170px">
ほぼ機能はこれだけですが、

用語を検索するとLineMessagingAPIが用語の説明を返してくれます。
部分一致にも対応しています。

用語リストは、スプレッドシートにWikipediaから用語を引っ張ってきてかたっぱしからコピペしました。（この作業が一番時間かかった）

###用語一覧表示機能
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643906/5a2686c9-4689-1c94-b341-4407e39c5ba3.gif" width="170px">
ゲンドウの顔をタップすると登録されている用語一覧を表示できます。
調べてみたい用語があったら検索できるような仕様になっています。

#まとめ
LineBot作るの五回目くらいなんですが、サーバーレスはやっぱり楽ですね。
みなさんも良いエヴァライフお過ごしください。
IPのクラスについて

#IPの表記

インターネットに接続されるコンピュータは、ユニーク（オンリーワン）なIPアドレスを必ず割り当てる必要がある。でなければ、TCP/IPで通信は行えない。

IPアドレスは、**32ビットの整数値**で表される。
コンピュータ内部では、2進数である。

しかし、人間には理解しにくく特別な表記として
8ビットずつを4組に分けて、その境目にピリオドを置いて10進数で表現する。

例.

```
10101100.00000011.000000101.00000101 ( 2進数
172     .       3.        5.       5 (10進数

IPアドレスは     172.3.5.5
```

IPアドレスで表すことのできる組み合わせは、
2^32 = 4,294,967,296通り
約43億通りあることになる。

数字上43億台のコンピュータに割り当てられる。
しかしながら、
[ネットワークインターフェース(NIC)](https://qiita.com/iyoshiha/items/cfaf984cb56d1277f8ae)ごとに割り当てるが、1つのインターフェースに複数のIPアドレスを割り当てることも可能である。
かつ、ルーターは2つ以上のインターフェースを持つため、1つのルーターが2つ以上のIPアドレスを持つことになる。

なので実際は、43億台のコンピュータにはつなぐことはできない。

![numIP.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162957/aa26d393-27b6-b77e-b4cd-15d4d5562a7f.jpeg)


##IPアドレスの構成

**ネットワークアドレス部**と**ホスト部**から構成される。

**ネットワークアドレス部**は、インターネットに接続されているすべてのネットワーク部と重ならないようにしなければならない。

**ホスト部**には、同じリンク内で重ならない値を割り当てる。

IPパケットが途中のルータで転送される時は、ネットワーク部のみ参照される。ネットワーク部を見ればどこにホストがいるかわかるからである。

##IPアドレスのホスト部とネットワーク部の分け方

2種類の区別がある。初期の方法は、クラスによって分けられていた。（クラスフル）
今は、サブネットマスクで分けられている。（クラスレス）

##IPアドレスのクラス

クラスは、A, B, C, D　の4種類がある。
このクラスによって、IPアドレスのどの部分がネットワーク部かを決めている。
先頭から4ビットのビット列の組み合わせで決められている。

クラスA
先頭１ビットが０
先頭から8ビットがネットワーク部となる。（クラス部を除くと7ビット）

クラスB
先頭2ビットが10
先頭から16ビット(クラス部を除くと14)がネットワークアドレス部となる。

クラスC
先頭3ビットが”110”
IPネットワークアドレス部は、先頭から24ビット（クラス部を除くと21ビット）

クラスD
先頭4ビットが"1110"の場合
先頭から32ビット(28)がネットワークアドレス部となる。
ﾎｽﾄ部はない。このクラスDは、マルチキャスト通信に使われる。

||先頭bit|ﾈｯﾄﾜｰｸｱﾄﾞﾚｽ部|ﾎｽﾄ部|ﾎｽﾄ数|
|---|:-|:-:|---|--:|
|A|0|8(7)|下位24ビット|16,777,214|
|B|10|16(14)|下位16ビット|65,534|
|C|110|24(21)|下位8ビット|254|
|D|1110|32(28)|------------|-----------|


##ホストアドレス割り当ての注意点

ホスト部をビットで表すとき、すべてのビットを0にすること、または、すべてのビットを1にはできない。
ホスト部のすべてのビットが0というのは、ホスト部がわからないときに使う決まりになっているからである。
また、ホスト部のすべてのビットが１の場合は、ブロードキャストアドレスとしてつかわれることになっている。

なので、ホスト部の割り当てられる数は、この2つを引いた数になる。
Ｃクラスの場合:  2^8 - 2 = 254

##ブロードキャストについて

ブロードキャスト　broadcast　とは、読んで字のごとく広く配信するということ。つまり、同一のリンク内（LAN）につながれたコンピュータすべてにパケットをおくること。

Bクラスのあるネットワーク部を持つアドレスがあるとして
そのホスト部をすべて1にすると、それはブロードキャストアドレスとして使われる。

```
10101100.00010100.00000000.00000000
10101100.00010100.11111111.11111111 (broadcast
```
10進数で表現すると以下となる。

```
172.20.255.255
```

##2種類のブロードキャストアドレス

* ローカルブロードキャストアドレス
* ダイレクトブロードキャストアドレス

ローカルは、自分が属しているリンク内のすべてのホストにパケットを送ること。
IPパケットは、ルータで遮断されるため自身のブロードキャストアドレスで設定されたネットワーク以外に情報が届くことはない。
172.20.0.0/16 (*1) に所属するコンピュータが、172.20.255.255として宛先を設定する。

ダイレクトは、自分が所属しているリンク以外のネットワークに対してブロードキャストを行う。
172.20.0.0/16から172.30.0.0/16に送るとすると
172.30.255.255として、ルータを経由してパケットを届ける。



*1 172.20.0.0/16の　"/16"というのは上位16ビットがネットワークアドレス部であることを示している。16は2バイトなので、IPが10進数表記の時、2つ目のピリオドまでがネットワーク部ということを示している。

##サブネットマスクの導入

クラスフルは、無駄がおおい。

使われない部分が多く足りなくなった。なので、サブネットマスクという識別子が導入されて、現在は、ネットワーク部、ホスト部の境目は、クラスに依存しない。


#####参考
マスタリングTCP/IP
AWS完全未経験がAWS認定クラウドプラクティショナーを28時間でとるまで

##結論
・[AWS公式のE-ラーニング][link-1]を受講する（10時間）
[link-1]:https://www.aws.training/Details/eLearning?id=66479
・[Udemyの問題集][link-2]をひたすら繰り返す(18時間)
[link-2]:https://www.udemy.com/course/aws-4260/



#はじめに
こんにちは
本記事はAWSについて何も知らなかった人がAWS認定クラウドプラクティショナーに合格するまでを記録した記事です

![スクリーンショット 2021-03-18 180531.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596309/9617d50c-dbc6-e17b-f614-929b11d9b8d6.png)


##前提
・文系卒
・新卒Sier1年目
・一応インフラ系の部署に配属されている
・オンプレなのでクラウドは言葉を知っている程度

##受験のきっかけ
~~**AWSエンジニアって給料高いやん！！とりあえず資格とったろ！**~~

##どう勉強したか
**◆[AWS公式のE-ラーニング][link-1]:AWS Cloud Practitioner Essentials**
・メリット　：無料、映像が分かりやすく面白い、イメージを掴みやすい
・デメリット：長い、試験対策としては網羅性が低い

結構ユーモラスな講座です。
一つ一つ動画で説明してくれるので各サービスのイメージを掴むのにはバッチリ
資格を受けなくてもこれだけは見てほしい
ただ全部見るのに10時間くらいかかるので、メモやノートを取りながら視聴するのがオススメ



**◆[Udemyの問題集][link-2]:【Udemy】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（7回分455問）**
・メリット　：安い(3600円、セールだともっと安い)、網羅性が高い、
　　　　　　　解説が充実、本番の試験とそっくり
・デメリット：全部終わらないと見直しが出来ない
　　　　　　　後半は難しすぎるので解く必要なし

問題は本番さながらで解説も充実しているので文句なしの問題集
迷ったらこれを買っとけと言えるレベル
ただ実際に試験対策で使えるのは65問×4回分だけなのでちょっと損した気分になる



**コツ**
・公式リファレンスを確認する
リファレンスを読むのが面倒ならサービスを紹介するページを眺めるだけでもOK
[こういうページとか][link]
[link]:https://aws.amazon.com/jp/ec2/?ec2-whats-new.sort-by=item.additionalFields.postDateTime&ec2-whats-new.sort-order=desc


・概念図を書いて整理する
サービス同士の関連性とかは図に書かないとなかなか理解できないので
ちょっとつまったらすぐに書いて整理してみるのがオススメ

##受験の感想
**割りと焦った**
問題演習を中心にやっていたので基礎的な項目の暗記が疎かだった
言うなれば「問題ごと覚えてる」状態
ただまあそれでも問題集が優秀だったので高得点にはなったのかなと…
ハンズオンとかやってればまた違ったのかなーと思いました
##まとめ
・試験合格を優先したいならとにかく問題演習
・知識、技術を高めたいならハンズオン

この資格は
**・AWSとは何か**
**・どんなサービスがあるのか**
**・何が出来て何が出来ないのか**
をとりあえず把握するのに最適だと言えます。
~~Oracleと違って~~教材は豊富で、~~Oracleと違って~~試験料も15000円ほどなので
とりあえずチャレンジしてみることをオススメします！
Amazon Lightsail + NginxでHTTP/2を有効にする 

### 本題について

Amazon LightsailでNginxを利用していますが、HTTPバージョンが1.1でした。
※以下図、ChromeのデベロッパーツールProtocolでは"http/1.1"と表示
![HTML 5 Shooting Game 2021-03-18 15-19-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130301/754229e0-eeaf-2923-797f-471a0c36dede.png)
Lightsail上でのNginxにおいて、HTTP/2のアップデート方法を検索したのですが、意外に見つからず。
学習がてらメモ要素も含みつつ、手順をここに記載します。

設定自体は大変簡単でした。

## 環境

- サーバ：AWS Lightsail（一番安い3.5ドル/月プラン）
- ウェブサーバーアプリ：Nginx（バージョン nginx/1.16.0）
- HTTPS設定済
![Screen Shot 2021-03-18 at 17.18.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130301/7c4192f6-c63c-0882-777e-8a2142dff5f6.png)

## 1.Nginxのconfで以下を設定

Nginxのconfファイルにて、listen箇所にhttp2を追加するだけでした。

```configuration:conf

# HTTPS server
server {
  listen 443 ssl http2;
  server_name  example.com;

  ・・・
}
```

## 2.Nginx再起動

```shell
$ sudo /opt/bitnami/ctlscript.sh restart nginx
```
以下図より、デベロッパーツールにて、Protocolに"h2"と表示されました。
![HTML 5 Shooting Game 2021-03-18 15-57-17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130301/16d7a57a-42db-2f87-c3d2-c1fd7cfae8d5.png)


##参考
- [NginxでHTTP2を有効にする](https://qiita.com/Aruneko/items/8c11f9e45a33457c3c1f#http2への対応)
- [「HTTP/2通信されているか？」をブラウザで手軽に判別する方法](https://nelog.jp/http2-browser-extensions)
Reactで使うStateに関する基礎知識

#はじめに
私が学んだstateについてのアウトプットです。

自分自身の健忘録であり、誰かの役に立てれば尚嬉しいです。

#stateとは？
stateとは**状態**のことであり、可変のデータである。
stateが変更されると、仮想DOMとの差分をとり、実際のDOMを更新し、コンポーネントを再描画します。

またstateではlocal stateとglobal stateの２つに分けられます。
1. コンポーネントの中で管理する変数(local state)
2. Reduxを使うことでどのコンポーネントからも参照できる(global state)

#なぜstateを使うのか？
render()内では無限に再レンダーされてしまうことを防ぐため、**値を変更してはいけない**というルールがあります。
そのため、render()内で値を変更するためには**setState()**を使って値を変更する必要があります。
そうすることで、ページリロードせずにコンポーネントを再描画し、表示を切り替えることができます。

#どうやって使うのか？
まず、stateは基本的にfunctional componentでは使用できません。
そのため、**class component**内で、かつconstructor内で使用する必要があります。
(React Hooksを使えばfunctional componentでも使用できます)
記述方法はObject型です
書き方の例↓

```react

class Qiita extends React.Component {
  constructor(props) {
    super(props);
      this.state = {
      isPublished: false
     }
  }
  //中略
}
export default Qiita;
```
##参考
https://ja.reactjs.org/docs/state-and-lifecycle.html
https://qiita.com/kyrieleison/items/78b3295ff3f37969ab50
https://www.youtube.com/watch?v=j4t0aZge0Mc&t=194s
Seleniumで、タグやクラスなどではなくテキストで要素を特定する方法

## テキスト指定は単にxpathつかえばいいだけだった
コメントで指摘されて初めてしったxpathの使い方。
特定のテキストのみを含むタグを指定したい場合は、単に

```ruby
 driver.find_element(xpath: "div[contains(text(), '目印にしたい文章')]")
```

で指定してやればいいだけだった。こんな便利な方法があったとは…。

## 以前やってた方法

Seleniumはブラウザ上で自動化して情報を取得したり、操作したりできて大変お役立ちなわけだが、要素の取得方法は限定的だったりして迷うことが多かったのでメモ的に（自分はruby使ってるのでrubyについてだが、多分他の言語でも同じようなこととは思う）。当たり前だろって感じなので、そんなに目新しいものはないけど。

通常、Seleniumによって要素を取得する方法はclassやid、xpathによって行う。

```ruby
 driver = Selenium::webDriver.for :chrome

 obj = driver.find_element(xpath: "//div[@class='hoge']/p")
```

多くはこのようにかいて、divタグのクラスhoge内のpタグの要素を取得するなど指定するわけだ。

しかしいずれの場合でもHTMLタグで取得したい情報の位置を指定するので、HTMLタグ側に特定の文字列がないと、とりたい情報を特定出来ない場合がある。同じようなHTMLが並んでて、テキストだけが違う場合はどうしたらよいだろう？

この場合でも同じように、まずは最低限しぼりこむところまでは同様のコマンドをかく。`find_elements`コマンドを使って、候補になる要素の配列までは獲得しておこう。

その上で、一端`.text`で、配列を生成しておく。

```ruby
obj = driver.find_elements(xpath: "//div[@class='hoge']")

ary = []

obj.each do |d|
 if d.text.include?("hogehoge")
       ary.push(d)
 end
end
```

これで`hogehoge`をテキストに含んだ要素の配列だけに絞れる。そしてさらにこの`<div class='hoge'>`以下のタグをとりたいなら

```ruby
ary2 = []

ary.each do |d|
 ary2.push(d.find_elements(xpath: "div[@class=fuga]/a"))
end
```

などすると`<div class="hoge">`以下の`<div class="fuga"> <a>`タグの要素が取得できる。

要するに、seleniumで取得した要素は、seleniumのコマンドでそこからさらに絞り込むことができますよ～っていうだけの話なんだけど、自分は知らなかったので。
E資格を取得した話

E資格を受験してみた。

# E資格とは

↓これ
https://www.jdla.org/certificate/engineer/

# E資格を受けた結果

■合否
合格

■分野別の得点率
応用数学：92 ％
機械学習：83 ％
深層学習：67 ％
開発環境：75 ％

# 勉強に使った資料

自分はzero 2 one という会社がやっているコースを受験した。勤務先の会社が指定してきたからここにしたが、自力で受験する人はいろいろ比べてみた方がいいと思う。

あとはこの黒本を買った。
黒本は本番と一字一句同じ問題も出るので、傾向と対策をつかむためにも早めにやっておいた方がよい。
3週はした。

https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0E%E8%B3%87%E6%A0%BC%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97AI%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE-%E5%B0%8F%E7%B8%A3-%E4%BF%A1%E4%B9%9F-ebook/dp/B08H79Y7X7

自分が受けたコースは結構大学1年レベルの線形代数、微分積分、確率あたりは知ってて当然、って感じで進んでいく。完全に忘れていたので、適時教科書で補った。大学のときの教科書があれば、それを使えばいい。ない人はこれがわかりやすいと思う。

https://www.mathema.jp/product_category/%E5%A4%A7%E5%AD%A6%E6%95%B0%E5%AD%A6%E3%82%AD%E3%83%A3%E3%83%B3%E3%83%91%E3%82%B9%E3%83%BB%E3%82%BC%E3%83%9F/

受講したコース ＋　黒本　を軸に、わからないところを付け足していく感じがよいと思う。

# 平均点

ここに平均点が載ってる。

https://www.jdla.org/news/20210312001/

# 俺的傾向と対策

思ったことを書いていく。

## 応用数学と機械学習

出題比率は応用数学が10%、機械学習が30%となっている。ここは古典的内容しか出ないし、問題も決まり切ってるので、9割とりたいところ。（取れてないけど）

## 深層学習

出題比率は50%。ここはマジで難しい。出題範囲も近年の論文から出題されることもあってとても広い。
なので、勉強中に「むずかしい！もうだめだ！」と思ったら、以下の2つは押さえておくととりあえず覚えておいた。

- その手法の図解（ぼんやりと覚えとく）
- 以前の手法からどう進化したか

その手法は過去の何かしらの欠点を克服しようとして登場している。どこをどう克服しようとしたかを意識してテキストを眺めると覚えやすい。

## 開発環境

特に対策しなかった。ゲーマーでGPUについて調べたことのある人は常識な問題とかもでる。

## まとめ

応用数学と機械学習で9割、深層学習で6割、開発環境で7割ぐらい正答すれば合格ラインは超えられる。

# 受験しての感想

- 強制的に勉強するようになる。
- ディープラーニングについて広く浅く知見が得られる
【Docker】ファイルの所有者501はどこからやってくる？ディレクトリマウント時の困りごと

発端
-
phpの`get_current_user()`でファイル所有者が取得できない。
スクリプトに下記のように書いても、

```php
var_dump(get_current_user());
```
こうなる訳です。

```php
string(0) ""
```

元々下記のようなコードがありwarning出力＆所有者変更が行われなくなってしまいはまっていた。

```php
chown($filename, get_current_user());
```
warningの内容。
forの後に不自然なスペースが、、

```php
chown(): Unable to find uid for  in
```

これ、仮に存在しないユーザーを所有者に変更しようとした場合にはここにユーザー名が入る。

```php
chown(): Unable to find uid for test in
```

環境
-

・Vagrantfileで作成したVM上で、Dockerコンテナを利用
・ローカル（Mac)のディレクトリをコンテナと共有

### ローカルで試してみた
Macのローカルで`var_dump(get_current_user());`してみると、ちゃんとファイル所有者が出力される。
**それで気づいた。**

コンテナ内ではスクリプトの所有者が501になってる、、

```shell

-rw-r--r--    1 501      dialout       2869 Mar  2 08:18 TestShell.php
```

501はどこからやってくるのか
-
コンテナと共有しているファイルは、ローカルで所有者表示させるとここでは置き換えているけど、ちゃんと意図したものになっている。

```Shell
-rw-r--r--  1 <ユーザー名>  <グループ名>  2869  3  2 17:18 ./app/src/Shell/QueingShell.php
```
これがコンテナに行った時には、違う所有者のものになっている。
当たり前といえば当たり前だけど、なんとなくrootとかが所有者になってると思ってた。

501は当然UIDだが、コンテナ（php-fpmのDockerHubイメージデフォルト）にはUID501のユーザーは存在していない。

```shell

/app # cat /etc/passwd
root:x:0:0:root:/root:/bin/ash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/mail:/sbin/nologin
news:x:9:13:news:/usr/lib/news:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
man:x:13:15:man:/usr/man:/sbin/nologin
postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin
cron:x:16:16:cron:/var/spool/cron:/sbin/nologin
ftp:x:21:21::/var/lib/ftp:/sbin/nologin
sshd:x:22:22:sshd:/dev/null:/sbin/nologin
at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin
squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin
xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin
games:x:35:35:games:/usr/games:/sbin/nologin
cyrus:x:85:12::/usr/cyrus:/sbin/nologin
vpopmail:x:89:89::/var/vpopmail:/sbin/nologin
ntp:x:123:123:NTP:/var/empty:/sbin/nologin
smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin
guest:x:405:100:guest:/dev/null:/sbin/nologin
nobody:x:65534:65534:nobody:/:/sbin/nologin
www-data:x:82:82:Linux User,,,:/home/www-data:/sbin/nologin
```


###Linuxにおける501ユーザーとは


UID501とは何を指すのか。
作成するユーザーのUIDは501から順にふられて行く、くらいしか知らなかったけど、下記のurlがとても参考になった。
https://oshiete.goo.ne.jp/qa/8209736.html

問題の解決
-

ローカルのボリュームがマウントされたコンテナでは、ボリューム内のファイルの所有者が501になるのが仕様っぽい。（掘り下げたい）
ただしコンテナ側ではuid501のユーザーは存在していない為`get_current_user()`すると空文字になってしまう。

空文字を回避したいだけなら、コンテナのuid501をちゃんとユーザーとして追加してあげれば良い。

alpineLinuxの場合

```sh

adduser -u 501 test -D
```
オプションの`-D`はデフォルト値を変更する意。
名前はなんでも良いので今回はtest。
これで`get_current_user()`した時にtestが取得されるようになった。
【Selenium】webdriver-managerのおかげでChrome Driverのバージョンを気にしなくてよくなった話

#はじめに

私は現在コンテンツ制作の現場に所属しています。
日々コンテンツを制作または更新し、WordPressにアップしていきます。

基本は創作活動なのですが、たまに作業でしかないタスクが発生することがあります。

- 数百件の外部リンクをWordPressにアップする
- リンク先のサイト構成の変更に伴い数百件の外部リンクのURLを変更する
- 数百件のコンテンツのアクセスレベルを変更する

これらは人間がやる必要のない仕事なので、Pythonで自動化してきました。
具体的には変更したい内容をcsvにまとめて、その内容をもとにSeleniumでChrome Driverを起動し、ブラウザ上でWordPressの内容を更新するといった流れです。

作成したツールはPythonがわからない人でも扱えるように[Pyinstaller](https://pypi.org/project/pyinstaller/)でexeファイル化してメンバーに配布していました。

しかし問題も抱えていました。

- Google Chromeがバージョンアップするたびに対応するChrome Driverを入れ替えて配布し直す必要がある
- exe内にChrome Driverを内包させているのでファイルサイズが大きくなる

この問題を解決してくれたのがこのライブラリです。

# webdriver-manager

[webdriver-manager](https://pypi.org/project/webdriver-manager/)

このライブラリを使うと、プログラム実行時に現在のGoogle Chromeのバージョンを確認し、
自動で適切なChrome Driverをあてて実行してくれます。

なので、定期的にバージョンの確認をしなくていいどころか、
そもそもchromedriver.exeを用意する必要すらなくなります。

使い方もすごく簡単です。

### webdriver-manager導入前の書き方

```***.py
from selenium import webdriver

driver = webdriver.Chrome(resource_path('chromedriver.exe'))
driver.get('https://www.xxx.com/')

```
※ `resource_path`は気にしないでください。pyinstallerでchromedriverもexeファイルに内包させるために必要になった記述です。

### webdriver-manager導入後

`pip install webdriver-manager`でインストールしたあとに

```***.py
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get('https://www.xxx.com/')
```

こんな感じで数行書き換えるだけです。

ヘッドレスなどのオプションをつけたい場合は

```***.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager

options = Options()
options.add_argument('--headless')

driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
driver.get('https://www.xxx.com/')
```

このように特に独自のルールはなく、
通常通り第二引数にoptionを指定してあげればOKです。

たったこれだけでchrome driverの呪縛から開放されました。
当然のことながらpyinstallerで作成したexeファイルも軽くなりました。

#まとめ

もし定期的に発生するchromedriverのバージョン違いエラーで悩んでる方がいれば、
webdriver-managerを試してみてください。
circleci/mysql:5.7でハマったお話

いつものようにGitにpushしたところエラー音を鳴らすメールが・・・

[![Image from Gyazo](https://i.gyazo.com/d36e23d108a8f678c0caa01a3b5e6476.png)](https://gyazo.com/d36e23d108a8f678c0caa01a3b5e6476)

慌ててCircleCIを確認しにいくと
[![Image from Gyazo](https://i.gyazo.com/e27ba8da59789d02ee8631a4c251c1e4.png)](https://gyazo.com/e27ba8da59789d02ee8631a4c251c1e4)

```
MYSQL_USER="root", MYSQL_PASSWORD cannot be used for the root user
    Use one of the following to control the root user password:
```

のエラーorz

##大ハマり

昨日はうまくいっていたのにうまくいかない理由がわからず大ハマりorz
何か変にコードを変えたのかと思い、revertしたりコードを書き直して、昨日と同じ状況にするも全く治らず（←そもそもこれが間違い）

その後ひたすらエラー文で調べたり、データベースをmariaDBにしてみたりと色々試す（ちなみにmariaDBはうまくいきました）

##判明
全く解決しないので、その後Twitterでcircleciで調べたところ同じような人がたくさんいることが判明。
どうやらmysql:5.7.33では

```yml:comfig.yml
MYSQL_USERNAME: 'root'
```
でrootを指定しているとエラーになるらしい。
***
##暫定の解決方法
あくまで暫定なので・・・もしかしたら褒められた方法ではないかもしれませんが、

```yml:comfig.yml
image: circleci/mysql:5.7
```

を

```yml:comfig.yml
image: circleci/mysql:5.7.32
```

に指定するとうまくいきます。ダウングレードなのであまり褒められた方法ではないかもしれませんが、とりあえずこれでなんとかなりましたorz

## 最後に

やっぱり色々な情報をキャッチアップする力が大事だなって思いましたorz(遅い)
そもそもcircleciについての知識もあまりないのに無理やり導入したのが悪いorz
導入したのなら裏でどういう働きをしているかしっかり考えなくてはならないと思いました（遅い）
CA Tech Challenge プロトスプリントリーグに参加してきた話

はじめまして、ぱられるです。3/12～14の3日間で行われたサイバーエージェントさんのハッカソンに参加してきた話です。
社員の方にブログを書くことを強くお勧めされたので書いてみようかなって。
3日間での気づきとか意識したこととかを書けたらいいなと思ってます。

https://www.cyberagent.co.jp/careers/students/event/detail/id=25320

# 作ったゲームの話
![花粉バスター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698373/3b1d373a-48b5-a99c-9ff9-d70d0145d2ff.png)
![プレイ画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698373/1f59ab53-e15b-1d4a-9871-72020670e851.png)

~~**花粉は悪**~~
チームで事前に顔合わせ兼企画会議をしてたときに、ちょうど花粉が飛ぶ季節だし鼻がぐじゅぐじゅ言い始める頃だから花粉症をテーマに作ったらおもしろいんじゃね？ってなったので、除草剤(通常ショット)と火炎放射(特殊ショット)で諸悪の根源を根絶するゲームにしました。~~僕は花粉症じゃないんですけどね。~~

# 0日目
テーマの発表が10日のお昼だったので、その日の晩にチームメンバーと顔合わせを兼ねて案出し会議をしました。
もともと他人のパーソナリティを深堀りしてコミュニケーションとるのが苦手&ここ1年でいろいろあってチーム制作が若干トラウマになっているので、チームメンバーのSlackの自己紹介とか見ててもすごい人ばかりだし、指揮とか任せて影薄く楽しく開発してようと思ってました。
事前の取り決めは、花粉をたくさん飛ばしたい→弾幕シューティング系のゲームにしよう→ルールは？→アイテムどんなん欲しい？→敵の行動パターンどうしよう？→誰が何担当する？→サーバークライアントの役割分担どうする？みたいな流れで割とサクッと決まりました。
僕はUnityは学校の制作とかでひと通り使う自信がありましたが、個人制作でのバージョン管理くらいにしかGitの経験がなかったので、ぶらんち？ぷるりくえすと？まーじ？って感じでぶっちゃけ滅茶苦茶不安でした。
![仕様書.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698373/7b3fa7cf-583a-1191-b226-aa4ff301c956.png)


# 1日目
自分だけで完結できるだろうっていう読みで敵の実装の担当を選んだので、とりあえずAssetフォルダ直下に自分の作業フォルダを作って引きこもることにしました。
最終的に自分のテストシーン→実際のゲームシーンに移さないといけないので基本的にプレファブ1個で全部完結できるようにすることと、短い時間で敵の種類を増やすためのクラス設計とパラメーター調整で弾幕の見た目が変わるような工夫を意識して実装をしていました。~~手を動かしながらクラス設計したから大人数開発だったらどっかで詰むんだろうなぁって思いながら。~~
1日目はそれぞれがほとんど自分の仕事をもくもくとする感じでチーム制作っていう感じではなかったからメンターの人もちょっと心配している様子でした(笑)。誰かが時間切って、進捗チェックとかタスクのマネジメントしないとって思ってたけれど、前述の通り影薄く行きたいなって思ってたので特に何も言わず。

# 2日目
朝から残りタスクの洗い出しと、今日の目標「ゲームループを回すこと」の再確認。僕は1日目を踏まえて敵のプレファブを作成。生成さえすればゲーム内で使えるよとだけ、ゲームシステム担当していたメンバーに伝えて後は弾幕の調整しとけばいいやって感じでのほほんとしてました。
昼に面談でメンターさんからちょっとチームの指揮をとってほしいと言われ、自分のタスクにかなり余裕が出てきていたこともあり、内心もやっとしながらも指揮をとる覚悟を決める。ここまでの作業を見ていて、時間の管理さえしていれば企画時点の内容は完成するだろうと思っていたので、そこに重点を置いてチームを回すことだけを意識していました。中間FB会の後も夜に少しだけみんなで作業してゲームループが回るところまでは完成。

# 3日目
朝から残りタスクとブラッシュアップの内容を確認してスタート。昼までにバグフィクス、そのあとは遊んで調整の繰り返し。
メンターさんからこうなってたらいいな、みたいな意見も沢山もらえたので取り入れつつ調整して調整してビルドしておしまい！ビルドエラーでちょっと時間オーバーしたけど提出して発表資料作成して待ち。
発表して他のチームのゲーム遊びながら4位くらいかなぁって思ってました。見栄えはそんなに良くないけれど、調整に時間を割いた甲斐もあって作者のひいき目抜きにしてもゲームとしてはかなり面白くできたという手ごたえを感じていました。

で、最終の順位発表がどうなったかというと。。。。。。。。

**なんと2位！**

めちゃ嬉しい。

# 振り返って
ゲームの見た目の部分で
事前にしっかり企画を詰めていたこと、棲み分けをしっかりしていたのでコンフリクトが全然起こらなかったことがスムーズに開発ができたと思っています。Gitに不慣れな人がチーム制作でGit使うときは作業フォルダを作るのがかなり有効な気がしました。また、メンターさんたちがいいところを見つけて褒めてくれたことやコードを見て意見をくれたりしたこと、面談でいろいろとアドバイスをくれたことがかなり今後のためになったかなと思います。
今後のチーム制作に今回の経験活かしていきたいですね。
SQL Server で DB 内の全テーブルのカラム情報を一覧化する

自分用覚え書き。

```sql
SELECT
    tbl.name AS 'TableName',
    c.name AS 'ColumnName',
	ty.name AS 'Type',
	c.max_length AS 'MaxLength',
	c.is_nullable AS 'IsNullable',
    ep.value AS 'Description',
    c.encryption_type_desc AS 'EncryptionType'
FROM
    sys.tables tbl
LEFT JOIN
    sys.columns c
    ON
        c.object_id = tbl.object_id
LEFT JOIN
    sys.types ty
    ON
        ty.user_type_id = c.user_type_id
LEFT JOIN
    sys.extended_properties ep
    ON
        ep.major_id = c.object_id
        AND
        ep.minor_id = c.column_id
ORDER BY
    tbl.name, c.name
```

急に「データベース定義どうなってる？ざっくりでいいんで出して」とか言われたときに ~~「接続情報教えましょうか」とか「ソースコード見れば分かります」とか言いたい気持ちを抑えて~~ さくっと実行する用。

## 更新履歴
2021/03/21: Description が無くても結果に含まれるように修正。
2021/06/18: カラム名を第2ソートに追加。
2021/10/19: 暗号化列が分かるように EncryptionType を SELECT に追加。
2023/03/15: カラム最大長と NULL 許可かどうかを追加。
Gilbert Strang先生から学んだ線形代数

# これは何か?

このシリーズでは、Gilbert Strang 先生の [Linear Algebra Vision 2020](https://ocw.mit.edu/resources/res-18-010-a-2020-vision-of-linear-algebra-spring-2020/) を元に、線形代数の直感的理解を得るための「目から鱗」の話題を紹介したいと思います。

https://ocw.mit.edu/resources/res-18-010-a-2020-vision-of-linear-algebra-spring-2020/

Gilbert Strang 先生は MIT の有名な（名物）線形代数の先生です。[OpenCourseware](https://www.youtube.com/watch?v=J7DzL2_Na80) で無償で先生の講義をみることができます。これが、とっても楽しいです。定理の証明を追うようなスタイルでなく、具体的な数で手を動かしながら、どんどん、直感的理解が進みます。ほんと、目から鱗です。まるで、古典落語を鑑賞するような感覚で何度も見ることができるクラシックです。

https://youtu.be/ZK3O402wf1c

その他、有名な著作がいくつもあり、インタビュー動画等もあります。

# 先生の線形代数の本

- 『[ストラング：教養の線形代数](https://www.amazon.co.jp/dp/4764906457)』 **日本語版が出ました（2023/2/11)**。 表紙の $A=CR$ の意味、解説はこちらに。（[→解説記事](https://qiita.com/kenjihiranabe/items/f3723e66f622a2aa9966
)）
[![EveryoneBook-small.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/db489535-14c1-5baf-ec1e-968477430e1f.png)](https://www.amazon.co.jp/dp/4764906457)


- 『[線形代数イントロダクション](https://www.amazon.co.jp/dp/4764904055)』([原著： "Introduction To Linear Algebra"](https://math.mit.edu/linearalgebra/) )表紙の意味わかりますか？ 解説がこちらに。（[→解説記事](https://qiita.com/kenjihiranabe/items/eadbcae5402d89660e65
)）
[![線形代数イントロダクション](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/0791cc01-5edb-687a-37f4-37b1394d03c3.png)](https://www.amazon.co.jp/dp/4764904055)

- 『[線形代数とデータサイエンス](https://www.amazon.co.jp/dp/4764906007)』
よりデータサイエンスや機械学習に必要な要素が詳しく。
[![Learning from Data](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/5df622f9-9cd6-65ca-59fa-3d1045842d1e.png)]((https://www.amazon.co.jp/dp/4764904055)
)

# 記事のリスト(執筆中)

さて、という訳で以下が**「Gilbert Strang先生から学んだ線形代数」**シリーズの目次です。

https://qiita.com/kenjihiranabe/items/f3723e66f622a2aa9966

https://qiita.com/kenjihiranabe/items/eadbcae5402d89660e65

https://qiita.com/kenjihiranabe/items/51a7f45e4972339e2aa3

https://qiita.com/kenjihiranabe/items/11d07d3cea0325f17851

- QR 分解を使ってGram-Schmidt の直交化を理解する（未稿）
- 対称行列の固有ベクトルは互いに直交する（ように選べる）（未稿）
- 特異値分解（SVD）によって任意の（長方）行列は、直交・対角・直交の3行列に分解できる（未稿）

視覚化して行列演算を捉えることに挑戦していて、こんな感じで上記を展開する予定です。

![Matrix Decomposition](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51055/1a3efcb8-a5ac-9d6a-a4c9-fa753e185ee6.png)

このあたりに興味がある方は、こちらに資料があります。

- [線形代数計算の視覚的と行列5分解](https://www.slideshare.net/hiranabe/graphic-notes-on-linear-algebra-and-data-science)
- [The Art of Linear Algebra](https://github.com/kenjihiranabe/The-Art-of-Linear-Algebra/blob/main/The-Art-of-Linear-Algebra.pdf)

# 先生と私のエピソード

個人的に　email を交換することができ、その過程で、先生の人柄にふれ感動してTシャツを作ったりしています。

- Gilbert 先生のTシャツのお話

https://anagileway.com/2020/06/04/prof-gilbert-strang-linear-algebra/

- Matrix World の話

https://qiita.com/kenjihiranabe/items/854dbe1f6d9fca9df85c
Rubocop実行した結果、文字数制限で指摘

# 前提
 - Rubocop導入済
 - gem 'devise' を導入済

# 経緯
今回、コミットする前にRubocopで確認しようと思い、
**docker-compose exec web bundle exec rubocop** （docker環境で動かしています）
をした結果以下の内容で指摘がありました。

```dockerfile:ターミナル
 config/initializers/devise.rb:17:151: C: Layout/LineLength: Line is too long. [152/150]
```
「150文字を超えてますよ」という指摘ですね。指摘箇所はこちらです。

```ruby:config/initializers/devise.rb
config.secret_key = (長いので省略しますが、[152文字]あります)
```

# 修正内容
指摘箇所の変更なしの方向でいきますので、以下のファイルを少し変更を加えました。

```ruby:.rubocop.yml
Layout/LineLength:
  Max: 150 #変更後　160
```

# 考察

あと、すこし調べてみましたが、**config.secret_key** と言うのは、**認証用のキー** ですので、
環境変数に置き換えた上で管理したほうが吉ですね。

私も一旦は文字数制限のみを変更しましたが、のちほど環境変数に置き換えて管理していきます💧
本番環境がある方はその辺りも確認したほうがいいですね。
【Git】git reset --hard すると git stash で待避させたログは消えるか？間違えて編集してしまったときの対処法

ブランチ間を移動して処理していた時に、`git stash`していたのを忘れて、作業中の内容を呼び出す前に変更してしまったとき、

**`git reset --hard @`で変更内容を強制削除しても、git stashの内容は残るか？**（消えたら怖い、、）

>@ は HEAD と同じ。（`git reset --hard HEAD`）

##結論
`git reset --hard`しても、**stashの内容は残る**。

焦らず、git reset --hardして、git stash popすればOK。


<br>
##git stash pop 上書き時の警告（エラー）と対処法
上書き後に`git stash pop`すると以下のようなエラーが出る。

```
$ git stash pop
error: Your local changes to the following files would be overwritten by merge:　ファイル名
Please commit your changes or stash them before you merge.
Aborting
The stash entry is kept in case you need it again.
```

待避内容を呼び出そうとしているファイルが上書きされているためエラー。マージする前にコミットするかスタッシュしてください。スタッシュ内容は残っているよとのこと。



###対処法

```
#直前のコミットに戻す（ワークツリー）
$ git reset --hard @
HEAD is now at e46b920 Merge pull request #60 from topic


#待避したデータは残っている。
$ stash list
stash@{0}: WIP on topic: e46b920 Merge pull request #60 from topic
```

  ↓　待避内容を呼び出し

```
$ git stash pop
On branch topic
Your branch is behind 'origin/topic' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
```

無事呼び出し完了。
NestJSにてクエリパラメータで渡した値が文字列になってしまう件について

NestJSでAPIを作成した際に、クエリパラメータでnumberやbooleanを渡すと文字列になってしまって、わざわざ自分で変換していたのですが、変換する方法が用意されていました。。


# 結論：Pipeを使おう

```
@Get()
async findOne(@Query('id', ParseIntPipe) id: number) {
  return this.catsService.findOne(id);
}
```

参考：https://docs.nestjs.com/pipes




# 現象について実際に動かして説明します



### バージョン


```shell
$ nest --version
6.12.2
```

### プロジェクト作成

```shell
nest new pipe-test
cd pipe-test
```

### コントローラーを修正

```src/app.controller.ts
import { Controller, Get, Query } from '@nestjs/common';

@Controller()
export class AppController {
    @Get()
    getTest(@Query('id') id: number, @Query('flg') flg: boolean) {
        console.log(id, typeof id);
        console.log(flg, typeof flg);
        return 'test';
    }
}
```

### 動作確認

`npm start`で起動し、ブラウザで`http://localhost:3000/?id=1&flg=true`にアクセスします

```shell
1 string
true string
```

id/flgともにstringになっています:sweat:



### パイプをかませる

```src/app.controller.ts
import { Controller, Get, ParseIntPipe, Query } from '@nestjs/common';
import { ParseBoolPipe } from './pipes/parse-bool.pipe';

@Controller()
export class AppController {
    @Get()
    getTest(@Query('id', ParseIntPipe) id: number, @Query('flg', ParseBoolPipe) flg: boolean) {
        console.log(id, typeof id);
        console.log(flg, typeof flg);
        return 'test';
    }
}

```

※NestJS6系だとParseBoolPipeとParseArrayPipeはないなので、雑に移植して試してみました。
参考：https://github.com/nestjs/nest/blob/master/packages/common/pipes/parse-bool.pipe.ts

```src/pipes/parse-bool.pipe.ts
import { ArgumentMetadata, BadRequestException, Injectable, PipeTransform } from "@nestjs/common";

/**
 * Defines the built-in ParseBool Pipe
 *
 * @see [Built-in Pipes](https://docs.nestjs.com/pipes#built-in-pipes)
 *
 * @publicApi
 */
@Injectable()
export class ParseBoolPipe
    implements PipeTransform<string | boolean, Promise<boolean>> {
    protected exceptionFactory: (error: string) => any;

    /**
     * Method that accesses and performs optional transformation on argument for
     * in-flight requests.
     *
     * @param value currently processed route argument
     * @param metadata contains metadata about the currently processed route argument
     */
    async transform(
        value: string | boolean,
        metadata: ArgumentMetadata,
    ): Promise<boolean> {
        if (value === true || value === 'true') {
            return true;
        }
        if (value === false || value === 'false') {
            return false;
        }
        throw new BadRequestException('Validation failed (boolean string is expected)');
    }
}
```

これで同じように`http://localhost:3000/?id=1&flg=true`にアクセスします

```shell
1 'number'
true 'boolean'
```

idがnumber型に、flgがboolean型になりました！



### 想定外の値を渡すとどうなるか

想定した型以外の値を渡すと以下のような戻り値になります

- `http://localhost:3000/?id=eee&flg=true`

```
{"statusCode":400,"error":"Bad Request","message":"Validation failed (numeric string is expected)"}
```

- `http://localhost:3000/?id=1&flg=aaa`

```
{"statusCode":400,"error":"Bad Request","message":"Validation failed (boolean string is expected)"}
```

※この時、controllerのメソッドは実行されません。

# まとめ

提供されているパイプは少ないですが、自作することもできるので色々出来そうです！
絶対パスと相対パス

# パスとは
- ディレクトリやファイルの所在を示す文字列のこと
- ディレクトリは階層ごとに/(スラッシュ)で区切られる
- パスの指定方法は`絶対パス`と`相対パス`の2つがある

##絶対パス
- ルートディレクトリから指定するパス
- 全ディレクトリにおけるルートディレクトリは`/`
- 絶対パスで指定するときにはパスの一番最初に`/`を指定

```:ターミナル
/Users/ユーザ名/Desktop
```
>
- `1番始めの/`は**ルートディレクトリ**
- `2番目以降の/`は**階層の区切り**
- `/Users/ユーザ名`は**ホームディレクトリであり`~`と表すことが可能**
>
```:ターミナル
~/Desktop
```

###メリット・デメリット
**メリット**
>
どのディレクトリで作業していても指定した場所に移動できる

**デメリット**
>
パスをルートディレクトリからたどって指定する必要があるため、
記述が冗長になる場合がある


##相対パス
- カレントディレクトリから指定するパス
- パスの始めに`/`を付けない

```:ターミナル
# カレントディレクトリがホームディレクトリの場合にデスクトップの場所を指定する
Desktop

# カレントディレクトリがホームディレクトリの場合にデスクトップにあるファイルの場所を指定する
Desktop/メモ.txt
```
>
カレントディレクトリ直下のディレクトリやファイルであれば、
どのようなディレクトリ階層にあるのか指定することなく簡単にパスの指定が可能

###メリット・デメリット
**メリット**
>
相対パスは、記述をシンプルにパスの指定が可能

**デメリット**
>
カレントディレクトリがどこにあるのかによって、指定するパスを変更する必要がある
React状態管理ライブラリ「Jotai」のProvider-less modeで楽々コーディング

[Jotai](https://github.com/pmndrs/jotai)使ってますか？

v0.15.0よりProvider-less modeが入りました。些細な差ですが、より手軽になりました。簡単に紹介します。

## codesandboxを開く

<https://react.new> を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/0a5b3598-10fe-daac-2d06-4260d6cb7400.png)

## jotaiをインストール

左下のAdd Dependencyにjotaiと入力してインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/4be144d5-f9a0-d1a3-7650-d07b18c99311.png)

## jotaiからimport

`atom`と`useAtom`をimportします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/4092aa8e-ab29-fdd7-ba47-4aff9eee6fb3.png)

## atomを定義

`atom`を使って一つのprimitive atomを定義します。引数に初期値を設定します。

```js
const countAtom = atom(0);
```

今回は簡単のため同一ファイルですが、通常はatom定義は別ファイルにした方が管理しやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/463f7f3a-e9a5-d787-90df-2a442e61361a.png)

## コンポーネントを作成

定義したatomを使ってコンポーネントを作ります。

```jsx
const Counter = () => {
  const [count, setCount] = useAtom(countAtom);
  return (
    <div>
      {count} <button onClick={() => setCount((c) => c + 1)}>+1</button>
    </div>
  );
};
```

useAtomの戻り値はuseStateと同等に使えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/25a9b68f-d1e0-ecc3-75c8-c7c3d08bd55d.png)

## Appに組み込む

最後に作ったコンポーネントをAppに組み込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63327/b9a30115-8440-b94a-d69d-c0ecc50a54a1.png)

カウンターが動きました。

作成したcodesandboxは[こちら](https://codesandbox.io/s/kind-framework-jr0rk)です。

## おわりに

とても簡単な例でしたが、useStateと同じように使えるuseAtomの使い勝手が示せたでしょうか。jotaiは派生atomも作ることができるのでぜひそちらもお試しください。

そういえば、デモサイトのURLが新しくなりました。
<https://jotai-demo.pmnd.rs>

## React開発者向けオンラインサロン「React Fan」の紹介

最後に、私が主催している「React Fan」というコミュニティをお知らせします。テキストチャットでコミュニケーションできるSlackのワークスペースを用意しています。Slackへの参加は無料ですので、ご興味がある方はぜひご参加ください。詳しくは、下記のページをご参照ください。

[React開発者向けオンラインサロン「React Fan」の入り口ページ](https://react-fan.axlight.com/)

Slackへの招待リンクも上記ページにあります。
十字アイコンのアコーディオン


よくあるやつです

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="okdyy75" data-slug-hash="gOLJNVR" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="十字アイコンのアコーディオン">
  <span>See the Pen <a href="https://codepen.io/okdyy75/pen/gOLJNVR">
  十字アイコンのアコーディオン</a> by Yuya Okada (<a href="https://codepen.io/okdyy75">@okdyy75</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### HTML
```html

<div class="accordion">
    <div class="accordionHead">
        <div>アコーディオン</div>
        <div class="accordionIcon">
            <span class="close"></span>
        </div>
    </div>
    <div class="accordionBody">
        <div class="close">
            アコーディオンの中身
        </div>
    </div>
</div>
```

### CSS
```css
.accordion {
    width: 300px;
    border: solid 1px #000;
    margin: 10px;
}
.accordionHead {
    display: flex;
    position: relative;
    margin: 10px;
}
.accordionBody {
    display: flex;
    position: relative;
    margin: 10px;
}
.accordionIcon {
    width: 20px;
    height: 20px;
    position: absolute;
    right: 10px;
}
.accordionIcon .open::before {
    content:"";
    position: absolute;
    width: 100%;
    top: 50%;
    border-top: solid 1px #000;
}
.accordionIcon .close::before {
    content:"";
    position: absolute;
    width: 100%;
    top: 50%;
    border-top: solid 1px #000;
}
.accordionIcon .close::after {
    content:"";
    position: absolute;
    height: 100%;
    right: 50%;
    border-right: solid 1px #000;
}
.accordionBody .open {
    display: block;
}
.accordionBody .close {
    display: none;
}
```

### Javascript
```javascript
document.querySelector('.accordionIcon').addEventListener('click', ev => {
    document.querySelector('.accordionIcon span').classList.toggle('open')
    document.querySelector('.accordionIcon span').classList.toggle('close')
    document.querySelector('.accordionBody div').classList.toggle('open')
    document.querySelector('.accordionBody div').classList.toggle('close')
});
```
Rails カラム名を変更かつ全てのファイルでカラム名を置換する（VSCode限定）

プログラミング初心者です。
ポートフォリオの作成をある程度進めた段階でテーブルのカラム名にスペルミスがあったことに気づき、テーブルのカラム名とカラム名を使用している全てのファイルを変更しました。

**※テーブルのカラム名変更まではRailsでのコマンドですが、全ファイルのカラム名置換はVSCodeでの操作になります。**

## 環境
ruby '2.6.5'
rails '6.0.0'

エディタ　VSCode

## 解決したいこと
店舗情報を保存するStoreモデルで、住所を保存するカラム名を"address"とするはずが、"adress"とスペルミスをしていました。
しかし"adress"という名前でビューやモデルなど複数のファイルに記述してしまっているため、全てのファイルで一個一個手直しするのは面倒です。
そのため**1.テーブル上のカラム名を変更**し、**2.全ファイルのソースコード上のカラム名を変更**していきます。

## 1.テーブル上のカラム名変更

下記のコマンドで、カラム名変更を記述するmigrationファイルを生成します。

```
$ rails generate migration rename_adress_column_to_stores
```

**※adressとstoresの部分は、各自の変更前カラム名とモデル名を入れてください。**

生成したmigrationファイルを以下のように編集します。

```ruby:db/migrate/20210318072032_rename_adress_column_to_stores.rb
class RenameAdressColumnToStores < ActiveRecord::Migration[5.2]
  def change
    rename_column :stores, :adress, :address
  end
end
```

DBへ反映させます。

```
$ rails db:migrate
```

これでテーブル上のカラム名は変更されました。

## 2.全ファイルのソースコード上のカラム名を変更

ここからはVSCodeでの操作となります。

VSCodeの左側にある虫眼鏡マークをクリックします。
![スクリーンショット 2021-03-18 16.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922273/cff122e0-ec61-8eb1-d6af-5a771bb85292.png)


クリックすると下のようにSearchフォームとReplaceフォームが出てきます。
![スクリーンショット 2021-03-18 17.15.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922273/cc29e531-5e11-8daf-e3c6-16db7d8513ad.png)

以下の手順で全ファイルのソースコード上の変更したいカラム名を置換します。
①Searchフォームに変更前のカラム名（adress）を記述
②Replaceフォームに変更後のカラム名(address)を記述
（フォームの下に対象となるファイルがズラーっと表示されます）
③Replaceフォームの右側のアイコンをクリック
![スクリーンショット 2021-03-18 16.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922273/ace9eb6c-e713-2bcb-60c3-9e03519094df.png)

すると画面上部に下のような画像が表示されるのでReplaceを選択します。
![スクリーンショット 2021-03-18 16.29.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/922273/48af16f4-7dcb-d91a-95a8-ca33ae1c95db.png)

これで全ファイルでの置換ができました。

ちなみにこの手順でやると、1.で生成したmigrationファイル内に記述されている変更前のカラム名も置換されるので、置換後に修正してください。

```ruby:db/migrate/20210318072032_rename_adress_column_to_stores.rb
class RenameAddressColumnToStores < ActiveRecord::Migration[5.2]
　　　　　　　#⬆︎AdressがAddressに置換されている
  def change
    rename_column :stores, :address, :address
　　　　　　　　　　　　　　　　　#⬆︎adressがaddressに置換されている
  end
end
```
修正

```ruby:db/migrate/20210318072032_rename_adress_column_to_stores.rb
class RenameAdressColumnToStores < ActiveRecord::Migration[5.2]
  def change
    rename_column :stores, :adress, :address
  end
end
```

この修正が入るのが嫌な場合は「全ファイルの置換」→「テーブル上の変更」の手順で実行すると、修正が不要になります。


## 参考にした記事
Rails カラム名変更方法
https://qiita.com/libertyu/items/93acd8733e34b1d0a63c

複数ファイルの同要素を一回で置換する裏技
https://kt-life.net/vs-code-alltikan/
windowsでiverilog その95

#概要　

windowsでiverilogやってみた。
rp2040 pioの、テストベンチ書いてみた。

#参考にしたページ

https://github.com/lawrie/fpga_pio

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/48cc5bf5-fbae-7ad7-c42b-c63e22b8f18d.jpeg)


#サンプルコード

```
module test();
	localparam NONE = 0;
	localparam INSTR = 1;
	localparam PEND = 2;
	localparam PULL = 3;
	localparam PUSH = 4;
	localparam GRPS = 5;
	localparam EN = 6;
	localparam DIV = 7;
	localparam SIDES = 8;
	localparam IMM = 9;
	localparam SHIFT = 10;
	wire [31:0] gpio_out;
	wire [31:0] gpio_dir;
	wire [31:0] dout;
	wire [3:0] tx_full;
	wire [3:0] rx_empty;
	wire [5:0] plen = 2;
	wire [23:0] div = 24'h0280;
	wire [31:0] pin_grps = 32'h04000000;
	wire [31:0] exec_ctrl = 32'h00001000;
	reg clk;
	reg reset;
	reg [31:0] din;
	reg [4:0] index;
	reg [3:0] action;
	reg [1:0] mindex;
	reg [31:0] gpio_in = 0;
	reg [15:0] program[0:31];
	initial $readmemh("./pio0.mem", program);
	task act(input [3:0] a, input [31:0] d);
		begin
			@(negedge clk);
			action = a;
			din = d;
			@(posedge clk);
		end
	endtask
	pio pio_1(.clk(clk), .reset(reset), .action(action), .index(index), .mindex(mindex), .din(din), .dout(dout), .gpio_in(gpio_in), .gpio_out(gpio_out),
		.gpio_dir(gpio_dir), .tx_full(tx_full), .rx_empty(rx_empty));
	integer i;
	initial
	begin
		reset = 1'b1;
		repeat(2) @(posedge clk);
		reset = 1'b0;
		for (i = 0; i < plen; i++)
		begin
			index = i;
			act(INSTR, program[i]);
		end
		mindex = 0;
		act(PEND, exec_ctrl);
		act(DIV, div);
		act(GRPS, pin_grps);
		act(EN, 1);
		act(NONE, 0);
		repeat(100) @(posedge clk);
		$finish;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
	end
	initial
	begin
		clk = 1'b0;
	end
	always
	begin
		#20 clk = !clk;
	end
endmodule



```


以上。
2021/03/18にCircle CIのMySQLのDocker ImageでMYSQL_USER=rootがNGになった

# 概要

タイトルまんま

## Docker Imageの修正内容

[こちらのPR参照](https://github.com/docker-library/mysql/commit/6a9edebd6ed7b0178b0cce7495bea1777cb9f128#diff-8b13cbe70e88ea25c1d77de%5B%E2%80%A6%5D479bcb36ffb0976a5842R156-R165)

## 対処方法

- MYSQL_USER=rootがNGなのでそれを使わなければ良い
- どこで見たか忘れたが、MySQLの一般ユーザーはパスワードが8文字以上じゃないとダメらしい

```.circleci/config.yml
.
.
.
      - image: circleci/mysql:5.7-ram
        name: mysql
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: 'false'
          MYSQL_DATABASE: 'test_db'
          MYSQL_PASSWORD: 'db_for_test'
          MYSQL_USER: 'hoge'
```

こんな感じで`MYSQL_USER: 'root'`をやめる

## 参照

- [circleci/mysql:5.7](https://hub.docker.com/layers/circleci/mysql/5.7/images/sha256-afea37130f6f9a9673f59edbfe0f486b036dc723a7a715bdbd294ae3c14cd663?context=explore)
- [docker-library/mysql](https://github.com/docker-library/mysql)