OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails / FontAwesome】formの検索ボタンを虫眼鏡のアイコンにする

Ruby on RailsでFont-Awesomeを初めて使ったの投稿しました。

Font Awesome HP
https://fontawesome.com/icons?d=gallery

#### ポイント：使いたいアイコンのUnicodeの前に \u をつける

1 . CDNでfont-awesomeを読み込む

```
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
```

2 .  submitの記述の後を下記に変更。

```
<%= f.submit "\uF002" %>
```
3 . cssで下記を追加

```
font-family: FontAwesome;
```
【読書記録】Kotlinイン・アクション -第6章-

書籍「Kotlinイン・アクション」を読んで個人的に疑問に思った点や調べたことについて記載する読書記録です。
書籍の内容については記載しません。

## 第6章の内容
第6章　型システム
https://book.mynavi.jp/ec/products/detail/id=78137

# Kotlinイン・アクション 第6章 型システム

## 混乱しやすいところ

nullの扱いについては、Kotlinでコードを書いている時にnullが返ってくるのか、無視されるのか混乱することがよくあるので、6章に書いてある内容をまとめてみた。

### 安全呼び出し演算子(?.)の戻り値

foo?.bar()の戻り値はnullableである。
fooがnullだった場合はbarが実行されないわけではなく、nullが返ってくる。
そのため、エルビス演算子と組み合わせて使うことができる。

```
val hoge = foo?.bar() ?: "Default value"
```

### 安全キャスト(as?)の戻り値

キャストに成功した場合はキャスト後の型のインスタンスが返される。
キャストに失敗した場合はnullが返される。
ClassCastExceptionはスローされない。

### let関数

```
foo?.let{}
```

fooがnullの場合、let関数のラムダは実行されない。(=nullを返さない)

## その他

### Javaのthisがnullになることはないが、kotlinのthisはnullになることがある

Javaの場合、thisは特定の型のインスタンスを指定するためnullにはならない。
Kotlinの場合、thisはレシーバを指すためレシーバがnull許容型であればnullになりえる。

### プラットフォーム型

Javaとの互換性のために存在している。
Javaコードで明示的に@Nullable、＠NonNullがついていない場合はKotlinではプラットフォーム型として扱われる。
例:String!
これはnull非許容型にもnull許容型としても扱えるため、実装者が適切に扱う必要がある。
コンパイラは警告やエラーを出さず、適切に扱われていない場合は実行時に例外が発生する。

コレクション型もプラットフォーム型として扱われる。
この場合はミュータブルからイミュータブルのどちらでも扱えるようになる。
Vi　使い方　8　手順書フォルダ

#概要
今の自分にとって必要なViコマンドをノートしました。
8選びました。　
##コンテンツ
###コマンド
###TakeAway
##コマンド
vi make-work.txt
:wq    保存
:q!　　終了
:/orange　文字列検索（順方向）
:?orange  文字列検索（逆方向）
n　　順方向へ検索
N　　逆方向へ検索
:%s/apple/orange/g
##TakeAway
（０）enterで実行
（１）vi ファイル名　で開始。（権限が必要なファイルはsudo viで開く）
（２）コマンドモードと，編集モードがある。
（３）iとかaで編集モードに移れる。
（４）ESCキーでコマンドモードに移れる。
（５）編集モードでは，普通に内容を編集できる。
（６）コマンド　:wq　で保存。
（７）コマンド　:q!　で終了。
（８）何かおかしいと思ったら英数になってないことを疑ったらいいのかも。
テスト20

```vb

'--------------------------
'ファイル検索と処理
'--------------------------

Sub Sample()

Dim Hiduke As String
Hiduke = Replace(Date, "/", "")

Call FileSearch("C:\Users\User\Desktop\経理関連", Hiduke)
    
End Sub

'-----------------------------------

Sub FileSearch(Path As String, Target As String)

Dim FSO As Object
Dim Folder As Variant
Dim File As Variant
Dim wb As Workbook
Dim Mrow As String

Set FSO = CreateObject("Scripting.FileSystemObject")


For Each File In FSO.GetFolder(Path).Files

'    If File.Name Like Target Then
    If InStr(File.Name, Target) > 0 Then
    
       MsgBox File.Name
       Set wb = Workbooks.Open(File.Path)
       '-------------
       'いろいろ処理
       '-------------
       wb.ActiveSheet.Select
       Mrow = wb.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
       MsgBox Mrow
       
       wb.Close SaveChanges:=True
        
    End If
    
Next File

Set wb = Nothing

End Sub

```
StreamAPIの話


##StreamAPIの話

ストリームAPIとは並列化、直列化

解りやすい記事
https://www.casleyconsulting.co.jp/blog/engineer/191/

###mapの説明が解りやすい

```java

public interface Stream<T> ...
  <R> Stream<R> map(Function<T, R> mapper);
```

map　戻り値ありのコール関数（戻り値と引数あり）を渡して結果を
ストリーム型に変換するもの
http://enterprisegeeks.hatenablog.com/entry/2015/11/30/081118

###java.util.stream 順次／並列ストリームについて理解する（直列と並列が解りやすい）
https://qiita.com/nmby/items/52d1b0e2dad5df475737

おまけ
javaをVSコードで実行する
※VSコードの説明、コンフィグはユーザー単位、フォルダ単位がある
※プロジェクトを作成してから作成した方が良い
ラズパイでSORACOM SIMを利用方法する AK-020 

## 概要
* SORACOM SIMを利用してラズパイからインターネット経由へアクセスをする。
    * インターネットからラズパイへのアクセスは別途記載する。

## 事前準備
* [3G USBドングル AK-020 SORACOMスターターキット](https://www.amazon.co.jp/dp/B01G1GSYHW/)
    * SIMとUSBドングルのセット
    * SORACOMの1000円分のクーポン付
    * 3GだがIoTでの利用目的なら問題なし
* [SORACOM](https://soracom.jp/)のユーザ登録と上記のSIMの登録

## 手順
1. SIMをUSBドングルへ挿入
2. USBドングルを利用したいラズパイのUSBポートへ接続
3. ラズパイでセットアップ用スクリプを取得し自動設定をする。
    * 実行後、SIMの設定が自動で行われ、IPアドレスなども割り当てられる。
    * SORACOMの[コンソール画面](https://console.soracom.io/#/)でもステータスがオンラインに変化する。
    * ステータスがオンライン = **従量課金** が開始するので注意。

    ```
    $ curl -O https://soracom-files.s3.amazonaws.com/setup_air.sh
    $ sudo bash setup_air.sh
    ```

4. グローバルIPアドレスが割り当てられていることを確認。

    ```
    pi@raspberrypi:~ $ curl inet-ip.info
    103.67.***.***
    ```

5. ラズパイからインターネットへのアクセスがで来たことを確認。

    ```
    pi@raspberrypi:~ $ ping 8.8.8.8 -c 4
    PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
    64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=147 ms
    64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=85.9 ms
    64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=84.2 ms
    64 bytes from 8.8.8.8: icmp_seq=4 ttl=116 time=81.1 ms
    ```


## 公式ドキュメント
* [各種デバイスで SORACOM Air を使用する](https://dev.soracom.io/jp/start/device_setting/)
WSL2のUbuntu20でapt-getができなくなったので対処法

# はじめに
WSL2のUbuntuで`sudo apt update`を久々にしたらエラーが出ました。なんだろうと思って`ping google.com`をしても接続ができていないのでググったところ、[この記事](https://cartman0.hatenablog.com/entry/2020/07/16/WSL2%E3%81%A7%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88)を見つけ解決できました。感謝！

自分の環境ではもうひと手間必要だったので、追記分だけ記事に残させてもらいます。

## 環境
* Windows10 ver2004（OSビルド 19041.630）
    * WSL2
        * Ubuntu 20.04
    * Docker Engine: 19.03.13

# 手順
* [参考記事の](https://cartman0.hatenablog.com/entry/2020/07/16/WSL2%E3%81%A7%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88)1~4までを行う

* 手順5の`wsl`を実行
* `sudo rm /etc/resolv.conf`を行う
    * →元々の設定で存在したシンボリックリンクが、手順3で実体のファイルが消えた？パーミッションで上書きができなかったために削除
* 手順5の`sudo vim /etc/resolv.conf`を実行
* 手順6を実行

# 所感
よく理解できていないのですが、いくつか記事など拝見したところMS側では特に対応していない？っぽく、少し強引に設定する必要があるようです。ネットワークも奥深い上にセキュリティにも関わるので難しいです。
なにか間違いや、よりよい方法などあればご教示いただけるとありがたいです。
chrome拡張のReact Developer Toolsが効かない

local:3000でReactのページを表示しても、ReactDeveloperToolsが効かないとき

chromeの右上「︙」
→「設定」
→「拡張機能」
→React Developer Tools　の詳細（chrome://extensions/?id=fmkadmapgofadopljbjfkapdkoienihi）
→「ファイルのURLのアクセスを許可する」をONにする
→Chromeを再起動

![画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513214/757ac6dd-0c96-4769-97e2-cba13eea818a.png)
【ElastiCache】ElastiCacheの可用性 / 拡張性 / セキュリティ

## 可用性
|機能|Redis|Memcahced|
|:-:|:-:|:-:|
|データベースの永続化<br>（ディスクストレージへの書き出し)|◯|×|
|レプリケーション|◯|×|

**【Redis】**
・データのディスクストレージへのバックアップとバックアップからのリストアが可能
・レプリケーションによるクラスタリング構成が可能
・プライマリノードと複数のレプリカを持つ
・プライマリノードに障害が発生した場合自動的にフェイルオーバーとなり、レプリカがマスターに昇格する

**【Memcached】**
・レプリケーション機能を持たないため、各ノードが独立して存在する
・クラスターに新たにノードを追加してもそのノードにはデータが入っていない
・アプリケーション側で、新しいノードに他のノードと同じデータを書き込むなどの対応が必要

## 拡張性
ノードタイプの変更によるスケールアップと、ノード数の増加によるスケールアウトが可能

## セキュリティ
### アクセス制御
RedisとMemcachedのいずれのエンジンを選択した場合にも、クラスターへのアクセス制御にセキュリティグループを利用する

### 暗号化
Redis利用時にのみ、SSL通信機能により通信内容を暗号化することが可能
（SSL通信機能はRedisクラスターの作成時にのみ指定可能）
配列を繰り返して取り出す処理が言語によって微妙に違う…

for文で配列を1つづつ取り出して変数に代入したいことってよくありますよね。
色々な言語による微妙な違いで脳がやられます。ここではPython,JavaScript,PHPを取り上げます。

---

Pythonだと

```python

for(変数 in 配列)
    #繰り返したい処理
```
inなんですよね。そしてPythonは{}なしでインデントで表します。

でみんな大好きJSだと

```JavaScript
//配列のとき
for(変数 of 配列){
    //繰り返したい処理
}
```

ofなんですよね。ちなみにオブジェクトだとinを使います。

で、PHPだと


```PHP
foreach($配列 as $変数){
    //繰り返したい処理
}
```

for文ではなくforeach使ってしかもasです。

混同しそうです………
FlutterでSwiftPackageManager利用時のパッケージ依存関係エラーを解消する方法

# はじめに
こんにちは趣味でアプリ開発をしている[@glassmonkey](https://twitter.com/glassmonekey)です。
今回はFlutterでiOSアプリの開発中に[Swift Package Manager](https://swift.org/package-manager/)を利用したときにハマった点があったので記録に残しておこうと思います。

補足などあれば遠慮なくコメントなどでご指摘ください。

# 環境


Xcode古いけど許して


```bash
$ flutter doctor
[✓] Flutter (Channel stable, 1.22.3, on Mac OS X 10.15.7 19H15, locale ja-JP)
 
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.4.1)
[✓] Android Studio (version 4.0)
(以下略)
```

# 発生したエラーについて
[Swift Package Manager](https://swift.org/package-manager/)を利用して、依存関係を増やしたところ、`Xcode`では通常通りビルドできるが、Android Strido経由での`flutter build ios`が以下のエラーで通らないようになりました。

```bash
Oops; flutter has exited unexpectedly: "ProcessException: Process exited abnormally:
Command line invocation:
    /Applications/Xcode-11.4.1.app/Contents/Developer/usr/bin/xcodebuild -list


xcodebuild: error: Could not resolve package dependencies:
  Packages are not supported when using legacy build locations, but the current project has them enabled.
  Command: /usr/bin/xcodebuild -list".

```

# 原因
[修正のPR](https://github.com/flutter/flutter/pull/58522)によると、もともとのFlutterで作成したプロジェクト設定がレガシービルド設定になっていたようです。

[Xcode 10のリリースノート](
https://developer.apple.com/documentation/xcode-release-notes/build-system-release-notes-for-xcode-10)
によると
> If you need it, the legacy build system is still available in Xcode 10. To use the legacy build system, select it in the File > Project/Workspace Settings sheet. Projects configured to use the legacy build system will display an orange hammer icon in the Activity View.

と言及している程度ですが、Swift Package Managerが利用できないって認識で良さそうっぽいですね。


https://github.com/flutter/flutter/pull/59009
https://github.com/flutter/flutter/pull/68361
にて追加対応があったので、今後のバージョンでは治ってる可能性が高いそうです。ありがたや。

# 修正方法
同じ現象が報告されている[issue](https://github.com/flutter/flutter/issues/57083)
に記載されている対応をします。

1.  プロジェクトを開く（ワークスペースではないことが重要）
  
```bash
$ open ios/Runner.xcodeproject
```

2. File > ProjectSettingを開く
 ![スクリーンショット 2020-11-23 16.56.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/29451e15-abfb-b17c-99fe-96e5a4c05780.png)

3. Advancedを開く
![スクリーンショット 2020-11-23 16.56.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/bcdf229b-fe56-14c3-f8d2-8e912460f07b.png)

4. Legacyからdefaultにする
おそらくLegacyにチェックが入っているはずなので、スクショのように`Xcode Default`にして`Done`を押下する
![スクリーンショット 2020-11-23 16.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/f7f364e3-95ac-1d38-0ea4-99a6127acce2.png)

これでFlutterコマンドからもビルドが通るようになったはずです。


5. もし上記の方法でもだめだったら、workspaceも確認してみる

Procject SettingがWorkSpaceSettingになってる以外は同様の項目なので、もしかしたら確認してみても良いかもしれません。

```bash
$ open ios/Runner.xcworkspace
```

# 考察
Android StdudioのToolから開いた場合はワークスペースで開いている
![スクリーンショット 2020-12-02 2.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152938/1ab4a323-0692-9a0d-b7af-b889bba16dec.png)
一方で、Flutterコマンドの場合はプロジェクト設定を見ているので、そこに齟齬があるとFlutterコマンドでのみビルドが通らないという事象が発生するようだった。

なので、Flutterコマンド経由のビルドに関しては

```bash
$ open ios/Runner.xcworkspace
```

で見る癖をつけると良さそうに思いました。


# 感想
Xcodeむずかしい。



w
[iOS]FDL(Firebase Dynamic Links)とは

### Firebase Dynamic Linksとは

ユーザーがあるURLを踏んだ場合、

- iOSデバイスを使っている時、
   - あるアプリがインストールされている時は、そのアプリでコンテンツを開く
   - インストールされていない時は、そのアプリのストアのページを開く
- Androidデバイスを使っている時、
   - あるアプリがインストールされている時は、そのアプリでコンテンツを開く
   - インストールされていない時は、そのアプリのストアのページを開く
- そのほかのデバイスを使っている時は、Webブラウザでコンテンツを開く

という風に、デバイスやアプリのインストール状況に応じて違う振る舞いをしたい時がある。

ただ、しかし、それぞれの振る舞いごとに違うURLを用意していては、何個もURLが必要になりユーザーがどれをタップしていいかわからないし、そもそもURLを何個も書ききれないだろう（例えば、ツイッターの一つの投稿にURLを5つも載せるのは無理である）。

一つのURLだけで、状況に応じて違う振る舞いができるのが、Firebase Dynamic Linksである。

下記ページのように、FDLの動きのフローチャートを見ると分かりやすい。
[Dynamic Links をデバッグする](https://firebase.google.com/docs/dynamic-links/debug?hl=ja)

### 導入手順

#### Firebase Dynamic Linksの生成

[iOS で Dynamic Links を作成する](https://firebase.google.com/docs/dynamic-links/ios/create)

#### Firebase Dynamic Linksをアプリ側で受け取る

[iOS でダイナミック リンクを受信する](https://firebase.google.com/docs/dynamic-links/ios/receive)

なおリンク先に記載があるが、iOS９以降ではカスタムURLスキームと Universal Linksが両方使われる（アプリインストール直後のFDLのみ、カスタムURLスキームとして受け取る）事に注意。
IBMCloud Classic ICLB負荷テスト

##目的
Classic環境のIBMCloud Load Balancer(ICLB)に負荷を掛けてみた。
Apache JmeterにてICLB配下のWebサーバに負荷をかける。

##環境
* ローカル端末：macOS Catalina 10.15.7 1台
* プラットフォーム:IBMCloud
    * ロードバランサ:IBM Cloud Load Balancer(ICLB) 1サービス(**Private to Private**)
    * 負荷掛けサーバ:CentOS 7.7.1908(Virtual Server for Classic) 3台
        * apache-jmeter-5.3
    * 接続先サーバ:CentOS 7.7.1908(Virtual Server for Classic) 3台
        * Apache/2.4.6(prefork)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/e96c0323-2c62-ca03-6e43-21b1189921e9.png)


##結果
負荷がけサーバ:**35,000 Request x 3台　(200スレッド x 160グループ (RampUp200秒))**
コンテンツ:**1kb未満の静的コンテンツ**

ICLBは**一台辺りの最大接続台数は15,000**となる。
今回は最小二台構成の為、30,000セッションに届くかのみ確認した。
負荷掛けサーバはちょっとオーバースペックではあるが、確かに<font color=red>**ICLBの上限の30,000で頭打ち**</font>した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/c4b838f0-a1d1-8cb0-3551-be56e100f7e4.png)


実際のサーバ側で80:443のアクセス数をカウント
30,000には届いていないが、ほぼ同じくらいなのでよしとした。

```
SV1
watch -d -n 1 'netstat -alpn | grep -E ":(80|443) " | awk "{print \$5}" | sed -e "s/\:[^.]*$//" | sort | uniq -c'
Every 1.0s: netstat -alpn | grep -E ":(80|443) " | awk "{print \$5}" | se...  Mon Nov 23 00:54:28 2020
 4404 10.132.180.187
 5470  10.193.48.68
```

```
SV2
watch -d -n 1 'netstat -alpn | grep -E ":(80|443) " | awk "{print \$5}" | sed -e "s/\:[^.]*$//" | sort | uniq -c'
Every 1.0s: netstat -alpn | grep -E ":(80|443) " | aw...  Mon Nov 23 00:54:34 2020
 4254 10.132.180.187
 5143  10.193.48.68
```

```
SV3
watch -d -n 1 'netstat -alpn | grep -E ":(80|443) " | awk "{print \$5}" | sed -e "s/\:[^.]*$//" | sort | uniq -c'
Every 1.0s: netstat -alpn | grep -E ":(80|443) " | awk "{print \$5}" ...  Mon Nov 23 00:54:47 2020
 4354 10.132.180.187
 4243  10.193.48.68
```

ICLBで表示されるCPSがなんかおかしいが、途中経路のSRXで確認すると近い値となっていた。

```
> show security monitoring fpc 0 | match "Session Creation Per Second"
Total Session Creation Per Second (for last 96 seconds on average): 6817
```

また、同時接続が30,000というだけで順番にアクセスを分散させているっぽい
SRX側では11万セッション程度見れた。

```
> show security flow session summary
node0:
--------------------------------------------------------------------------
Unicast-sessions: 51312
Multicast-sessions: 0
Failed-sessions: 0
Sessions-in-use: 67502
  Valid sessions: 51157
  Pending sessions: 0
  Invalidated sessions: 8345
  Sessions in other states: 0
Maximum-sessions: 2097152
node1:
--------------------------------------------------------------------------
Unicast-sessions: 60101
Multicast-sessions: 0
Failed-sessions: 0
Sessions-in-use: 81705
  Valid sessions: 68092
  Pending sessions: 0
  Invalidated sessions: 6613
  Sessions in other states: 0
Maximum-sessions: 2097152
```

##所感
Classic ICLBは小規模環境向け、必要に応じてVPXを利用したほうが良さそう。
また、ICLBであればオートスケールするVPC環境の方がいいので、さっさとVPC環境に移行しよう
VPC環境であれば、最大16台までオートスケールするようだ(柔らか層本より)
[技術よりなひとが最初に読む　IBM Cloud柔らか層本（PPT）](https://ibm.ent.box.com/v/ibmcloud-yawaraka)

VPCスタート
[IBMCloud 今から無料で始めるVPC](https://qiita.com/khoshina/items/92b7e259df9d17247867)
〔備忘録〕pythonでHelloworldの出力

#基本の基本
まずはこれですよね。Helloworldの出力をします。この程度の記事だけど1日1投稿頑張りたいです。
#開発環境

-　Windows10
-　corei5
-　エディタはAnacondaから導入したVisual Studio Code

#さっそくやってみる
まずアナコンダを起動します。いま知ったのですが**shift+Windowsキー+s**で**範囲をしていしてスクショ**を取れるんですね。しかもそのままコピペできます。便利。左下のVS Codeを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/9445455d-594f-8929-64fe-35e1090736ff.png)
Vscodeが起動しました。もうすでにコードが記載されていますが、とりあえず備忘録のためそのまま行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/309e631d-b438-907a-513a-04380e87006c.png)
左上の作業用フォルダ（名前は任意。今回はqiita用とする。）を選択します。フォルダがない場合はフォルダ作成アイコンをクリックして任意の作業フォルダを作成してください。その後ファイル作成アイコンをクリックし「hello.py」というファイルを作成します。拡張子は.pyにするとパイソン用のファイルとなります。多少画像を加工してみました。パワーポイントで加工してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/150ddf28-cb0a-4217-e347-8d9e496b1a70.png)
ファイルが作成されました。右側の部分がコード入力領域です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/e220aec6-9ed1-0017-6a46-76f6e7e307dd.png)
下記のとおりコードを入力します。ちなみにMarkdownでqiitaの入力の際、下記のようにコード挿入する場合バッククオートでコードを囲む必要があります。バッククオートの出し方はWindowsの場合はshift+@で入力可能です。

```python:hello.py
print("hello world")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/8895000b-d897-a3c3-5c19-5b2d041bc81b.png)
今後実行しますが、一度保存しないと実行できないので、Ctrl+sで保存をしましょう。これ重要です。さあ実行です。実行には右上のターミナルでpythonファイルを実行をクリックします。すると右下のターミナルに実行結果が表示されます。なんだか達成感があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/890398/971a94d5-7c71-ff9d-95c9-3a5ceb382676.png)
GoでPostgreから取得したSelectクエリをJSONに変換する

## やりたいこと
- SELECT文で取得したクエリをまるごとJSONにしたい
- sqlパッケージのscanで一行ずつ処理しているようで、ループの中で配列を作る必要がある（？）
- 配列からjsonパッケージで変換する
- 参考のコードはMSのサイトにのっているやつ

## コード
```main.go
package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    _ "github.com/lib/pq"
)

const (
    // Initialize connection constants.
    HOST     = "127.0.0.1"
    DATABASE = "testdb"
    USER     = "root"
    PASSWORD = "password"
)

func checkError(err error) {
    if err != nil {
        panic(err)
    }
}

func main() {

    // Initialize connection string.
    var connectionString string = fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", HOST, USER, PASSWORD, DATABASE)

    // Initialize connection object.
    db, err := sql.Open("postgres", connectionString)
    checkError(err)

    err = db.Ping()
    checkError(err)
    fmt.Println("Successfully created connection to database")

    // Read rows from table.
    var id int
    var name string
    var quantity int

    sql_statement := "SELECT * from inventory;"
    rows, err := db.Query(sql_statement)
    checkError(err)
    defer rows.Close()

    // 構造を定義
    type data struct {
        ID int
        Name string
        Quantity int
    }

    // 配列の型を宣言
    var fruit []data

    for rows.Next() {
        switch err := rows.Scan(&id, &name, &quantity); err {
        case sql.ErrNoRows:
            fmt.Println("No rows were returned")
        case nil:
            fmt.Printf("Data row = (%d, %s, %d)\n", id, name, quantity)

            // 一行毎に配列を追加
            fruit = append(fruit,data{
                ID: id,
                Name: name,
                Quantity: quantity,
            })
        default:
            checkError(err)
        }
    }

    fruitjson, _ := json.Marshal(fruit)
    fmt.Println(string(fruitjson))

}
```

## 結果

```
yuta:~/postgre $ go run main.go 
Successfully created connection to database
Data row = (1, banana, 150)
Data row = (2, orange, 154)
Data row = (3, apple, 100)
Data row = (4, test, 100)
[{"ID":1,"Name":"banana","Quantity":150},{"ID":2,"Name":"orange","Quantity":154},{"ID":3,"Name":"apple","Quantity":100},{"ID":4,"Name":"test","Quantity":100}]
```

## 参考
https://docs.microsoft.com/ja-jp/azure/postgresql/connect-go
VirtualBoxが起動しなくなった時の対処法

## 環境
 * macOS Catalina 10.15.6
 * VirtualBox 6.1.4 r136177
 * 起動しなくなったVM名：Windows10

## 発生事象(エラー内容)
 * 以下のエラーメッセージとともに起動ができなくなる。
  * COMオブジェクトの生成に失敗しました。
  * NS_ERROR_FAILURE

## 発生手順
 * ホストOSのストレージが限界の状態でVirtualBoxを起動すると失敗し、それ以降上記エラーが表示され起動ができない。
 * VirtualBox設定ファイルが空になっていた。


## 解決策
* VirtualBox設定ファイルの修復
 1. `$HOME/Library/VirtualBox/`へ移動
 1. `VirtualBox.xml`を削除 
 1. `VirtualBox-prev`を`VirtualBox.xml`へリネーム
* イメージの修復
 1. `$HOME/VirtualBox VMs/Windows10/`へ移動
 2. `Windows10.vbox`を削除
 3. `Windows10.vbox-prev`を`Windows10.vbox`にリネーム
【備忘録】AWS LightSailでterminalからssh接続

#はじめに
AWS LightSailでデータサイエンス環境構築の練習の備忘録です

#目次
1. LightSailでインスタンスを作成
2. shh接続

#1. AWSのlightsailでインスタンスを作成する
https://lightsail.aws.amazon.com
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861809/792d06ee-fabd-aa7e-6602-2aa77859d971.png)

#2. ssh接続
アカウントページからプライベートキーをダウンロードする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861809/32e5844b-73cc-0dae-c900-f542e7d0203a.png)
アカウントページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/861809/412354b8-7aa1-0750-8de0-fd5a9a3676c9.png)

プライベートキーと設定ファイルを「~/.shh」ディレクトリに格納する

```bash
cd ~/.ssh
ls
Lightsail_ubuntu_20201123.pem	config
#Lightsail_ubuntu_20201123.pem・・・プライベートキー
#config・・・設定ファイル
```

```:~/.ssh/config
host lightsail_ubuntu
	HostName 3.112.200.82
	Port 22
	User ubuntu
	IdentityFile ~/.ssh/Lightsail_ubuntu_20201123.pem
```

ssh接続

```bash
ssh lightsail_ubuntu
```

もしくは、configファイルを設定せずにプライベートキーのオプションをつける方法もあります

```bash
ssh -i Lightsail_ubuntu_20201123.pem ubuntu@3.112.200.82
```


これで接続完了です！

##参考
・Amazon Lightsailのサーバにssh接続する
https://nana4-story.com/ssh-amazon-lightsail
AtCoder青を達成しました

[ARC107](https://atcoder.jp/contests/arc107)にてAtCoderの青コーダーになったので、記念に初投稿します。
青になるまでやったことを色々まとめます。
#1.AtCoderを始める前
プログラミング言語を知ることになったきっかけは、中一の6月頃に始めた[Swift Playgrounds](https://www.apple.com/jp/swift/playgrounds/)というもので、for文やwhile文、関数について学びました。
次に9月頃にPaizaを始めてPythonを色々学び、ランクBまで到達しました。
ここまではプログラミングに興味を持つきっかけなので、特にする必要はないと思います。
その後競プロについて知り、[APB4G](https://atcoder.jp/contests/APG4b)や[AOJ](http://judge.u-aizu.ac.jp/onlinejudge/)にて、Pythonによる基本的な競技プログラミングの問題の解き方を定着させました。
#2.AtCoder灰色期間
2019年11月に[DISCO2020予選](https://atcoder.jp/contests/ddcc2020-qual)のコンテストに参加し2完して、これがAtCoder参加初となりました。(Rated対象~2799のコンテストに参加した理由が分かりませんが、当時AtCoderに慣れていなかったのでまあいい)
次の[三井住友信託銀行プログラミングコンテスト2019](https://atcoder.jp/contests/sumitrust2019)にも参加しましたが、なぜかABC __F__(!)の4完を取ってしまいました。D問題とE問題はDPの知識が必要で分かりませんでしたが、Fは努力と根性で何とかなったと言うことでしょう。
そしてこの頃に[蟻本](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B3%E3%83%B3%E3%83%86%E3%82%B9%E3%83%88%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%96%E3%83%83%E3%82%AF-%E7%AC%AC2%E7%89%88-%EF%BD%9E%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E6%B4%BB%E7%94%A8%E5%8A%9B%E3%81%A8%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E3%82%92%E9%8D%9B%E3%81%88%E3%82%8B%EF%BD%9E-%E7%A7%8B%E8%91%89%E6%8B%93%E5%93%89/dp/4839941068)を買いました。しかし何もわからず、真剣に読んだのは緑色の頃から。
また、[JOI](https://www.ioi-jp.org/)にも参加して、1次予選300点、2次予選230点を取り終了。
[2次予選の1問目](https://atcoder.jp/contests/joi2020yo2/tasks/joi2020_yo2_a)でポスターを回転するのに配列を回転する関数を必死に探していたのは記憶に残っています。実際にrot90があったので良かったですが、見つからなかったら太陽だったでしょう。__回転の仕方問題文に書いてあるのに。問題文を読みましょう__(自戒)。
#3.~水色
この頃は、~~Pythonの豊富なライブラリ、[多倍長整数の特権](https://atcoder.jp/contests/abc152/tasks/abc152_e)、そして~~中学受験で鍛えた考察力を駆使して、レーティングを急上昇させました。最終的に[日立コンテスト2020](https://atcoder.jp/contests/hitachi2020)で早解き2完をして、水色になりました。
JOIの過去問をかなり解いていました。難易度4までをさくさく埋め、難易度5も7割程度埋めました。
#4.停滞
実をいうと、水色になるまでに学んだ競技プログラミングで主に用いるアルゴリズムは、__貪欲法__と__累積和__しかなく、このまま押し切るのは難しかったです。そのため蟻本に載っていたアルゴリズムを[けんちょんさんの問題集](https://qiita.com/drken/items/e77685614f3c6bf86f44)を解きながら定着させていきました。
また同時並行で水diffの問題を色々と漁っていったので、考察力も伸びていきました。
一旦緑に落ちましたが、DPやグラフの問題を解けたことで4完、5完が安定し、徐々にレーティングが上がっていきました。
#5.青色到達
ABC174から全てのABCで5完以上を達成し、レーティングが順調に伸びていきました。そして2020年10月31日に青色を達成しました。
次のABCで緑diffに1時間かけて水色に戻ってしまいましたが、その次のABCで全完黄perfを出して安定青コーダー(?)になることが出来ました。
#6.まとめ
典型アルゴリズムの習得と考察力のバランスが大切。アルゴリズムが身についていないと考察の結果このアルゴリズムを使おうと思っても出来なかったりします。
またABCの復習についてですが、自分のレーティング以下OR典型でない限り、復習はしていません。将来強くなったときに考察問題として使える可能性があるからです。
#7.次にやること
青になったのにも関わらず、ここ最近コンテスト中に青diffの問題を解けていないので、ひたすら過去問演習をします。
また蟻本の中級のアルゴリズム(セグ木、座圧、平方分割etc.)などを定着させていきます。
Unity Rewiredで接続されていないコントローラーのボタンマップ情報を取得する

#どういう状況なのか

Unityのコントローラー管理アセットRewired、便利ですよね。

さて、私が開発中のゲームではマルチプラットフォーム対応のため、実行しているデバイスに合わせて画面に表示するボタンのテクスチャを切り替える処理を作っています。

RewiredのAction名に割り振られたボタンの名称を取得して、その名前であらかじめ用意したSpriteAtlasからボタンのテクスチャを取得して表示するコンポーネントを作ろうと考えました。

しかし、Rewiredの通常のヘルパークラスでは「現在接続されている」コントローラーの情報しか取得できないため、開発用PCでは特定デバイスのコントローラーの情報を取得できません。

そこでやり方を調査しました。

#結論

MappingHelper.GetJoystickMapInstanceからとってきます。

https://guavaman.com/projects/rewired/docs/api-reference/html/Overload_Rewired_ReInput_MappingHelper_GetJoystickMapInstance.htm

```GetActionElementsInfoFromNotConnectedJoystick.cs
string rewiredActionName = "Attack";

var guid = new Guid("3eb01142-da0e-4a86-8ae8-a15c2b1f2a04");

var  joystickMap= ReInput.mapping.GetJoystickMapInstance(guid, "default", "default");

var actionElementMaps = joystickMap.GetButtonMapsWithAction(rewiredActionName);
        
Debug.Log(rewiredActionName + " " +actionElementMaps[0].elementIdentifierName);

```
こちらのスクリプトで、接続されていないコントローラー設定からアクション名でボタンの名前を引っ張ってこれるようになりました。

コントローラーのGuidで指定するところがミソで、GuidはAssets\Rewired\Internal\Data\Controllers\HardwareMaps\Joysticksの中の.assetファイルを選択して、インスペクターから「Launch Hardware Joisitck Map Edsitor」ボタンをクリックすると確認できます。

コントローラーの名称から引っ張って来れると楽だったのですが、
GUIDの他はControllerIdentifierかJoystickクラスの指定のみに対応しており、これらのクラスをランタイムでどっから取ってくるのか分からなかったためGUIDで解決しました。

以上
#5 【python3】文字列から文字を取り出す

#はじめに
この記事はプログラミングを勉強し始めて２ヶ月ほどの駆け出しエンジニアがアウトプット目的に書いている記事です。
ruby、jsをかじったのちトレンドであるpythonに興味を持ったので学習を始めました。
今回は文字列について記事を書いていこうと思います。
拙い記事になりますが、気になる点があればご指摘いただけるとありがたいです！
なお本記事は、macOSにpython3およびanacondaの導入をしていることが前提となっております。

#1 インデックス番号
文字列にはインデックス番号があります。

```python:sample.py
sample = "abcdefghi"
         #↑↑↑↑↑↑↑↑↑       
         #012345678 前からカウントした場合
       #-{987654321}後カウントした場合
```
文字列のインデックス番号は１文字目を０から数えます。
間違えやすい部分なので注意が必要です。後ろから数える際は-1から始めます。

#2 []で文字列を取り出す

```インタプリタ
>>>sample = "abcdefghi"
```
[]を使ってインデックス番号２のcを取り出してみます。

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample [2]
'c'
```
文字列からcを取り出せました。
今度は後ろからカウントした場合のインデックス番号を利用してcを取り出してみます。

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample [−７]
'c'
```
無事文字列を取り出すことができましたが、一つ注意点があります。
インデックス番号で文字列を取り出すことは狩野ですが、書き換えることはできないということです。

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample [−７]　= "j"
  File "<stdin>", line 1
    sample [−７]　= "j"
             ^
SyntaxError: invalid character in identifier
```
このようにsample[-7]を"j"に置き換えようとするとエラーが出てしまいます。

#3 部分文字列を呼び出す
[]を使って範囲を指定して文字列を取り出すことも可能です。

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample[1:4]
   #文字列[開始番号:終了番号]
'bcd'
```
上記ではインデックス番号1のaから4のdまでを選択して取り出しています。
また開始番号と終了番号は省略することが可能です。

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample[:4]
   #文字列[:終了番号]
'abcd'
```
この場合は文字列の最初から番号４までを範囲指定しており

```python:インタプリタ
>>>sample = "abcdefghi"
>>>sample[1:]
   #文字列[開始番号:]
'bcdefghi'
```
この場合は番号1から最後までを範囲指定できます。

#終わりに
今回の記事は以上で終了です。
文字列のインデックス番号は１文字目を０から数えるということはわかっていても、間違えやすいの注意したいですね。

前の記事→https://qiita.com/shin12032123/items/a8cc0d7612259683562e
【ElastiCache】ElastiCacheとは

## ElastiCacheとは
インメモリキャッシュデータベースのマネージドサービス

- KVS型で、キャッシュとしての利用に適する
- 書き込み・読み込みが高速である
- トランザクション機能は無く、完全性を求められるデータの保存には適さない
- 利用可能なデータ容量に制限がある
- アプリケーションが高速なI/Oを必要とする処理を行う場合、一時的にElastiCacheにデータを格納し処理を行うことでパフォーマンスの向上が可能

### ユースケース
- セッション管理
- IoT処理とストリーム分析
- メタデータの蓄積
- pub/sub処理　※
- DBキャッシュ処理
- ソーシャルメディアのデータ処理・分析　　　など

**pub/sub処理**
「イベントを起こす側」と「イベント処理を行う側」を分離するpub/subモデルを活用した処理
（例）メッセージ処理、チャットアプリ

## ElastiCacheのエンジン
**1. Memcached用ElastiCache**：扱うデータ型・暗号化・高可用性構成・コンプライアンスなどへの対応が不要なシンプルな利用に適する

**2. Redis用ElastiCache**：複雑なデータ型・暗号化・高可用性構成・コンプライアンスへの対応がサポートされているミッションクリティカルな業務用途に適する

||Memcached用ElastiCache|Redis用ElastiCache|
|:-:|:-:|:-:|
|データ型|シンプル|複雑|
|暗号化|なし|あり<br>保管時・通信時をそれぞれ設定可|
|コンプライアンス認証<br>（FesRAMP/HIPAA/PCIDSS）|なし|あり|
|マルチスレッド|あり|なし|
|高可用性（レプリケーション）|なし|あり|
|自動フェイルオーバー|なし|必須|
|スナップショット機能|なし|あり|
|バックアップと復元|なし|あり<br>バックアップ保持期間はデフォルト1日|
|pub/sub機能|なし|あり|

## データ書き込み方式
###遅延読み込み
データ読み込み時にキャッシュを参照し、ヒットしなかった場合にデータソースから必要なデータを取得してキャッシュに書き込む方式

**メリット**
・リクエストされたデータのみをキャッシュするため、データ使用量が比較的少ない
・障害発生時にノードが空になった場合、レイテンシーは高くなるがシステムを継続して使用可能

**デメリット**
・キャッシュミス時のレイテンシーが高い
・キャッシュヒット時にはキャッシュデータを更新しないため、キャッシュデータが古い可能性がある

### 書き込みスルー
データ書き込み時にキャッシュにも書き込みを行い、データは全てキャッシュから読み込む方式

**メリット**
・キャッシュのデータが常に最新となっている
・読み込み時のキャッシュミスが発生しない

**デメリット**
・障害発生時にノードが空になった場合、データの読み込みが行えない
・データソースへの書き込み後、キャッシュへの書き込みに失敗した場合にデータが欠落する
・メモリの使用量が多い
JavaScript基礎まとめ

JavaScriptの基礎を自分の備忘録＆アウトプットも兼ねて記述。

そもそも、、JavaScriptはWEBページ内でページ遷移や更新をせずに画面を表示できる。
つまり、読み込む時間がないのでユーザーはストレスなく使えるということ。

検証ツール（ディベロッパーツール）で確認ができる（Rubyでいうirb的なやつ）
右クリック＋検証、または⌘ + option + Cで出せる

１．変数定義
var(ほとんど使わないらしいから省略）
const
let　の３種類


・const　再代入、再定義NG

```javascript

const sample = "Hello"
sample = "Hello" 
再代入NG
const sample ="こんにちは"
再定義もNG
```

・let

```javascript

const sample = "Hello"
sample = "Hello" 
再代入OK
const sample ="こんにちは"
再定義はNG
```

２．テンプレートリテラル
文字の中に変数を入れる

rubyだと　

```ruby

name = "yamada"
puts #{name}さん
```
だったのが

```
const name = "yamada"
console.log(`${name}さん`）
```

この``で囲うのがテンプレートリテラル

３．条件分岐

```javascript

if (条件式1) {
  // 条件式1がtrueのときの処理
} else if (条件式2) {
  // 条件式1がfalseで条件式2がtrueのときの処理
} else {
  // 条件式1も条件式2もfalseのときの処理
}

```

rubyとの違いは
条件式を（）で囲ったり、条件式の後の処理は｛｝で囲うこと、
elsif ではなく　else ifぐらい、、？


４．繰り返し（for文）

```javascript

for ([①初期化式]; [②条件式]; [③加算式]) {
  // 繰り返す処理の内容
}
```

①初期化式
変数の定義をする
②条件式　
処理内容を何回繰り返すか
③加算式
①で定義をした変数の増減を書く

```javascript

let name = ['A','B','C','D','E']
for (let i = 0; i <= name.length; i ++) {
  console.log(name[i])
}
```
①②③で考えると
①変数 i = 0
②配列の中から i 番目を取り出す（現時点ではi=0としている)
このi番目の長さがnameの配列の個数以上になるまで繰り返す
③繰り返す度にiに1ずつ加えていく


、、、もし間違えている点があればコメントいただきたいです！よろしくお願いいたします。
【自分メモ】モデル/コントローラー/ビューの役割

モデル…コントローラーで定義したインスタンス変数にデータを入れるため、コントローラーからモデルへデータを取ってくるよう指示が出る(モデル名.all)→指示を受けたモデルはデータベースからデータを取得後、コントローラーのインスタンス変数へ入れる。
またコントローラーから指示を受けて新しいオブジェクトを作成する(モデル名.new)。

コントローラー…インスタンス変数に入れるデータをモデルに持ってくるよう指示を出したり、そのインスタンス変数をビューに渡したりする。

ビュー…コントローラーから受け取ったインスタンス変数を元にhtmlファイルを作成する。

※自分の考えをメモとして残していますので、間違っていたり修正した方が良い点がございましたら、ドシドシつっこみいただけると嬉しいです！
リレーショナル代数 （関係演算）


### リレーショナル代数とは？

---
リレーショナル代数とは、1972年に E.F.Codd 氏によって提唱された演算の集合で
選択、射影、直積、和集合、差集合、共通集合、結合を定義しテーブルを操作する。

> PostgreSQL 7.1.2 ドキュメント(日本語版 1.0)より
https://cellbank.nibiohn.go.jp/legacy/information/pc/postgres_man/relmodel-oper.html

---
#### 選択（行の抽出）
・テーブルからすべての列を選択し、条件に合致した行を抽出する

```
SELECT *
FROM TABLE NAME
WHERE 条件
```
---
#### 射影（列の抽出）
テーブルから必要な列だけを抽出する

```
SELECT 抽出したい列を指定
FROM TABLE NAME
```
---
### 集合演算
和集合(OR)、差集合、共通部分集合(AND)
> 参考
http://www.cs.reitaku-u.ac.jp/infosci/rdb/rdb02.html
---

### 直積演算
全てのタプルの組み合わせる演算（直積集合演算）

---
### 結合
結合とは、複数のテーブルから1つのテーブルにする操作の事（内部結合、外部結合、等結合）

---
#### 内部結合（INNER JOIN）

2つのリレーションから、指定した属性の値が一致するタプルのみを取得して結合する
(指定したタブルはドット演算子で繋ぐ）

---
#### 外部結合
2つのリレーションから、指定した属性の値が一致するタプルに加えて、どちらか一方のリレーションにしかない属性値を持つタプルも含めて取得して結合

---
#### 等結合
結合の条件式(F)で比較演算子が "=" である結合演算
同じ属性列が重複してしまう

---
#### 自然結合
等結合の結果から重複する属性列を除去した結合演算

---
### other

---
#### ドット記法
異なる直積の属性名を.(dot)により結合することができる

Exp) 仕入れ商品.仕入商品

---
#### 商演算
2つのリレーション(RとS)から(S)の全ての属性の値を同時に満たす(R)のタプルを抽出し、(S)の属性を取り除いた列を取り出す演算
特殊な演算あまり使用されない

---
#### 改名演算
属性の名前を付け替える演算
リレーション(R)の属性(B)の名前を(A)に変更する時σa←b(R)で表現する
【React Hooks】 useEffectの動作タイミングをきっちり理解する

# useEffectとは
- React Hooksにおいて```ライフサイクルメソッド```を関数コンポーネントで実現する仕組み。
- classコンポーネントで言うcomponentDidMountなどに相当する。
- 1つの関数コンポーネントに複数記述しても良い。

# サンプルコード
以下のサンプルコードを用いて解説したい。

```react
import React, { useEffect, useState} from 'react';
import './App.css';

const App = props => {
  const [state, setState] = useState(props)
  const { id, name } = state

  useEffect(() => {
    console.log('#001:レンダリング毎に呼ばれる')
  })

  useEffect(() => {
    return () => console.log('#002:アンマウント直前に呼ばれる')
  })
  
  useEffect(() => {
    console.log('#003:マウント時とアンマウント時にのみ呼ばれる')
  },  [])

  useEffect(() => {
    console.log('#004:特定のstateが変更された場合のみ呼ばれる')
  },  [name])

  return (
    <>
      <p>id:{id} name:{name}</p>
      <p>id:<input value={id} onChange={e => setState({...state, id: e.target.value})} /></p>
      <p>name:<input value={name} onChange={e => setState({...state, name: e.target.value})} /></p>
    </>
  )
}

App.defaultProps = {
  id: 'Id001',
  name: 'NoName'
}
```

# レンダリング時
以下のように記述するとrenderメソッドが走る度に処理が呼ばれる。初回のレンダリング時はもちろんであるが、stateやpropsが更新された際にも呼ばれることとなる。

```react
 useEffect(() => {
    console.log('#001:レンダリング毎に呼ばれる')
  })
```

# アンマウント時
useEffect内で関数をリターンさせるとアンマウント時の処理を記述できる。

```react
  useEffect(() => {
    return () => console.log('#002:アンマウント直前に呼ばれる')
  })
```

# マウント時およびアンマウント時
空配列```[]```を第２引数に指定するとマウント・アンマウントに限定させることができる（001のように更新時には呼ばれなくなる。）

```react
  useEffect(() => {
    console.log('#003:マウント時とアンマウント時にのみ呼ばれる')
  },  [])
```
# 特定のstateが更新された時
特定の値が更新された場合に限定したい場合は、第２引数の配列に変数名を記載すれば良い。下記の例では```name```が更新された時(nameを保持するinputのonChangeが呼ばれた時)にのみ実行される。

```react
  useEffect(() => {
    console.log('#004:特定のstateが変更された場合のみ呼ばれる')
  },  [name])
```
PHPスクリプトで発生したエラーがどの出力レベルで報告されるのかを確認するスクリプト

この記事は，**[PHP Advent Calendar 2020](https://qiita.com/advent-calendar/2020/php)** 3日目の記事として公開される予定です（11月23日記載）．

今年のカレンダーは @rana_kualu  さんが作成してくれました．ありがとうございました．

## 本題

phpのスクリプトで発生したエラーについて，そのエラーがどの出力レベルで報告されるかを確認するスクリプトです．

```error_reporting.sh
#!/bin/bash

SCRIPT_NAME="$1"

LEVELS=(E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_STRICT E_RECOVERABLE_ERROR E_DEPRECATED E_USER_DEPRECATED)

for LEVEL in ${LEVELS[@]};
do
  echo "${LEVEL}"
  php -d error_reporting=${LEVEL} "$1"
done
```

実行結果はこんな感じです．

```terminal
$ . ./error_reporting.sh e_notice.php 
E_ERROR
E_WARNING
E_PARSE
E_NOTICE
PHP Notice:  Undefined variable: a in /home/taro/projects/php-fun/e_notice.php on line 4
PHP Stack trace:
PHP   1. {main}() /home/taro/projects/php-fun/e_notice.php:0
E_CORE_ERROR
E_CORE_WARNING
E_COMPILE_ERROR
E_COMPILE_WARNING
E_USER_ERROR
E_USER_WARNING
E_USER_NOTICE
E_STRICT
E_RECOVERABLE_ERROR
E_DEPRECATED
E_USER_DEPRECATED

```

読み込んだファイルです．

```e_notice.php
<?php

echo $a;
```

以上 [PHP Advent Calendar 2020](https://qiita.com/advent-calendar/2020/php) 3日目でした．

明日は @yoshikyoto さんです．

## 参考・関連

- [PHP: 実行時設定 - Manual](https://www.php.net/manual/ja/book.errorfunc.php)
- [PHP: 定義済み定数 - Manual](https://www.php.net/manual/ja/errorfunc.configuration.php#ini.error-reporting)
- [ソースコード](https://github.com/tarohida/gomibako-php/blob/main/error_reporting.sh)
Enumerator::Lazy でエラトステネスの篩

Enumerator::Lazy は無限数列を扱うことができるが、それを使って「エラトステネスの篩」をちょっとおもしろく実装できることに気づいた。何はともあれコードである。

```ruby:lazy_prime.rb
prime_seq = Enumerator.new do |y|
  sieve = 2.step.lazy
  loop do
    a = sieve.first
    y << a
    sieve = sieve.reject {|x| (x % a).zero?}
  end
end

prime_seq.take(10)    #=>[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
```
　
Enumerator::Lazy は`sieve = 2.step.lazy`のところで生成している。これの先頭`a`は必ず素数なので、素数列として Enumerator で取り出す（`y << a`）。そして、`sieve`から`a`の倍数を`reject`ですべて篩い落とし（Lazy だから可能なのである）、そうされたものを新しい`sieve`とする。以下、繰り返し、というわけである。

これは子供の頃に紙と鉛筆でやってみた「エラトステネスの篩」のやり方そのものである。小さい方から素数に丸でも打っておいて、その倍数を斜線で消していく…。実装としては、素直といえば素直だ。

しかし、これ、めちゃめちゃに遅いのはすぐわかる。素数ひとつ得るたびに、Enumerator::Lazy オブジェクトを作り直しているのだから、どれほど遅いかというと、例えば最初の 500個の素数を得るのに、この方法だとわたしの環境でなんと 2.8秒ほどもかかる。標準添付ライブラリの prime を使うと 0.0002秒ほどだから、比較にもならない。

でもまあ、ちょっとおもしろかったので書いてみた。


なお、単なる Enumerator ももちろん無限数列を扱うことができるが、`map`や`select`、それにここで使った`reject`などの結果が有限数列（Array）になってしまう。なので、Enumerator::Lazy を使ったのである。為念。


以上はブログ記事の転載です。
SpringBootでJacksonを使おうとしてちょっとハマった

#Jakcson使おうとしてちょっとハマった。
SpringBootでトークンによる認証つきのRestfulAPIを開発中。
認証エラーが起きた時のエラーレスポンスをjacksonで行おうと思い、bulid.gradleにjacksonの設定を記述しコンパイル。しかし以下のエラーが吐かれてしまった。

```
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/databind/ser/std/ToStringSerializerBase

Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase
```

#原因究明
###1. 依存ファイルの記述が足らない？
この時点での自分のbuild.gradleは以下のようになっていた。

```
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.4'
```

しかし、[このページ](https://stackoverflow.com/questions/44718345/java-lang-noclassdeffounderror-com-fasterxml-jackson-databind-exc-invaliddefini)を見てみるとどうやらjackson-databindだけではなくjackson-core、jackson-annotationも必要らしい。ということで

```
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.4'
    implementation 'com.fasterxml.jackson.core:jackson-core:2.9.4'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.9.4'
```
追加。

しかし、コンパイルはうまくいかず最初のものと同じエラーが出てしまった。
困った。

###2. バージョンが古い？
頭をかきつついろいろ調べていると、今度は[このページ](https://gist.github.com/kemsakurai/8e124ab4df1b741055fbbc1757c15e9d)に行き着いた。
>アプリケーションの pom.xml で定義していた Jackson の version と Dropzwizard が必要とする version が異なっていたために発生していた。アプリケーションでは、2.7.4 を定義していたが、Dropwizard の最新版 1.3.4 が 依存する Version は、2.9.6 で以下の通り、pom の dependency を書き換えた。

バージョンが古いとうまくいかないことがあるらしい。
早速、「jackson version」でググってみると[公式ページ](https://openstandia.jp/oss_info/jackson/version/)がヒットし、最新バージョンが2.11.2であることが判明。そこで、さらに以下のように書き換え。

```
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.2'
    implementation 'com.fasterxml.jackson.core:jackson-core:2.11.2'
    implementation 'com.fasterxml.jackson.core:jackson-annotations:2.11.2'
```

すると、うまくいった！

#まとめ
[このページ](https://gist.github.com/kemsakurai/8e124ab4df1b741055fbbc1757c15e9d)で筆者の方もおっしゃられている通り、
>ライブラリでの、NoClassDefFoundError はほとんどは 依存ライブラリの version が古いか、新しいかのどちらかで発生するように思う。

ということだろう。しっかり最新バージョンを調べて使おう！（当たり前）

#参考文献
- https://stackoverflow.com/questions/44718345/java-lang-noclassdeffounderror-com-fasterxml-jackson-databind-exc-invaliddefini
- https://gist.github.com/kemsakurai/8e124ab4df1b741055fbbc1757c15e9d
- https://openstandia.jp/oss_info/jackson/version/
【Java】getter・setterのメモ

# getter・setter
## getter・setterとは
結論から言うと、private になっている[フィールド変数]を

- **変更するのが setter**
- **取得するのが getter**

です！
なぜ、どうして、どのように使うのかというのは、カプセル化したものを扱うためです。

## getter
**getter** は **「[フィールド]の値を取り出すだけの[メソッド]」** です。

前述の通り、private に設定された[フィールド]は外部からアクセスが出来ないので、[メソッド]を介してアクセスする必要があり、それが **getter** というわけです。

### getter の書き方
こちらがgetter [メソッド]の書き方になります。

```
//フィールド変数を定義
private データ型 フィールド名

// getter
public データ型 getフィールド名() {
    return this.フィールド名;
}
```
こちらは、number という[フィールド変数]に対して作った getter のサンプルです。

```java
// フィールド変数
private int number;

// Getter
public int getNumber() {
    return this.number;
}
```

## getter の命名規則
getter の**命名規則は setter と同じです。**

- **[フィールド]名の頭に「 get 」をつけたキャメルケースで書くこと。**( 例: getName )
- **getter, setter は** 外部で扱えなくてはいけないため、**すべて 「public」で記述すること！**






## setter
setter は単純に**「フィールドに値を代入するためのメソッド」** です。

### setter の書き方
こちらがsetter メソッドの書き方になります。

```
// フィールド変数
private int number;
// setter
public void setNumber(int number) {
    this.number = number;
}
```

こちらは、number というフィールド変数に対して作った setter のサンプルです。

```java
// フィールド変数
private int number;
// setter
public void setNumber(int number) {
    this.number = number;
}
```

## setter の命名規則

先程述べたように、setter の**命名規則は getter と同じです。**

- **[フィールド]名の頭に「 get 」をつけたキャメルケースで書くこと。**( 例: getName )
- **getter, setter は** 外部で扱えなくてはいけないため、**すべて 「public」で記述すること！**



## setter をチェックを掛けて使う
setterメソッドを使って書き込むことで、**書き込むデータのチェックを行うことが出来ます。**

例えば、[フィールド] に100以下の値しか入れたくない場合、[フィールド]に直接値を書き込む場合は書き込む側がチェックをする必要があります。
しかし、setter[メソッド]であれば、[メソッド]の中でチェックしておけば書き込む側の手間がなくなり安全性も高くなります。

```java
// フィールド変数
private int フィールド名;

// setter
public void setフィールド名(int 引数名) {
	if ( 条件式 ){
    this.フィールド名 = 引数名;
	}
}
```

[インスタンス]:https://qiita.com/takahirocook/items/ec01cdcbb440cf0d1cc4
[インスタンス化]:https://qiita.com/takahirocook/items/ec01cdcbb440cf0d1cc4
[アクセス修飾子]:https://qiita.com/takahirocook/items/e51b0b9d37d95ad587fe
[フィールド]:https://qiita.com/takahirocook/items/28df75a133049a74ece1
[フィールド変数]:https://qiita.com/takahirocook/items/28df75a133049a74ece1
[new演算子]:https://qiita.com/takahirocook/items/00f9f97592bf50831d39
[カプセル化]:https://qiita.com/takahirocook/items/e469a7c0539a0012868e
[クラス]:https://qiita.com/takahirocook/items/50cbbdca8e21539170e9
[メソッド]:https://qiita.com/takahirocook/items/5bfe43576d87a2a4006c
[mainメソッド]:https://qiita.com/takahirocook/items/f4635915337303de338c
[メソッドの呼び出し]:https://qiita.com/takahirocook/items/f4635915337303de338c
[コンストラクタ]:https://qiita.com/takahirocook/items/fa1822f2f22c3786593e
[引数]:https://qiita.com/takahirocook/items/5e5b0ba79e869f4a592e
[戻り値]:https://qiita.com/takahirocook/items/3b6fa670a1d6dd4a9386
[this]:https://qiita.com/takahirocook/items/d251ec4693c68f6b9538
GitHub Releasesからインストールしたコマンドを管理するツールを作った

GitHub Releasesから取得したコマンドを所定のパスに配置して、
一括アップグレードできるようにするコマンドを作りました。

![demo.gif](https://user-images.githubusercontent.com/13825004/97173868-94b00000-17d4-11eb-8f59-f3ca7fdb5ae6.gif)

なぜ作ったかと、仕組みについて書きます。

# なぜ作ったか

インストールしたコマンドのアップグレードをするのが面倒だったのを解消したかったからです。

GitHub Releasesから取得するタイプのコマンドをインストールする時、僕は以下のようなコマンドを実行します。

```bash
cd /tmp
wget https://github.com/jiro4989/nimjson/releases/download/v1.2.8/nimjson_linux.tar.gz
tar xzf nimjson_linux.tar.gz
mkdir -p ~/bin
install -m 0755 ./nimjson_linux/bin/nimjson ~/bin/
```

インストールする時は特にこれで不便ありません。
ですが、コマンドをアップグレードしたくなった時に困りました。

主に以下の問題に遭遇しました。

- このコマンドどこから取得したっけ？
- どうやってインストールしたっけ？
- そもそも新しいバージョン出てるんだっけ？

この問題はGitHub Releasesから取得するコマンドが増えるほど大きくなりました

# ソースコード

前述の問題を解消するために`relma`というコマンドを作りました。

https://github.com/jiro4989/relma

Windowsでも動作します(管理者権限が必要ですが)。

# 使い方

## インストール方法

最初に `init` で初期化して、 `install` にリリース物のURLを渡してあげるだけです。

これでリリース物の圧縮ファイルを展開して `$HOME/relma/bin` に実行可能ファイルのシンボリックリンクが配置されます。

```bash
relma init
relma install https://github.com/jiro4989/nimjson/releases/download/v1.2.8/nimjson_linux.tar.gz
```

## アップグレード方法

以下の様に `update` して `upgrade` するだけです。

`update` では最新バージョンの有無をチェックし、バージョン情報をローカルに保存します。
`upgrade` を実行するとアップグレード可能なパッケージをすべてアップグレードします。

```bash
relma update
relma upgrade
```

## インストールしたパッケージの確認方法

relma でインストールしたパッケージの一覧を確認する場合は `list` を実行します。

```bash
relma list
```

# 仕組み

## インストール方法

`relma install` に渡したURLのファイルをローカルに落し、所定のパスに展開してシンボリックリンクを作ります。

```bash
$HOME/
    relma/
        bin/
            command.exe # シンボリックリンク
        releases/
            $OWNER/
                $REPO/
                    $VERSION/
                        $RELEASE_FILE.tar.gz
                        assets/
                            command.exe # 実体
```

リリースファイルの展開後のディレクトリ構造にはある程度パターンがあります。

大体は以下の 3 パターンのいずれかだろう、と考えました。

これらの展開後のディレクトリ構造を判別して実行可能ファイルのパスを特定し、 `$HOME/relma/bin` 配下にシンボリックリンクを作成します。

```bash
release_v1.0.0.zip/
    command.exe         # コマンドだけ配置されるケース

release_v1.0.0.zip/
    release_v1.0.0/
        command.exe     # 圧縮ファイル名のディレクトリ配下に
                        # コマンドが配置されるケース

release_v1.0.0.zip/
    release_v1.0.0/
        bin/
            command.exe # 圧縮ファイル名のディレクトリ配下に
                        # bin ディレクトリが配置され、
                        # その下にコマンドが配置されるケース
```

## アップグレード時のインストールURLの特定方法

GitHub Releasesで公開されているコマンドの多くは、リリース手順を自動化されています。

ローカルで手動で叩くコマンドか、あるいはCIからか、手段は違えど大なり小なり自動化されている場合が多いです。

また、リリースファイルの命名も、リポジトリごとに違えど、概ね命名が決まっていて、「リリースファイル名に含まれるバージョン番号だけが異なる」という点で共通点があります。

よって、 `relma install` に指定したURLのバージョン番号をリリースのタグ番号で差し替えれば、次のバージョンのリリースファイルを取得するURLが特定できるのでは、と考えました。

```bash
https://github.com/jiro4989/nimjson/releases/download/${VERSION}/nimjson_${VERSION}_linux.tar.gz
```

しかし、開発者が毎回手動でリリースファイルを作っていて、命名が不規則だったり、タグとバージョン番号が不一致になるケースもあると思います

これはサポート外としました。

あらゆるリポジトリをサポートするつもりはないですし、命名が不規則なのはリポジトリのオーナーの管理の問題と考えます。

# まとめ

- relma コマンドの使い方を説明しました
- relma コマンドの仕組みを説明しました

コマンド管理に立てば幸いです。

以上
docker環境でlsb_releaseがエラーになる時にコマンドラインからlsb_releaseをインストールする

docker環境でlsb_releaseがエラーになる時

```
# lsb_release -sc
bash: lsb_release: command not found
```

以下の通り、コマンドラインからlsb_releaseをインストールする

```
apt-get update -y;apt-get install -y lsb-release;
```
AWSのEC2にGUI環境を構築する

学習環境が欲しくて、EC2にGUI環境を構築したら、思いのほか苦戦したのでメモ。

# 環境
サーバー : Amazon Linux 2 
クライアント : Mac

# 事前準備
・AWSのアカウント作成
・[EC2作成](https://qiita.com/r_saiki/items/dfc6122aaeb830256cf8)
・[EC2にSSH接続](https://qiita.com/r_saiki/items/cc1d7ed9864ce07501f2#ssh%E6%8E%A5%E7%B6%9A)

# GUI環境構築
[公式](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-2-install-gui/)から、ほぼコピペして進める。

~~~
# MATEデスクトップ環境のインストール
$ sudo amazon-linux-extras install mate-desktop1.x
# 全てのユーザーにMATEをデフォルト設定
$ sudo bash -c 'echo PREFERRED=/usr/bin/mate-session > /etc/sysconfig/desktop'
# TigerVNCをインストール
$ sudo yum install tigervnc-server
# VNCのパスワード設定をした後に画面表示専用のパスワードを聞かれるので「n」で入力
$ vncpasswd
~~~

起動時に常にVNCサーバーを起動するように設定。

~~~
$ sudo cp /lib/systemd/system/vncserver@.service /etc/systemd/system/vncserver@.service
$ sudo sed -i 's/<USER>/ec2-user/' /etc/systemd/system/vncserver@.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable vncserver@:1
$ sudo systemctl start vncserver@:1
~~~


xstartupファイルにMATEを実行するコマンドを追加する。（これを追加しないと繋がっても真っ黒い画面になり操作できない・・・ここで苦戦した）

~~~:~/.vnc/xstartup
#!/bin/sh
exec mate-session
〜(以下略)〜
~~~

VNCサーバーを再起動。

~~~
$ sudo systemctl daemon-reload
$ sudo systemctl restart vncserver@:1
~~~

# Google Chromeのインストール
[公式](https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-linux-2-install-gui/)から引用。

~~~
$ sudo amazon-linux-extras install epel
$ sudo yum install chromium
~~~

# Macからリモート接続

sshでポートフォワーディングを有効にするオプションを付けて繋ぎなおす。
PEM_FILE : 鍵のパス
INSTANCE_IP : 接続先IP

~~~
ssh -L 5901:localhost:5901 -i PEM_FILE ec2-user@INSTANCE_IP
~~~

Finder→移動→サーバへ接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/ac910b05-71a5-e91e-88d8-eb40398ae704.png)

接続するとパスワードを聞かれるので、先ほど設定したVNCのパスワードを入力する。
ログインに成功すると以下の画面になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/ca0019e0-b165-ebba-bb85-ff94115f8afd.png)

# 終わりに
無事に作業環境を構築できて良かった〜！
余裕があれば他のOSも挑戦したい。
VScodeでsettings.jsonが見つからない

## 調べた
erbファイルでもemmet記法でタグを短縮して記述できるよう調べていたのですが、VScodeのセッティングでsttings.jsonが見つかりませんでした。

設定方法の記事はたくさんありました。以下を参考にしました。
参考：https://qiita.com/Mr_ozin/items/d7fb30ed56347f6d222e

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693815/744e9b5b-e618-12dd-e6eb-06edfca23457.png)

## 結論
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693815/f526f87e-f28a-976f-453b-6dd120a03b91.png)
settingと入力すると画像下にsettings.jsonで編集と書かれたリンクが見つかるのでそれをクリックすると無事にsettings.jsonファイルにたどり着けました。

```json:settings.json
    "emmet.includeLanguages": {
        "erb": "html", //erbで使いたい時
        "vue": "html", //vue.jsで使いたい時
        "vue": "css", //vue.jsで使いたい時
        "javascript": "javascriptreact", //React.jsで使いたい時
    }
```
SAAとった勉強方法と実務経験して感じた事

この記事は [AWS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/aws) 17日目の記事です。

## はじめに

AWSの認定資格であるソリューションアーキテクト・アソシエイト（以下SAA）を取得して、AWSを本格的に業務で構築するようになったので、資格をとった事によるメリットを書いていきたいと思います。

「資格取りたいけど・・・実際のところどうなん？」と、迷っている方の助力になれたらなと思います。

## 資格を取ろうと思った経緯

~~会社が費用を出してくれるからです~~
本音を書くと一行で終わってしまうので具体的にいうと、やはりサーバーサイドエンジニアとしてAWSはやっておくとメリットは大きいと思ったからです。

主に以下の通り。

### １、パブリッククラウドでAWSがトップである
エンジニアならインフラやってなくても誰もが知っているであろうAWS。
その仕組みを理解しておくことは、サーバーサイドの開発を行う上でも大きな力になります。

### 2、クラウドの特性を活かしたシステムを作る事ができる
クラウドならではのインスタンス性を利用したオートスケールとかはその最もたる例だと思います。
AWS独自の仕様もかなり多いので、理解すると最適化して組む事が出来るようになります。

### 3、キャリアの幅が広がる
他の領域との組み合わせでスキルを持っておくと、その分、エンジニアとしての能力の幅が広がります。
特にサーバーサイドエンジニアの方にとっては、親和性も高いのでメリットは大きいと思います。

と、色々と書いていきましたが、役に立つ立たないに限らず、何らかの目に見える結果があると自分がレベルアップした感覚になるので、自信をつけるという意味でも良いと思います。

## 勉強のプロセス

本題に入る前に、SAAをどのように勉強したかを簡単に書いておきます。
実際に取ろうと思う方は参考にして頂けると幸いです。
```私が取得したのは2019年１０月なので、現在の試験内容とは違う点もあると思うので、あくまで参考でおねがいします```

### １、参考書を何周もやった
試験勉強定番のやり方ですね。参考書を買ってひたすら読んで付属の演習問題を理解出来るまでやりました。
「読むだけでは頭に入ってこない」という意見もありますが、私的には言葉の意味や仕組みを目で追うだけでも意味はあると思っています。
というのもじっくり見るわけではなく、とにかく全ての章をざっと何周もするやり方でやったからです。
この方法だと初回よりも２周目、２周目よりも３周目と繰り返すうちに理解度が上がっていくのを感じる事ができます。
大体６、７割程度の理解で次の章に進むのがよいでしょう。
５周くらいやる頃にはほぼ理解しているはずです。

### ２、BlackBeltスライドをひたすら読んだ
私の読んだ参考書は深い所まで解説はしていなかったので、理解を深める為にもBlackBeltのスライドを各サービス毎に読んで理解することを繰り返しました。
ただスライドを見てもらうと分かるのですが・・・枚数が非常に多い！
一つのサービスで８０くらいあります。じっくり読んでいたらめちゃくちゃ時間かかります。
なので私は全部ではなくEC2やS3など主要サービスに絞って繰り返しました。どれが主要サービスなのかは参考書で説明しているサービスがそれだと思ってもらって問題ないと思います。

BlackBeltの資料は[こちら](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)になります。

### ３、全体像を理解することに注力した
SAAはその名の通り、アーキテクト的な問題が殆どです。
サービス単体に関しての質問もあると言えばあるのですが、割合的には少なかった気がします。
なのでAWS上に各サービスを連携してどのように作っていくのがいいのか。を頭で描く練習をしておくといいかなと。

まとめると以上のような感じでしょうか。
３つにまとめましたが、ほぼこれだけで一発合格しました。
私はスコアが750だったので結構ギリギリでしたがｗ分からない問題は後に回すという基本テクニックでなんとか乗り切りました。

## 実務を担当した結果

SAAを取る前はほぼAWS触った事のない素人だったのですが、取得をきっかけに担当になることになりました。
かなりざっくりとですが、既存アーキテクチャの見直し、EC2からECSへの移行など、かなりダイナミックにやらせて頂きました。

まず一番のメリットは各サービスの特性を分かっている状態で入れた事です。
ググったり調べながらやるのと比べて体系的に理解しているので、「あーこれそういうことね」という余裕感たっぷりなスタイルで見ることができます。
もちろんやってるうちに想定外の事は起きるものなのですが、それでも何とか乗り切ろうとするモチベーションを保ち続ける事が出来ました。

もう一つはベストプラクティスを念頭におきながら進められた事です。
AWSでは「AWSのベストプラクティス」という最適解というものが公式にあります。基本的にSAAはこのベストプラクティスに沿ってアーキテクチャを構築する事が求められるのですが、これを意識しながら出来たのは大きいメリットでした。
ある程度マネージドなしくみになっていて自由度は損なわれているとはいえ、適当に構築して動かす事も出来る訳ですからね。
特にセキュリティ面に関してはこのメリットが大きかったと感じました。セキュリティグループとかIAM周りとか雑に作ってももなんとかなりますもん。

逆にデメリットは決定的な差になるわけではないという所でしょうか。
上記で挙げたメリットもめちゃくちゃ大きい訳ではなく、普通に自分で勉強したり、詳しい人に聞いたりする事でも身につくポイントではあります。

あとは受験にお金がかかる事。アソシエイトはプロフェッショナルより安いとはいえ１万以上出ていきます。

## まとめ

結論としては列挙したメリットが良いと思うのなら、取ってから実務に入るとスムーズに進められると思います。
履歴書の資格欄が何もなくて寂しい方にもオススメです。私のことですが。
今後の方針としてはプロフェッショナルも取得したいなと思います。高額ですが、有効期限切れる前にキープしておきたいです。
Vue.js環境で画像の遅延読み込み(vue-lazyload)を行う

#概要
Vue.j環境の自作のWebアプリで画像読み込みに時間がかかることから、vue-lazuloadを使って画像の遅延読み込みを行う。

#経緯
知識がなく当初、lazyload.jsを使って試みましたが動作しませんでした。

#結果
ただしく画像遅延読み込みができた

#やったこと
## vue-lazyload.min.jsを読み込み

~~~html
 <script src="https://cdn.jsdelivr.net/npm/vue-lazyload@1.3.3/vue-lazyload.min.js"></script>
~~~

vue-lazyloadは[jsdeliver](https://www.jsdelivr.com/package/npm/vue-lazyload)を使用

##Vuelazyloadの設定
~~~js
Vue.use(VueLazyload, {
    loading: 'img/no_img.png',
    attempt: 1
  })
~~~

##イメージの読み込み
~~~js
<!-- <img class="content_img" :src="videoInfo.img_url" v-bind:style="disp_prm.c_img_blur"> -->
<img class="content_img" v-lazy="videoInfo.img_url" v-bind:style="disp_prm.c_img_blur">
~~~

#参考記事
[画像の遅延読み込みを「Vue-Lazyload」で 簡単に実装する](https://www.kabanoki.net/2099/)
[【Vue.js】画像の遅延読み込みを実現する為にvue-lazyloadを導入してみた](https://qiita.com/shin_moto/items/9870b4e450d22fe4f1d5)
[Lazy Loadで画像を遅延ロードする方法](https://cluster-seo.com/blog/lazy-load-javascript-library.html)
※Lazy Load何？とか 、なぜ使うの？ とかも記載されてるます



#lazyload.jsを使って動作しなかったときの設定【個人用のメモ】

##やったこと
- lazyloadのjsを読み込む  
 
~~~html
<script src="https://cdn.jsdelivr.net/npm/lazyload@2.0.0-rc.2/lazyload.min.js"></script>
~~~

- imgタグをの画像指定をsrcからdata-srcに変更(※下記はVueで記述)
- imgタグのclassにlazyloadを追加

~~~html
<!-- <img class="content_img" :src="videoInfo.img_url"> -->
<img class="content_img lazyload" :data-src="videoInfo.img_url">
~~~

- bodyの最後でlazyload()を実行
<script>lazyload()</script>

#参考
[SEOを考慮したGoogle推奨の画像の遅延読み込み処理まとめ](https://webtan-tsushin.com/seo-lazy-image-load)