OmniAICreator/Qiita-1.07M huggingface dataset:
【Nuxt】Vuexについてのメモ

## Vuexとは

Vuexはアプリケーションのデータを一箇所で管理できるライブラリのことです。
Vuexの中心にはデータの状態保存しておくstoreというものがあります。
アプリケーション内のどのコンポーネントからアクセスできるため、アプリケーション全体で管理するものはstoreに保存しておきます。
storeを使用することで、コンポーネント同士の受け渡しの管理が複雑になるのを防げます。

## storeの特徴

storeには以下のような特徴があります。

- storeの状態を変更すると、storeから値を取り出したときの値もリアクティブに変更される
- store内部は直接変更できない。変更はmutationをコミットすることでのみ可能になる

また、storeには４つ機能があります。

- state ：データの状態を保存しておく。
- getter　：stateの情報を取得する。
- mutation　：stateの状態を更新する。stateの値を更新できるのはmutationのみ。
- action　：mutationをコミットしたり、非同期処理を含むことができる。


## 補足：store導入方法

nuxtでは、Vuexストアはnuxtに付属しているのですぐに使用することができます。
sotreディレクトリの下にindex.jsファイルを作成することで、storeが有効化されます。
また、index.jsはルートモジュールになります。







### 参考
https://nuxtjs.org/ja/docs/directory-structure/store/

https://vuex.vuejs.org/ja/
収穫を増やすためにJohn DeereはどのようにAIを活用したのか (Databricksユースケース)

[How John Deere Uses Industrial AI in Precision Agriculture \- The Databricks Blog](https://databricks.com/blog/2021/07/09/down-to-the-individual-grain-how-john-deere-uses-industrial-ai-to-increase-crop-yields-through-precision-agriculture.html)の翻訳です。

最近、John DeereのCTOである[Jahmy HindmanはThe Verge](https://www.theverge.com/22533735/john-deere-cto-hindman-decoder-interview-right-to-repair-tractors)で、会社の農業機械はこの30年間で純粋な機械から、彼の言葉によれば「計算機能を搭載したモバイルセンサースイート」への変換について語りました。これはJohn Deereの「スマートインダストリアル」戦略として稼働しているものです。スマートインダストリアルは個々の装置を売るのではなく、大規模な農業従事者が持つエーカー当たり数万もの植物それぞれ(エーカー数だけ量が倍増します)にケアができるように、農業従事者が必要とする全体のシステム(装置、データ、分析、自動化)を提供することを指しています。これによって、生産量の改善、廃棄の削減が行えるようになります。

今年の[Data + AI Summit](https://databricks.com/dataaisummit/north-america-2021)(DAIS)において、John DeereのGregory Finch (Senior Principal Software Engineer, Intelligent Solutions Group)とJake Sankey (Technical Product Manager, Enterprise Data & Analytics Platforms)は、[彼らの製造業キーノート](https://databricks.com/session_na21/manufacturing-and-distribution-industry-summit)において、これらを実現しているデータプラットフォームの詳細を説明しました。装置によって生み出されるデータ量は年を重ねるごとに倍増していたため、Deereはこの規模のデータを今後も取り扱え、新規データソースと容易に連携でき、セールス、サービス、エンジニアリングのような後段に控えているチームがお客様の成果を改善できるように、それらのデータを統合できるようなデータプラットフォームを必要としていました。

Jakeは右の通り説明しています。「我々の技術スタックは非常に広大です...オンボードとオフボードのコンポーネントから構成されています。オンボードサイドでは、大量のセンサーを有しています。ビジョンシステム、ガイダンスシステムやワイヤレス接続も含まれています。オフボードにおいては、クラウドインフラストラクチャ、クラウドストレージがあり、全てのデータを受信、処理、分析できるようにしてくれるスケーラブルなサービスがあります。このスタックによって、我々はお客様がより生産的、より成功するように支援することができています。」

例として、彼は[X9コンバイン](https://www.deere.com/en/harvesting/x-series-combines/)(穀物を収穫するマシン)を挙げています。「コンバインのエレベーターを上りタンクに投入される穀物の個々の粒までを、カメラは継続的にモニタリングしています。穀供物の品質を分析するために機械学習を用いており、穀物に損傷が認められた際には自動的に機械の制御パラメーターを調整しています。」

これらの種の進展は農業従事者を支援するだけではなく、より広範な社会の利益にもつながっています。精度農業(Precision Agriculture)を通じて、農業従事者は化学薬品の消費を70%削減し、農薬の過剰使用による環境影響を削減しました。

このキーノートでJakeとGregは、データと人工知能(AI)が欠かせない重要なツールとなるのに従い、184年の歴史を持つ企業がどのように業界の変革をリードしたのか、店舗での実行から顧客の手によって物事が行われるようになったのかについて語っています。
<iframe width="560" height="315" src="https://www.youtube.com/embed/9zXV_l-LtzY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Vue3 emitsオプションについて

#初めに
皆さんこんにちは！
今回はVue3でシステムを実装時に新しくemitsオプションに出会ったのでこちらを記事にしたいと思います。

#emitsオプションとは
まずはemitsオプションの概要から紹介させていただきます。
vue3アップデート時の新機能として追加されたオプションになります。

emit実行時にpropsと同じような形で、
受け取る際にバリデーションの実行や型の指定が可能になりました。

>公式より
Vue 3 では emits オプションが、既存の props オプションと同様に提供されるようになりました。このオプションを使用して、コンポーネントが親に発行できるイベントを定義することができます。
[Vue3 リファレンス](https://v3.ja.vuejs.org/guide/migration/emits-option.html)

#emitsの使い方
emitsはpropsのように構文設定することが可能になりました。
設定方法としては、2通りあって
1.配列での設定
2.オブジェクトでの設定

になります。

まずは公式の記述例を見ていきましょう。

```javascript
const app = createApp({})

// 配列の構文
app.component('todo-item', {
  emits: ['check'],
  created() {
    this.$emit('check')
  }
})

// オブジェクトの構文
app.component('reply-form', {
  emits: {
    // バリデーションなし
    click: null,

    // バリデーションあり
    submit: payload => {
      if (payload.email && payload.password) {
        return true
      } else {
        console.warn(`Invalid submit event payload!`)
        return false
      }
    }
  }
})
```

いかがでしょうか。
まさしくpropsのような書き方なのでVue2を利用されていた方であれば理解が早いと思います。

オブジェクト構文で記述することで、
型指定やバリデーションの実装も可能になっております。

#最後に
良いVue3ライフを！！

#参考にさせていただいたサイト
https://v3.ja.vuejs.org/api/options-data.html#emits
Nuxt V3 試してみた

10/12にNuxtのV3（ベータ版）が出たので試してみます

https://v3.nuxtjs.org/

# 実行環境

WSL2＋Ubuntuにて試してます。

# Nuxt V3プロジェクトの作成

参考：https://v3.nuxtjs.org/getting-started/installation

```bash
$ npx nuxi init nuxt3-app
```

VSCodeで開きます

```bash
$ code -r nuxt3-app
```

ファイルが↓しかありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/91faf29d-0876-bbe9-b3c6-f7d262504d6c.png)

### ファイルを確認

```app.vue
<template>
  <div>
    <!-- Remove this component to get started! -->
    <NuxtWelcome />
  </div>
</template>
```

⇒`NuxtWelcome`コンポーネントはどこにあるのか．．．？

```nuxt.config.ts
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
})
```

⇒ベータ版だからなのか、何も設定がありません

```tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": false,
    "allowJs": true,
    "resolveJsonModule": true,
    "types": [
      "node"
    ]
  }
}
```

```package.json
{
  "private": true,
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "start": "node .output/server/index.mjs"
  },
  "devDependencies": {
    "nuxt3": "latest"
  }
}
```

# プロジェクト起動

```bash
$ cd nuxt3-app
$ npm install
$ npm run dev -- -o
```

↓のような感じで起動します。

```bash
Nuxt CLI v3.0.0-27234503.d5127e9                                                                              07:26:58
                                                                                                              07:26:58
  > Local:    http://localhost:3000/
  > Network:  http://172.30.162.254:3000/

ℹ Vite warmed up in 622ms     
✔ Generated nuxt.d.ts        
✔ Vite server built in 907ms 
✔ Nitro built in 166 ms      
```

NuxtV2だとビルドで結構時間かかってましたが、Nuxt V3だと2秒以下で完了してます。
ビルドが完了すると自動で`http://localhost:3000/`がブラウザで開きます。
ただ、Nuxt V2と違ってそのままだとlocalhostでアクセスできないようなので、`Network`の方でアクセスしてみます
（ベータ版でnuxt.config.tsに何も定義されてないせい？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/be235236-2b8d-b60c-2544-275070315210.png)
備忘録#1　Windows用リソース確認コマンド①

# 備忘録#1　Windows用リソース確認コマンド①
サーバーのリソースを確認するためのコマンド一覧

## 目次
掲載内容は以下の通りです。
1. systeminfo
	- 基本情報のcsv出力
	- リモートサーバーの基本情報の表示
	- リモートサーバーの基本情報をcsvで出力
1. fsutil
	- Cドライブの空き容量を表示する
1. wmic
	- インストール済みKB情報をリスト形式でデスクトップにcsv出力
1. schtasks
	- タスクスケジューラを詳細表示にしてデスクトップにcsv出力
1. tasklists
	- タスクリストを詳細表示でデスクトップにcsv出力

## systeminfo
サーバーの基本情報を表示するコマンド
### 基本情報のcsv出力
```Batchfile
$ systeminfo /fo csv > %userprofile%\Desktop\systeminfo.csv
```
### リモートサーバーの基本情報の表示
```batchfile
$ systeminfo /s servername /u domain¥userid
```
### リモートサーバーの基本情報をcsvで出力
```batchfile
$ systeminfo /s servername /u domain¥userid /fo csv > %userprofile%\Desktop\remotesysteminfo.csv
```
## fsutil
システム情報を表示するコマンド
### Cドライブの空き容量を表示する
```batchfile
$ fsutil volume diskfree c:
```
## wmic
システム情報を表示するコマンド
### インストール済みKB情報をリスト形式でデスクトップにcsv出力
```batchfile
$ wmic qfe list /format:csv > %userprofile%\Desktop\kblist.csv
```
※「/format:hform」でHTMLフォーマットで出力可能(視認性向上)
## schtasks
タスクスケジューラを表示するコマンド
### タスクスケジューラを詳細表示にしてデスクトップにcsv出力
```batchfile
$ schtasks /query /v /fo csv > %userprofile%\Desktop\schtasks.csv
```
## tasklists
タスクリストを表示するコマンド
### タスクリストを詳細表示でデスクトップにcsv出力
```batchfile
$ tasklist /v /fo csv > %userprofile%\Desktop\tasklists.csv
```

## 参考にしたページ
- [Windowsコマンド虎の巻](https://windows.command-ref.com/cmd-systeminfo.html)
- [【Windows】ディスクの空き容量を取得するコマンド（＋ディスク情報を取得する）](https://correct-log.com/windows-get-free-space-by-commandline/#toc2)
- [特定の更新ファイル（KB）がインストールされているか調べるコマンドとバッチファイル](https://qwerty.work/blog/2017/08/kbfile-find-command-batchfile.php)
- [【windows】タスクスケジューラ 一覧の取得コマンド](https://qiita.com/sunmontue1006/items/fca3d99fcddc5e2d94db)
- [Windows で実行中のプロセス（タスク）の一覧を表示する (tasklist)](https://maku77.github.io/windows/admin/tasklist.html)

## Official Reference
- [systeminfo/Microsoft Ignite](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/systeminfo)
- [fsutil/Microsoft Ignite](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/fsutil)
- [wmic/Microsoft Ignite](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/wmic)
- [schtasks/Microsoft Ignite](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/schtasks)
- [tasklist/Microsoft Ignite](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/tasklist)
Ginでサーバーを立ち上げてJSONのメッセージを表示

#概要

Ginでサーバーを立ち上げてJSONのメッセージを表示させる。


#環境
・Docker
・MacBook

#docker run でgolamgが入ったコンテナを作る。


````
~/d/q/gin_server ❯❯❯ docker run -itd --name gin_server -p 8080:80 golang:latest

#コンテナにはいる
~/d/q/gin_server ❯❯❯ docker attach gin_server
````


````:Docker
root@1cc8cba550f2:~# cd ../root

#Vimをインストールする
root@1cc8cba550f2:~# apt update
root@1cc8cba550f2:~# apt install vim

#Vimで空のmain.goを作る
root@1cc8cba550f2:~# vim main.go

#ginをダウンロードする
root@1cc8cba550f2:~# go get github.com/gin-gonic/gin
go: downloading github.com/gin-gonic/gin v1.7.4

root@1cc8cba550f2:~# go mod init example.com/m
````


#コーディング

````golang:main.go
package main

import "github.com/gin-gonic/gin"

func main() {
	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run(":80")
}

````


###go mod vendorする
````:Docker
root@1cc8cba550f2:~# go mod vendor
go: finding module for package github.com/gin-gonic/gin
go: found github.com/gin-gonic/gin in github.com/gin-gonic/gin v1.7.4
````

###main.goを起動する
````
root@1cc8cba550f2:~# go run main.go

````

###ブラウザからlocalhostにアクセスする
http://localhost:8080/


画面に下記のように表示されたら成功

```
{
message: "pong"
}
```
Docker マウントの理解

Dockerのコンテナの中のファイルをVsCodeで編集したい。
その悩みはバインドマウントをすることで解決します。


[参考記事]
　https://nyakanishi.work/docker_mount/
　https://qiita.com/aki_55p/items/63c47214cab7bcb027e0

#バインドマウントとボリュームマウントについて知っておきたいこと

###バインドマウント
コンテナ内の特定のディレクトリやファイルをDockerホストにマウントさせリンクする。
リンクしたディレクトリ内のファイルを修正するとコンテナ内のファイルも修正される。
※ホストマシン上でVscodeを使ってファイルを修正したい時はこっちを使う。

###ボリュームマウント　
コンテナの外(Dockerホスト上)にストレージ領域（ボリューム）を作成してコンテナ内の特定のディレクトリをリンクさせる。
コンテナを削除してもマウントしたディレクトリ内のデータはボリュームに保持されているため、利用していたボリュームをマウントすることで同じデータを持つコンテナが作れる。１つのボリュームを参照し、複数のコンテナに同じファイルを共有したりすることができる。

###`-vオプション`か`--mountオプション`でマウントできる
・どちらのオプションを使うかによって書き方が異なる。
・`--mountオプション`の方が推奨されている。
>
　`-vオプション`ではタイプミスしてもタイプミスした名前で新しいディレクトリを作成し、コンテナへのマウントを行う。
　`--mountオプション`ではホスト側に存在しないディレクトリやファイルを指定するとエラーになる。
　よって`--mountオプション`の方が推奨されている。


#マウントの方法の違い

##バインドマウント
````
#-vオプションの場合
# docker run -itd --name 任意の名前 -p 8080:80 -v ホスト側PATH:コンテナ側PATH イメージ
$ docker run -itd --name sample-nginx -p 8080:80 -v /Users/<ユーザ名>/tmp_dir:/usr/share/nginx/html nginx:latest

#--mountオプションの場合
# docker run -itd --name 任意の名前 -p 8080:80 --mount type=bind,src=ホスト側PATH,dst=コンテナ側PATH イメージ
$ docker run -itd --name sample-nginx -p 8080:80 --mount type=bind,src=/Users/<ユーザ名>/tmp_dir,dst=/usr/share/nginx/html nginx:latest

#上下とも同じことをしています
````


##ボリュームマウント

````
#ボリュームマウントを使用する際は、事前にボリュームをホストマシン上で作成する。
$ docker volume create sample-volume

#-vオプションの場合
# docker run -itd --name 任意の名前 -p 8080:80 -v ボリューム名:コンテナ側PATH イメージ
$ docker run -itd --name sample-nginx -p 8080:80 -v sample-volume:/usr/share/nginx/html nginx:latest

#--mountオプションの場合
# docker run -itd --name 任意の名前 -p 8080:80 --mount type=volume,src=ボリューム名,dst=コンテナ側PATH イメージ
$ docker run -itd --name sample-nginx -p 8080:80 --mount type=volume,src=sample-volume,dst=/usr/share/nginx/html nginx:latest

#上下とも同じことをしています
````
CSSのプロパテーと値

#CSSのプロパティーについて
プロパティーの種類は様々なものがありあます。
文字の色、背景色、背景画像、フォントの種類、フォントの大きさなどがあります。
ではここで実際に使ってみしょう。

まずはhtml内にPタグを指定し文字の色を変えてみよう。

```
index.html
<p>テスト</p>

style.css
@charset "utf-8"
p {
/*処理を書く*/
color:#f0000;
}
```
![Web キャプチャ_13-10-2021_3441_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074932/0dc0a042-b6a0-d895-062a-2df0f265bd6a.jpeg)
 
上の様に文字が赤くなっていれば成功です！
日本で訳すとすべてのPタグに対して文字の色を赤くしてねという命令になります。
Pタグの{}内の処理はcolorで文字色を変えてほしいということになり、何色に変えるのかという
命令を：の後に書いています。

文字の大きさを変える場合はfont-size:〇〇px;
背景色はbackground-color、背景画像はbackground-imag：url();です。

例題として、html内でPタグを指定しテキスト内容はHallo.
cssでpタグに対して文字の大きさを20ピクセル　文字色は白　背景色を青にしてください。
すると以下の結果になります。
![Web キャプチャ_13-10-2021_31745_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074932/d856fd71-5ed4-a5e4-0799-ec2c8ef2ebd2.jpeg)

コードの回答はこちら

```
index.html
<p>Hallow</p>

style.css
@charset "utf-8"
p {
color:#ffffff;
background-color:#0000ff;
font-size:20px;
}
```

次は四角箱を３つほど作ってみましょう
まず横幅を４０ピクセル、縦幅を３０ピクセルにします。
そしたら箱の空間を１０ピクセルほどにしていきます。

```
index.html
    <div class="box"></div>
    <div class="box2"></div>
    <div class="box3"></div>
style.css
@charset "utf-8"
p {
/*処理を書く*/
.box {
    width: 40px;
    height: 30px;
    background-color: blue;
}
.box2 {
    width: 40px;
    height: 30px;
    margin-top: 10px;
    background-color: blue;
}
.box3 {
    width: 40px;
    height: 30px;
    margin-top: 10px;
    background-color: blue;
}

```

処理を見ていきましょう
widthは横幅、heightは縦の長さを表しています。
margin-topは上の余白部分を表しています、余白についてはまた後日書いていきます。
background-colorで背景色の指定をしています。これらの結果は以下の様になっていますか？
![Web キャプチャ_13-10-2021_3343_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074932/bc31700f-9885-de62-7b53-fd464033dd56.jpeg)

縦に並んでいれば正解です。
HTMLの処理を基本的には上から下に流れ左側に反映されていきます。

問題です、青い箱を好きな色に変えてください(青以外の色、３つの箱の色をバラバラで）大きさは横と縦を同じ１００ピクセルに指定。余白はそのままで平気です。

こんな感じになりましたか？なっていれば正解です。答えは次回に載せます。
![Web キャプチャ_13-10-2021_34045_.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2074932/e06cba25-2736-7a59-5798-aa4cd0324acb.jpeg)
AWS 代表的なサービス一覧

## リンク集
1. [AWS 代表的なサービス一覧](https://qiita.com/hiro-hiro/items/97258c7be6bf65fc4adf)
1. [AWS 個別サービス詳細1]()

## 代表的なサービス一覧

### サーバー関連

|サービス名|概要|
|---|---|
|Amazon EC2|仮想サーバー|
|Amazon Elastic Container Service|Dockerコンテナの実行および管理|
|Amazon Lightsail|仮想サーバーとネットワーク一式の起動と管理|
|AWS Batch|バッチジョブの実行|
|Amazon VPC|ネットワーク環境|
|Amazon APIGateway|Web APIを構築するサービス|
|Amazon CloudFront|コンテンツキャッシュサービス(CDN)|
|Amazon Route 53|DNSサービス|
|Amazon Direct Connect|AWSネットワークに専用線で接続|
|AWS Transit Gateway|VPC同士などを接続|
|Elastic Load Balancing(ELB)|負荷分散装置|
|Amazon Simple Email Service(SES)|メールサービス|
|Amazon GameLift|ゲームホスティングサービス|
|AWS Amplify|モバイルアプリとWebアプリの構築とデプロイ|

### メディア

|サービス名|概要|
|---|---|
|Amazon Elastic Transcoder|メディア変換サービス|
|AWS Elemental MediaLive|ライブビデオコンテンツの変換|
|AWS Elemental MediaPackage|動画の配信パッケージ|

### ストレージ

|サービス名|概要|
|---|---|
|Amazon Simple Storage Service(S3)|汎用的なクラウドストレージ|
|AWS Transfer for SFTP|SFTPサービス|
|Amazon Elastic Block Store(EBS)|EC2で用いるストレージ|
|Amazon FSx for Windows ファイルサーバー|Windowsファイルシステムのサービス|
|Amazon S3 Glacier|S3の長期保存サービス|
|AWS Backup|バックアップサービス|

### データベース

|サービス名|概要|
|---|---|
|Amazon Aurora|Amazonによってカスタマイズされた高性能なRDS|
|Amazon DynamoDB|NoSQLデータベース|
|Amazon DocumentDB|MongoDB互換のドキュメントデータベース|
|Amazon ElastiCache|インメモリキャッシュシステム|
|Amazon RDS|リレーショナルデータベース|

### セキュリティ

|サービス名|概要|
|---|---|
|AWS Identity and Access Management(IAM)|ユーザー機能|
|Amazon Congnito|アプリケーション認証機能を提供するサービス|
|Amazon GuardDuty|脅威を検出|
|AWS Certificate Manager|証明書を生成|
|AWS Firewall Manager|ファイアウォールの一元管理|
|AWS WAF|Webのファイアウォール機能|

### データの集計・分析

|サービス名|概要|
|---|---|
|Amazon Athena|S3に保存したデータの集計サービス|
|Amazon Redshift|大量データの集計サービス|
|Amazon Kinesis|リアルタイムのビデオやデータストリームを分析|
|Amazon Elasticsearch Service|ログやモニタリング、セキュリティなど、データ分析サービス|

### アプリケーション連携

|サービス名|概要|
|---|---|
|AWS Step Functions|順次プログラムを実行する仕組み|
|Amazon Simple Queue Service(SQS)|アプリケーション同士を連携するキューイングサービス|
|Amazon Simple Notification Service(SNS)|アプリケーション同士で通知メッセージを送信するサービス|

### 機械学習

|サービス名|概要|
|---|---|
|Amazon SageMaker|機械学習モデルの構築、トレーニング、デプロイ|
|Amazon Lex|音声やテキストに対応するチャットボットの構築|
|Amazon Polly|テキストを話し声に変換|
|Amazon Textract|ドキュメントからテキストやデータを抽出|
|Amazon Translate|言語翻訳|
|Amazon Transcribe|自動音声認識|

### IoT

|サービス名|概要|
|---|---|
|AWS IoT Core|IoTデバイスをクラウドに接続するための基本サービス|
|Amazon FreeRTOS|マイコン向けリアルタイムOS|
|AWS IoTボタン|クラウドでプログラミングできるダッシュボタン|
|AWS IoT Things Graph|デバイスとWebサービスを相互接続するサービス|

### クライアント向けサービス

|サービス名|概要|
|---|---|
|Amazon WorkSpaces|仮想デスクトップ環境|
|Amazon AppStream 2.0|デスクトップアプリケーションをWebブラウザにストリーミング|
|Amazon WorkLink|社内のWebサイトへのモバイルアクセスを可能に|

### 開発ツール

|サービス名|概要|
|---|---|
|AWS Cloud9|Webブラウザで操作できる統合開発ツール|
|AWS CodeBuild|プログラムのビルドやテストツール|
|AWS CodeCommit|プライベートなGitサービス|
|AWS CodeDeploy|開発したプログラムを配備するツール|
|AWS CodePipeline|開発したツールをビルドして配備するまでを自動化するツール|
|AWS CodeStar|ビルドから配備までを一式提供するツール|
|AWS コマンドラインインターフェイス|コマンドでAWS を操作するツール|

### コスト管理

|サービス名|概要|
|---|---|
|AWS Cost Explorer|コストと使用状況を分析|
|AWS Budgets|予算を設定して超えそうになったときに通知|
Nuxt3のpublic beta版がついに公開されたので、さっそく導入してみた

# はじめに
<p>Vue3に対応したフレームワークであるNuxt3のPublic beta版が
2021/10/13についに公開されました。</p>

<p>まずは公式ドキュメントの内容を紹介しつつ、
プロジェクトの作成を試してみたいと思います。</p>

※詳細は個人ブログこちらから御覧ください。

https://gonkunblog.com/nuxt3-public-beta/1033/
module-info.javaの書き方

#module-info.javaの書き方

##問題点と解決策
モジュールの名前に、パッケージと同じ(またはほぼ同じ)名前を付けた例が散見された。
間違いではないが非常に紛らわしく混乱した。
どこにどのレベルの名称を書くのか、構文レベルで事前把握しておくが吉。

```x:ModuleDeclaration
{Annotation} [open] module Identifier {. Identifier} { {ModuleDirective} }
```

```x:ModuleDirective
requires {RequiresModifier} ModuleName ;
exports PackageName [to ModuleName {, ModuleName}] ;
opens PackageName [to ModuleName {, ModuleName}] ;
uses TypeName ;
provides TypeName with TypeName {, TypeName} ;
```

```x:RequiresModifier
(one of)
transitive static
```

|提供側|単位|利用側|単位|
|:----|:----|:----|:----|
|exports|パッケージ|requires|モジュール|
|opens|パッケージ|-| |
|provides|タイプ|uses|タイプ|
docker環境でvscodeのrubocop拡張が反応しない時の対処法

# はじめに
vscode の rubocop 拡張 [ruby-rubocop](https://marketplace.visualstudio.com/items?itemName=misogi.ruby-rubocop) を Docker 環境で使用したところかなり詰まったのでその備忘録です。

ホストに rubocop をインストールすれば良いという記事が散見されましたが、根本的な解決になっていません。ここではホストを汚さずコンテナ内の rubocop を参照するような解決方法をあげます。

一人でも多くの方の参考になれば幸いです。

# 何も設定していない時のエラー ( rubocop 拡張入れただけ)
```
command /Users/horisho/.rbenv/shims/rubocop returns empty output! please check configuration.
```
ホストに rubocop は存在しないので、 docker コンテナに実行先を向けないといけません。

# 初期設定
https://github.com/misogi/vscode-ruby-rubocop/issues/112#issuecomment-673513315

こちらのIssueコメントを参考に設定をしました。
rubocop の実行ファイルを作成し、実行環境を Docker コンテナ内に向けている形です。
ディレクトリ構成は以下のようです。

```bash
$ tree -L 2 -a
.
├── .vscode
│   └── settings.json
├── api
│   ├── .rubocop.yml
│   ├── rubocop
│   └── 略
├── docker-compose.yml
└── 略
```
ファイルの中身は以下のようです。

```bash:api/rubocop 
#!/bin/bash
docker-compose exec -T api bundle exec rubocop -c .rubocop.yml "$@"
```

```yml:docker-compose.yml 
version: "3"

services:
  api:
    build:
      context: ./api
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    depends_on:
      - db
      - redis
    volumes:
      - './api:/myapp'
    ports:
      - '3010:3000'
    tty: true
    stdin_open: true
    env_file:
      - .env

# 以下略
```

```yml:.vscode/settings.json 
{
  "ruby.rubocop.executePath": "./api/"
}
```
rubocop 周りの設定ファイルは`api`ディレクトリに含め、起動コンテナにマウントしている状態です。また、Issueコメントとは異なり、 rubocop 拡張の実行パスを`./api`に向けています。

# 遭遇したエラーメッセージ
```
command ./api/rubocop returns empty output! please check configuration.
```

```
./rubocop is not executable
```

# 結論（修正方法）
rubocop 実行ファイルを`docker-compose.yml`と同階層に配置し、実行パスをIssueコメント同様`./`に修正すれば良い。

```bash
$ tree -L 2 -a
.
├── .vscode
│   └── settings.json
├── api
│   ├── .rubocop.yml
│   └── 略
├── docker-compose.yml
├── rubocop
└── 略
```

```yml:.vscode/settings.json 
{
  "ruby.rubocop.executePath": "./"
}
```

# 原因
rubocop 実行ファイル(`/api`ディレクトリ)で `docker-compose` コマンドを実行しています。当然 `docker-compose` は同階層の `docker-compose.yml` を参照しにいきますが、 `/api` ディレクトリには存在せず、ルートディレクトリに存在します。そのため、コンテナが見つからずエラーというわけです。

# 注意点
rubocop実行ファイルで`docker-compose exec api ...`と`exec`コマンドを実行しているため、コンテナがすでに立ち上がっていないとエラーで怒られます。
MacBook Pro (macOS Catalina 10.15.7)のデフォルトシェルをbashに変更してみた

この記事は、物理的インフラエンジニアをしている筆者が、MacBook Proのターミナル設定で焦った話です。

プログラミング環境構築したくて、MacBook Proを購入しターミナルを開いてみると...

```
%
```
ん？確かmacOSはUnix系だから、一般ユーザのプロンプト表示は$なのでは？
普段実務でLinuxを触っている私は、違和感を感じた。

調べてみると、どうやらデフォルトシェルがzshだとプロンプト表示が％になるという。確かに確認してみるとzshだ…


```
% echo $SHELL
/bin/zsh
```

https://discussionsjapan.apple.com/thread/251307575

https://qiita.com/normalsalt/items/5b71fbd03721800de4a0


```
chsh -s /bin/bash
```
上記コマンドでデフォルトシェルをbashに変更したが、ログイン時に毎回下記メッセージが表示される…
`The default interactive shell is now zsh.`

そこで、下記コマンドでこのメッセージを非表示に！
参考にさせていただいたサイトは[こちら](https://original-game.com/what-to-do-when-default-shell-is-now-zsh-is-displayed-on-mac/#m_heading-1
)

```
$ echo "export BASH_SILENCE_DEPRECATION_WARNING=1" >> ~/.bash_profile
```

これでやっとプロンプト表示が$になって、謎の安心感を得たのでした。見慣れたものに変えたくなったお話でした。めでたし。

```
$ echo $SHELL
/bin/bash
```
SwiftUI + Combine で空値チェック【VIPERでログイン機能を作ろう】

## 前提
VIPERでログイン機能を作るための要素を勉強中です。
今回は入力チェックの導入として空値チェックを実装してみます。

## 環境
- macOS 11.4 
- xcode13
- swift5

## ゴール
TextFieldに文字列が入力されていればButtonを活性化する
という単純な処理をSwiftUI + Combine で実装する

![login_validation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263661/5ff08d9a-6dd1-4adf-3ca9-1bcfe73a2d7f.gif)


## 参考
https://www.youtube.com/watch?v=_bQnBLMGpqc&t=523s

## 実装
### LoginPresenter
最終的にVIPERにしたいので、Presenterを作ってバインディングするプロパティなどを記述していきます。
MVVMの場合はViewModelに同じように書いていくと良いと思います。

```swift
protocol LoginPresentation {
    func didTapLoginButton()
}

final class LoginPresenter: ObservableObject {
    let emailPlaceholder = "email"
    let passwordPlaceholder = "password"
    let loginButtonTitle = "Login"

    @Published var email = ""
    @Published var password = ""
    @Published var isValid = false

    init() {
        Publishers.CombineLatest($email, $password)
            .map { email, password in
                return !email.isEmpty && !password.isEmpty
            }.assign(to: &$isValid)
    }

}

extension LoginPresenter: LoginPresentation {
    func didTapLoginButton() {
        print("Login")
    }
}
```

重要なのはこの部分
emailとpasswordの両方の値を監視して
変更があった場合にisValidの値を処理結果に応じて更新しています

```swift
Publishers.CombineLatest($email, $password)
    .map { email, password in
        return !email.isEmpty && !password.isEmpty
    }.assign(to: &$isValid)
```

### LoginView
email, password共にPresenter(ViewModel)に記述した値を使っています。

```swift
struct LoginView: View {
    @ObservedObject var presenter: LoginPresenter

    var body: some View {
        VStack {
            emailTextField
            passwordSecureField
            loginButton
        }
    }

    var emailTextField: some View {
        TextField(presenter.emailPlaceholder, text: $presenter.email)
            .autocapitalization(.none)
            .padding()
    }

    var passwordSecureField: some View {
        SecureField(presenter.passwordPlaceholder, text: $presenter.password)
            .autocapitalization(.none)
            .padding()
    }

    var loginButton: some View {
        Button(presenter.loginButtonTitle) {
            presenter.didTapLoginButton()
        }
        .frame(maxWidth: .infinity)
        .padding()
        .foregroundColor(.white)
        .background(Color(.orange))
        .cornerRadius(24)
        .padding()
        .disabled(!presenter.isValid)
        .opacity(presenter.isValid ? 1: 0.5)
    }
}
```

肝心のボタンを非活性化させているのはこの部分で
isValidの値に応じてdisabledとopacityが変化します。

```swift
.disabled(!presenter.isValid)
.opacity(presenter.isValid ? 1: 0.5)
```

## まとめ
Combineを使って、入力値をチェックすることができました。
今回は空文字かどうかのチェックしかしていませんが色々と応用できそうです。

### 次に記事にしたいこと
- $つけるつけないの判断はどうやってするのか
- Publisherで購読しているものはdeinitで購読解除しなくて良いのか
- Presenterに定数書くのは正しいのか（VIPERの理解）
DigitalOceanのSpacesのCDNにCloudFlareを使う

キャプチャ取り忘れていたので雑な記事です。
手順はこの通りなので次やるときは迷わないように残しておきます。

## この記事を書いた理由

AWS S3以外の安いサービスを探していました。
また、CloudFlareのArgoを使ってみたかったので、DigitalOcean独自のCDNは使用しませんでした。

## 料金
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/c0c879a8-90de-5959-e722-c82af707a389.png)

5TB保存して、転送量(out)を仮に1TBとしたときの概算です（適当なので大きく間違っていたらご指摘ください）
**Digital Ocean Spaces**: 90(Stored) + 0 (Transferred) + 5(基本料金) = **$95**
**S3**: 125(Stored) + 113.8(Transferred) + etc = **$238.8↑**

Spaces安くていいですね。

## CloudFlareのWebサイトを構築する

ドメインを取得し、CloudFlareのWebサイトを構築します。
私はRoute53でドメインを取得していたのですが、ホストゾーンのNSレコードを変更してしまい時間を無駄にしました。
正解の手順→https://teratail.com/questions/188602

## CloudFlareのSSL証明書を発行する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/1e0f5411-97ab-f390-fc2f-4b4697d0a558.png)

上記箇所から証明書を発行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/91c60cca-dbfe-e264-efa5-d1cc527312e1.png)

CloudFlareでプライベートキーとCSRを生成する、を選択して発行してください。

## DigitalOceanのSpacesを作成する

DigitalOceanでSpacesを作成してください。
CDNを有効にするのを忘れないようにしてください。

先程発行した証明書のキーを２つ設定します。
任意のサブドメインが必要なので入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/a7a80973-43c2-8ea8-9cd2-b7c19e6053a6.png)


設定できると上記のような表示になります。CNAMEレコード用の文字列（画像の赤い枠の部分）を控えておいてください。
「Enabled. Your Space is being served via the content delivery network.」と表示されます。

## CloudFlareのDNSを設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105394/98eab5b4-dacd-b723-4463-7f06b41fe94a.png)

CNAMEで設定するだけです。
名前はDigitalOceanで入力したサブドメインの名前を使用します。
コンテンツにはSpacesで控えておいたCNAMEレコード用の文字列を入力します。

## サブドメインでアクセスしてみる

Spacesに適当にファイルをアップロードして、サブドメインでアクセスできるか検証してみてください。
ブラウザで表示できたらOKです。
UI、UXについて

# はじめに
本記事では、`UI`と`UX`について記述します。
よく、企業のHPを拝見しているとこのような言葉を目にします。
調べては忘れを繰り返しているので、改めてアウトプットします。

# UIとは
ユーザーインターフェース(User Interface)の略で、
`クライアントとコンピューターの接する境界部分`のインターフェースです。

IT関係ではないですが、
シャンプーボトルとリンスボトルのギザギザの有無なども、
UIの考え方だと思います。

#### インターフェースとは
恥ずかしながらインターフェースという言葉を理解できていないので調べました。

(参考)
[「インターフェース」ってどういう意味？ わかりやすい使い方と例文](https://gakumado.mynavi.jp/freshers/articles/43476)
> 英単語の「Interface」の直訳は「境界面」「接点」であり、ビジネス用語の「インターフェース」はここから「異なる2つのものを仲介する」という意味で使われます。

## CUIとGUI
UIのIT用語の具体例として、`CUI`と`GUI`があります。

### CUI
Character User Interfaceの略。
コンピューターに対してキーボードで`コマンドを入力`して命令する方法です。
ターミナルでコマンド入力することもCUIです。

メリットは以下の通り

- 作業の手順を記録・共有しやすい
- 操作性がシンプル
- メモリなどのリソースをあまり必要としない
- 実行内容の自由度が高い

*([CUI（キャラクター・ユーザー・インターフェース）とは？意味・定義・特徴をわかりやすく解説](https://www.kumikomi.jp/cui/))より

### GUI
Graphical User Interfaceの略。
`アイコンやボタンをクリック`して命令する方法です。

以下のような部品を使って操作します。

|名称|概要|
|-|-|
|ラジオボタン|複数の項目から１つを選択するボタン|
|チェックボタン|項目を選択させるボタン|
|スプンボタン|特定の値の増減ができるボタン|
|プルダウンメニュー|上から項目を表示させるメニュー|
|ポップアップメニュー|画面から出てくるように表示されるメニュー|

# UXとは
User experienceの略。
使いやすさや機能だけでなく、使うことで利用者を楽しく快適な経験ができるという考え方です。

以下のサイトでいろんな例え話がありました。
IT関連では、LINEが`気軽に会話`できるという点から、
従来のメールでのやりとりよりも
今では、普及しています。

今では当然のようなことかもしれませんが、
このような考えを持ち、アプリケーションを作成する必要がありますね。

[UXデザインとは　～　身近な事例から理解する　～](https://archeco.co.jp/ux-design/what-is-ux-design/)

> 今や多くの人が利用しているLINEにおけるユーザー体験は、アプリのUIや仕様が大きく影響しています。LINEの機能だけに注目すると、メールアプリ、メッセンジャー、テキストチャットなどと捉えることができます。そう考えると、フィーチャーフォンやスマートフォンなどに元々インストールされているメールアプリと同じように感じます。しかし、多くの人が今や元々インストールされているメールアプリを利用せずに、LINEを利用しています。この要因として、ユーザー体験の違いがあげられます。

以上です。

# 終わりに
基礎の部分ですが、本記事で忘れないようにしたいと思います。(n回目)

以下参考サイトです。

[「インターフェース」ってどういう意味？ わかりやすい使い方と例文](https://gakumado.mynavi.jp/freshers/articles/43476)
[CUI（キャラクター・ユーザー・インターフェース）とは？意味・定義・特徴をわかりやすく解説](https://www.kumikomi.jp/cui/)
[UXデザインとは　～　身近な事例から理解する　～](https://archeco.co.jp/ux-design/what-is-ux-design/)


明日も頑張ります！
WSL2のUbuntuでPHPStanを使う（VSCode）

# はじめに

- 自分だけの環境に PHPStan を入れて、他の開発メンバーと差をつけたい時、あると思います
- ということで、WSL2 で利用する Ubuntu ディストリビューションに PHPStan を設定し、そちらを VSCode で読み込むようにします

# バージョン

- Windows11 Pro
    - 21H2
- VSCode
    - 1.61.0
- Ubuntu
    - 20.04.2 LTS
- Composer
    - 2.1.3

# 前提

- こちらの記事の続きです

<https://qiita.com/rowpure/items/fcf84ae42d8e5ed81ad1>

# 拡張機能インストール手順

## 1．PHPStan インストール

- 以下のコマンドを実行する

```bash
# パッケージ最新化
sudo apt update
# PHPStan インストール
composer global require phpstan/phpstan
```

## 2．VSCode と連携

- VSCode の拡張機能[PHPStan](https://marketplace.visualstudio.com/items?itemName=swordev.phpstan)をインストールする

## 3．PHPStan 読み込み設定

- VSCode の settings.json を編集する

```JSONC:settings.json
{
    "phpstan.path": "/home/xxxx/.config/composer/vendor/bin/phpstan",
}
```

## 4．`phpstan.neon`ファイル作成

- PHPStan で分析させたいリポジトリに以下のファイル配置
    - 一番厳しいレベルに設定（0 ～ 7 ［= max］が設定できる）
    - `src`ディレクトリ配下を分析する設定

```yml:phpstan.neon
parameters:
  level: max
  paths:
    - src
```

- 保存することで VSCode に反映され、対象ファイルの分析が行われる
    - NG 個所はサイドバーのエクスプローラーのファイル名が赤くなり、対象コードに赤い波線が出ます

# おわりに

- 小さいリポジトリでも、それなりに赤い波線が出てしまいました  
  （ほとんどが array のドックコメント　＆　null になる可能性のある変数の不適切な引数設定についてでした）
- かなり不具合を予防できるような気がします、特にログに出る Notice エラーを
- CakePHP の例ですが、今回の対応で修正したコミットになります
    - [GitHub | PHPStan設定追加：コード最適化](https://github.com/q23isline/reinventing_the_wheel/commit/8ea0327a19c724e5e52f09b9d04a939a462dd2f3)
- メンバー間でコード形式を統一するために、PHPStan を追加すべき個所はリポジトリの `composer.json` ですが、  
  いろいろな事情で追加できない（したくない）時に、参考にしていただければと思います
- この記事が他のエンジニアの助けになれば幸いです
Nuxt3のプロジェクトを作成してみる

## 経緯
先ほど[Nuxt3](https://v3.nuxtjs.org/)がbetaではあるが公開され、どんなものか早速プロジェクトを作成してみたので、そのやり方と感想を記載します。

## Nuxt3?
NuxtはVue.jsのフレームワークです。サーバーサイドレンダリング、静的なHTMLの出力などの機能など、Vue.jsで開発をスムーズに行うことが出来る機能が備わっています。

これまではVue2しか対応していませんでしたが、このNuxt3でVue3に対応しました。

## Nuxt3の機能、何が変わったのか？
ざっくりとサイトに目を通して、個人的に興味を持ったところを抜粋して紹介します。

### Vue3の対応
もちろんVue3への対応が一番大きいと思います。Vue3のコードから大幅に書きなおすことなく、Vue3の機能を使用できるようです。

### Nuxt Bridge
既存のnuxt2で作成されたプロジェクトをアップグレードする[Nuxt Bridge](https://v3.nuxtjs.org/getting-started/bridge)があるみたいです。
また、現状ではNuxt3で新しくプロジェクトを作成するよりかは安定しているそうです。

### Viteのサポート
サーバーの起動など(`npm run dev`)が一瞬になります。

### パフォーマンスの向上
どれくらい変わったかは未検証ですが、パフォーマンス的には`Nuxt3 > Nuxt Bridge > Nuxt2`になるみたいです。

## プロジェクトを作成してみる
[公式ドキュメント](https://v3.nuxtjs.org/getting-started/installation)のとおりに進めてみます。

```
npx nuxi init nuxt3-app
cd nuxt3-app
npm install
```

上記のあと、次のコマンドを実行してサーバーを起動させます。

```
npm run dev
```

起動はたった1~2秒で終わりました。ブラウザ`http://localhost:3000`にアクセスします。

![592be8ece6882507dcdda342cb2cd1c9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208110/f4f11850-1741-9793-8d57-b4ef5af521da.png)

このようなページが表示されました。

## ディレクトリ構造
上記で作成したプロジェクトのディレクトリ構造は以下のとおりになっていました。
![73fa5c6662bea01f25481c05063e2154.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208110/d5a8473e-0323-d290-0d4f-51d4cf2facac.png)

第一印象としては、標準がTypeScriptとなっているのと、とても構造がコンパクトになっていると感じます。

現段階では、`components`、`pages`、`layout`などの様々なディレクトリは自分で作成する必要があるようです。用意できる各ディレクトリは[こちら](https://v3.nuxtjs.org/docs/usage/data-fetching)に記載されています。

## まとめ
まだベータ版なので、今後どのようにアップデートがされるか楽しみです。ドキュメントも作成途中だと思いますが、まだ読み切れていないのでこれから読んでみようかなと思います。

情報の更新があれば、記事も更新するかもしれません。
Rails N+1問題への対処

## 課題
RailsのActiveRecordはRubyでデータベースとの問い合わせができる便利なツールである一方、発行されるSQLを意識しなくても済んでしまうため、効率の悪いクエリを発行していても気づかない危険性があります。Railsにおいては特にN+1問題という必要以上にデータベースに問い合わせをしてしまい、パフォーマンスを低下させてしまう問題がよく知られています。

## N+1問題とは？
N+1問題とは、「ループ処理の中で都度SQLを発行してしまい、大量のSQLが実行されパフォーマンスが低下する」という問題のことです。100件あれば100回、1000件あれば1000回、ループ処理の中で問い合わせすることになるので、いかにも非効率的です。馬鹿馬鹿しい初歩的なミスに聞こえますが、Railsを使用していると往々にしてこの問題が生じます。

では具体的なN+1問題の例を見ていきましょう。
まず、usersテーブルとpostsテーブルがあると仮定しましょう。

__groupsテーブル__

|  id  |  name  |
| ---- | ---- |
|  1  |  A  |
|  2  |  B  |
|  3  |  C  |

__usersテーブル__

|  id  |  group_id  | name  |
| ---- | ---- | ---- |
|  1  |  1  | 一郎  |
|  2  |  2  | 二郎  |
|  3  |  3  | 三郎  |
|  4  |  2  | 四郎  |

UserモデルとGroupモデルは一対一の関係で成り立っています。

```rb:app/models/group.rb
class Group < ApplicationRecord
  has_many :users
end
```

```rb:app/models/user.rb
class User < ApplicationRecord
  belongs_to :group
end
```

では全てのグループに所属する人を表示するプログラムを書いてみます。

```rb
Group.all.each do |group|
  user_names = comp.users.pluck(:name).join(",")
  p "#{group.name}: #{user_names}"
end
```
上記のコードでは、まずGroup.allでgroupsテーブルから全件レコードをとってきて、その結果に対しそれぞれ紐づけられたusersの情報を表示しています。結果は以下のようになります。

```sql
  Group Load (0.3ms)  SELECT `groups`.* FROM `groups`
   (0.3ms)  SELECT `users`.`name` FROM `users` WHERE `users`.`group_id` = 1
"A: 一郎"
   (0.3ms)  SELECT `users`.`name` FROM `users` WHERE `users`.`group_id` = 2
"B: 二郎、四郎"
   (0.3ms)  SELECT `users`.`name` FROM `users` WHERE `users`.`group_id` = 3
"C: 三郎"
```

まず一回目のSQLでgroupsテーブルの全ての情報を問い合わせ、その後各グループごとに所属ユーザーの問い合わせをしていることがわかります。n回ループをした場合、N+1回の問い合わせが生じてしまうため、N+1問題と言われています。
SQLを見れば非効率的なDB問い合わせをしているのがわかるのですが、このとおりRailsではSQLを意識することなくコードがかけてしまうため、知らず知らずのうちにこういった問題が起こります。今回の例ではデータが少ないためそこまでパフォーマンスに問題が出るわけでないですが、データ量が大きくなってくると無視できないレベルまでパフォーマンスが悪化してしまいます。特にRailsを使うようなWebアプリケーションではミリ単位のパフォーマンスが重視されるため、気をつけて実装する必要があります。

## 解決方法
先ほどのuserとgroupの例で言うと、Group.allでgroupの情報をとってくる段階でuserの情報を取って来れれば問題は解決しそうですね。そのためにはincludes()と言うメソッドを使います。

```rb
Group.all.includes(:users).each do |group|
  user_names = comp.users.pluck(:name).join(",")
  p "#{group.name}: #{user_names}"
end
```

```sql
SELECT `group`.* FROM `groups`
SELECT 'users'.* FROM 'users' WHERE 'users'.'user_id' IN (1,2,3,4,5)
```
今度はSQLが二つだけで済みました。

## N+1問題を検知するgem「bullet」
今回のように単純な構造のRDSなら自分でもログを見ていれば気がつけますが、複雑なシステム伴ってくると見落とす可能性もありますし、解決するのに時間がかかる可能性があります。
そこでN+1問題を自動で検知して解決方法を自動で提案してくれるgem「bullet」を使うことによって開発を効率化することができます。

```ruby:Gemfile
group :development do
  gem 'bullet'
end
```
Gemfileの開発環境のグループにbelletを記述し`bundle install`します。
次に`bundle exec rails g bullet:install`をターミナルで走らせると自動でconfig/environments/development.rbに詳細な設定が追記されます。

```rb:config/environments/development.rb
config.after_initialize do
  Bullet.enable        = true
  Bullet.alert         = true
  Bullet.bullet_logger = true
  Bullet.console       = true
# Bullet.growl         = true 
  Bullet.rails_logger  = true
  Bullet.add_footer    = true
end
```
それぞれの項目については[公式のdocument](https://github.com/flyerhzm/bullet)を読んで適宜調整してください。
これで準備完了です。これでアプリを走らせれば、N+1問題が発生した時に自動でアラートで知らせてくれるようになります。
Gitの基本とコマンド

#目次
######基本
[0.はじめに](#0-はじめに)
[1.ファイルの作成、編集を行う](#1-ファイルの作成、編集を行う)
[2.ファイルの作成/変更/削除をgitのインデックスに追加する](#2-ファイルの作成/変更/削除をgitのインデックスに追加する)
[3.変更結果をローカルリポジトリにコミットする](#3-変更結果をローカルリポジトリにコミットする)
[4.ローカルリポジトリをプッシュしてリモートリポジトリへ反映させる](#4-ローカルリポジトリをプッシュしてリモートリポジトリへ反映させる)

######ブランチ
[1.ブランチの作成、移動](#1-ブランチの作成、移動)
[2.ブランチにプッシュ](#2-ブランチにプッシュ)
[3.ブランチからプル](#3-ブランチからプル)
[4.ブランチのマージ](#4-ブランチのマージ)

######リポジトリをローカルにClone
[1.Clone URLをコピー](#1-Clone URLをコピー)
[2.ターミナルでgit clone](#2-ターミナルでgit clone)

#0. はじめに
Gitのコマンドを忘れてしまうのでメモ程度にまとめました。
「１」の作成は初回のみ行い、「２」から「４」を繰り返す。

#1. ファイルの作成、編集を行う
ローカルのPC上にローカルリポジトリを作成する。
今回は[sample]というディレクトリを作成する。
[mkdir]...新しくディレクトリを作成する。
[cd]...ディレクトリを移動する。
[git init]...新しくGitリポジトリを作成する。

```
>> mkdir sample 
   cd sample
   git init
``` 
次に作成したファイル（今回はsample.html）をsampleフォルダに保存する。

#2. ファイルの作成/変更/削除をgitのインデックスに追加する
「sample.html」のファイルをローカルリポジトリに追加する。
インデックス...リポジトリにコミットする準備をするために変更内容を一時的に保存する場所。

```
>> git add sample.html(←ファイル名)
   
``` 

#3. 変更結果をローカルリポジトリにコミットする
インデックスに追加されたファイルをコミットする。

```
>> git commit -m "add new file"
   
``` 
リモートリポジトリに反映させる前に、リモートリポジトリの情報を追加する。


```
>> git remote add origin https://github.com//sample.git ←自分のリモートリポジトリに置き換える
   
``` 
#4. ローカルリポジトリをプッシュしてリモートリポジトリへ反映させる
ローカルリポジトリの変更を、Github上にあるリモートリポジトリに反映させる。

```
>> git push origin master
   
``` 

#ブランチの使用法
ブランチは履歴の流れを分岐して記録していくもの。
#1. ブランチの作成、移動
現在のブランチの確認

```
>> git branch
   
```
作業中のブランチには「*」が付く。
「feature/step1」というブランチを作成する。

```
>> git branch feature/step1
   
```
[checkout]...ブランチの移動

```
>> git checkout feature/step1
   git checkout -b feature/step1 ←ブランチの作成と移動をまとめて行う
   
```

#2. ブランチにプッシュ
作成したファイル（今回はbranchsample.html）をgitに追加、コミットする。

```
>> git add branchsample.html
   git commit -m "feature/〇〇"
   
```

リモートリポジトリの情報は登録済みなので、ブランチ名を指定して、プッシュする。

```
>> git push origin feature/step1
  
```
#3. ブランチからプル
他の開発者がbranchsampleリポジトリで開発する場合にプルコマンドを使って行う。
リポジトリfeature/step1に移動する。

```
>> git checkout feature/step1
  
```

リモートブランチfeature/step1のコードを取得する。


```
>> git pull
  
```

#4. ブランチのマージ
新機能をブランチを使って開発を行い、テストが完了したら、メインのブランチに取り込む。取り込む作業のことをマージという。
作業中のブランチをmasterに切り替える。

```
>> git checkout master
  
```
feature/step1ブランチの作業結果をマージする。

```
>> git merge feature/step1
  
```
GitHubにプッシュする。

```
>> git push origin master
  
```

#リポジトリをローカルにcloneする方法

#1. Clone URLをコピー
GitHub上でcloneしたいリポジトリのページに行き、clone URLをコピー

#2. ターミナルで git cloneする
ターミナルでcloneしたいディレクトリに移動し、コピーする。

```
>> cd projects
   git clone git@github.com:xxx/clonesample.git
  
```
Slackを使おう！

#Slackメッセージを見やすく！
テキストメッセージで正確に伝えるためには、ちょっとした工夫が必要です。
この記事は、他の方が書いている記事を自分用備忘録として残すことが目的です。（もっとわかりやすいものはたくさんあります！！）
ここでは以下の３つと最後におまけを記しておこうと思います。

1. グレー（灰色背景）で表示させる方法
2. 太字にする
3. 引用の形式にする

##グレー（灰色背景）で表示させる方法

####バッククウォート３連打 → 『```』 

バッククォートの入力方法（半角で行う）
・Windows：Shift + ＠
・Mac：command + @

ちなみに短文なら、バッククウォートでテキストを囲うと短くできます。

例：https://gyazo.com/4252c81f0d27e42bbdfd3f424d969200

##太字にする

#### 『*』で囲う
実際太字は『B』にて設定できる。
キーボードから手を離したくないときに有効。

例：https://gyazo.com/3fd49ac6fdbf046ac450b5205ab4ac92

##引用の形式にする

####『>』

メッセージ冒頭に記述すれば大丈夫です。
引用した部分に使用するとわかりやすくできそうかと！

例：https://gyazo.com/0814769ecc754a3e418c1501e9645084

##おまけ

#### +:絵文字コード:
+:OKと入力するとこのような感じにでてきます！
キーボードで素早くレスポンスを返せます！（慣れると便利！）

![スクリーンショット 2021-10-13 0.13.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2161951/7b6c2c17-0b79-5c3f-1433-2f1001910823.png)


さまざまな参考記事が充実していてありがたい今日この頃です。
ありがとうございました！！！
JetPack4.5.1とJetPack4.6を行き来している間に起きるカメラの不具合(Jetson NX Xavier)


JetPack4.5.1とJetPack4.6を行き来しているうちに、Jetson NX XavierがCSIカメラのクリティカルエラーで落ちるようになる

## エラー内容

```
gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! nvoverlaysink
```

```
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:645 No cameras available

(gst-launch-1.0:21557): GStreamer-CRITICAL **: 20:55:08.910: gst_mini_object_set_qdata: assertion 'object != NULL' failed
Got EOS from element "pipeline0".
Execution ended after 0:00:00.031217692
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
(Argus) Error EndOfFile: Unexpected error in reading socket (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 266)
(Argus) Error EndOfFile: Receive worker failure, notifying 1 waiting threads (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 340)
(Argus) Error InvalidState: Argus client is exiting with 1 outstanding client threads (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadCore(), line 357)
(Argus) Error EndOfFile: Receiving thread terminated with error (in src/rpc/socket/client/ClientSocketManager.cpp, function recvThreadWrapper(), line 368)
(Argus) Error EndOfFile: Client thread received an error from socket (in src/rpc/socket/client/ClientSocketManager.cpp, function send(), line 145)
(Argus) Error EndOfFile:  (propagating from src/rpc/socket/client/SocketClientDispatch.cpp, function dispatch(), line 87)
```

```
nvgstcapture
```

```
...

bitrate = 4000000
Encoder Profile = High
Encoder control-rate = 1
Encoder EnableTwopassCBR = 0
Opening in BLOCKING MODE
Opening in BLOCKING MODE 
** Message: 20:57:13.753: <main:4670> iterating capture loop ....
NvMMLiteOpen : Block : BlockType = 4 
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4 
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:645 No cameras available

(nvgstcapture:21803): GStreamer-CRITICAL **: 20:57:13.791: gst_mini_object_set_qdata: assertion 'object != NULL' failed
```

## 原因

Jetson NX XavierをJetPack4.6を焼いたSDカードから起動すると、bootromのUpdateがおこなわれる。その状態で、JetPack4.5.1のSDカードを起動すると、カメラ周りが起動しなくなる場合がある。

Jetson Xavier NXでは、JetPack 4.6をインストール後 Bootromの更新が行われる。

![bootrom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63450/2e351455-4e42-5a9a-da93-796c7175ee30.png)


## 復活方法

SDKManagerからJetPack 4.5.1をインストールする事で復活する。
Ruby(Open-URI)とNokogiriでスクレイピングした際に出会ったエラー対応（404エラーのハンドリング）

## はじめに

Ruby（Rails）でWebスクレイピングをしたとき

URLが404 Not Foundになり指定したURLのリソースが見つからず、以下のエラーを出力して止まってしまって困りました。

```
OpenURI::HTTPError
```

今回はこのエラーハンドリングの話をします。

ちなみに、Webスクレイピングで用いたライブラリやGemは、`OpenURI`と`Nokogiri`です。

### 用語の説明

**OpenURI**

- httpやftpを通じてネットワーク上のリソースを取得することができます。こちらはRuby標準のライブラリです
- こちらだけでもスクレイピングは行えます

https://docs.ruby-lang.org/ja/2.7.0/library/open=2duri.html

**Nokogiri**

- こちらも、Webスクレイピングをサポートしてくれるやつです。こちらは、HTMLの情報を全て取得したい場合に楽に扱えます
- 特定のDOMを取得する際の 僕はよく使う`search` など、スクレイピングをする上でひつようなメソッドがたくさんあるので、よく用いています

https://otn.hatenablog.jp/entry/20090509/p1

## 現象

ざっくり、以下のようなコード書いていたら

```rb
require 'open-uri'
require 'nokogiri'

url = 'https://www.test.jp/'

# open-uriでurlにアクセスしてhtmlを取得し、Nokogiriでパースする
doc = Nokogiri::HTML(open(url), nil, 'utf-8')
```

特定のページで404が発生し、エラーが発生し、それ以上スクレイピングできなくなりました。

## 対策

困るので、エラーハンドリングしつつ、スクレイピングを続けられるようにしましょう。

```rb
require 'open-uri'
require 'nokogiri'

url = 'https://www.test.jp/'

begin
  # open-uriでurlにアクセスしてhtmlを取得し、Nokogiriでパースする
  doc = Nokogiri::HTML(open(url), nil, 'utf-8')
rescue OpenURI::HTTPError => e
  # 例外処理
end
```

これでハンドリングできました。

## さいごに

当たり前ですが、このスクリプトを間髪を入れずに連続して実行すると対象となるサーバへ連続的にアクセスが行われてしまうので絶対にしないようにしてください。

本日は、以上です。

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
PHPでnull判定関数(isset, empty, is_null)の違い

## はじめに
実務で「変数に配列がセットされてるけど、空配列であることを判定」する必要がありました。
PHPでは配列の空判定が出来る関数としてisset, empty, is_nullがありますが、違いがよくわからずに苦労しました。
理解を深めるために違いをまとめたので記事にしました！

## 対象者
この記事は下記のような人を対象にしています。

- 駆け出しエンジニア
- プログラミング初学者
- null？空文字？なにそれ美味しいの？な人
- isset, empty, is_null...聞いたことあるけど、全部同じじゃないの？と思ってる人

## PHPのnull判定関数(isset, empty, is_null)の違い早見表
まずは結論から。

||  値  |  if($var)  |  isset  |  empty  |  is_null  |
|----| ---- | ---- | ---- | ---- | ---- |
|1|  $var=1  |  true  |  true  |  false  |  false  |
|2|  $var="";  |  false  |  true  |  true  |  false  |
|3|  $var="0";  |  false  |  true  |  true  |  false  |
|4|  $var=0;  |  false  |  true  |  true  |  false  |
|5|  $var=NULL;  |  false  |  false  |  true  |  true  |
|6|  $var  |  false  |  false  |  true  |  true  |
|7|  $var=array()  |  false  |  true  |  true  |  false  |
|8|  $var=array(1)  |  true  |  true  |  false  |  false  |

以下、それぞれについて解説します。

### PHPのisset関数
>変数が宣言されていること、そして null とは異なることを検査する

[公式ドキュメント](https://www.php.net/manual/ja/function.isset.php)より

「変数が宣言されていること」がempty, is_nullと違う点なので注意です。
表5のケースでは変数$varにnullがセットされているのでfalse。
表6のケースでは変数$varは宣言されているものの、値はセットされていないのでfalse。
それ以外のケースでは、空文字/数字の0/空の配列だろうと、nullでないものがセットされてるのでtrueです。


### PHPのempty関数
>変数が空であるかどうかを検査する

[公式ドキュメント](https://www.php.net/manual/ja/function.empty.php)より

PHPのempty関数は「空であるかどうか」を判定します。
空文字/数字の0/文字列の0/null/空の配列などがtrueになります。

### PHPのis_null関数
> 変数が null かどうか調べる

[公式ドキュメント](https://www.php.net/manual/ja/function.is-null.php)より

名前の通り、null/何もセットされていない場合にtrueになります。


### と、いうことはissetと!is_nullは一緒やんな？→違います
ぱっと見、issetとis_nullは正反対の判定をしているように見えます。
ということはissetと!is_nullどっち使ってもいいはず...と思ったあなた、ダウトです。
issetは「変数が宣言されていること」も判定していますが、is_nullは関係ありません。

```php:test.php
$x = 'test';
var_dump(isset($y));
// 結果(変数$yは宣言されていないのでfalse)
bool(false)

$x = 'test';
var_dump(!is_null($y));
// 結果(そもそも$yが宣言されていないのでundefined)
PHP Notice:  Undefined variable: y in test.php on line 7
```
## おわりに
PHPのnull判定関数(isset, empty, is_null)の違いについてまとめました。
特にissetと!is_nullは素人目には同じように思えましたが、きちんと調べると挙動が違うことが理解できました。


## 参考記事
[PHP isset, empty, is_null の違い早見表](https://qiita.com/shinichi-takii/items/00aed26f96cf6bb3fe62)
わたしがWindows10を新規セットアップするときにやること

#インストールするもの
##マルチメディア
**VLC Media Player** : 動画ビューア
**IrfanView** : 写真ビューア
**Aviutl** : 動画編集
**GIMP** : 画像編集

##ブラウザ関連
**Firefox ESR**
前までは逆張ってWaterfox Classicをつかっていましたが時代の波に流されこうなりました
####拡張機能Waterfox Classic
uBlock Origin : 広告ブロック
Download Manager : ダウンロードマネージャ
Better TweetDeck : TweetDeck拡張

##その他
**エディタ** : Sublime Text 3
**IDE** : Visual Studio : 特に何を作るというわけでもないけど。
**端末** : Windows Terminal についての解説はわたしの他の記事を参照ください
**シェル** : PowerShell 7.x
**暗号化** : VeraCrypt :システムパーティションごと暗号化します(いまはしてないけど)
**便利** : Microsoft PowerToys
**ディスクヘルスチェック** : Crystal Disk Info
**メーラー** : Mozilla Thunderbird 
**老害** : Classic Shell

#チューニング（笑）関連
##タスクバーまわり

- 検索ボックスを消す
- Cortanaボタンを消す
- 小さいアイコンを使う
- ラベル化する(入りきらない場合まとめる)


##殺しておくサービス
services.mscからサービス一覧を開ける

###診断系

- Diagnostic Execution Service
- Diagnostic Policy Service
- Diagnostic Service Host
- Diagnostic System Host

###殺しておくことを推奨
- SysMain
- Windows Search
- Xbox Game Bar グラボのドライバに入っているもの(Radeon Reliveなど)をつかうため

あとはタスクスケジューラからWinSATを止めるなどをします
Ubuntu20.04でXmodmap使って左Win(Super_L)キーを左Ctrl（Control_L）に書き換え

## 状況
US配列キーボードを使っていて、キーボード側の設定でキー配置やら変えており、更にWindowsでは[Change Key](https://forest.watch.impress.co.jp/library/software/changekey/)を使ってキーマッピングを調整していました。

今回Superのキーマップ変更に詰まったため、備忘録のため書いておきます。
（※自分はこんな感じで行けたのですが、知識が浅いためもし不備等があったらすみませんm(_ _)m）

## 手順
こちらの記事を参考に、Xmodmapのバックアップをとり、xevを実行します。

https://qiita.com/tamayaman/items/f87bbd092702d6c36f8b

自分の場合、`xev`を実行した際に__左Winキー（Super_L）を押すとアクティビティ画面（Macのミッションコントロールみたいな）が起動してしまい__、`xev`が起動しているコンソールにもそれらしい情報が出ませんでした。
一方、右Winキー（Super_R）はkeycode=134と表示されました。
ここで↑でバックアップをとった.Xmodmap_defaultを確認。（`less ~/.Xmodmap_default`）
しばらくスクロールするとkeycode = 133がSuper_Lとあるため、この情報を使います。

## 完成形

https://askubuntu.com/questions/137172/how-to-remap-superleft-key-to-control-key

こちらを参考にmod4からSuper_Lを削除。（`xmodmap -pm`で確認）
そしてkeycode=133にControl_Lを割り当て。
`xmodmap ~/.Xmodmap`で反映後、ここで自分は期待した挙動になりました。

```:.Xmodmap
clear control
remove mod4 = Super_L

keycode 133 = Control_L

add control = Control_R Control_L
```

## 備考
Arch Linuxの記事ですがこちらを参考に`.xinitrc`ファイルを用意することでPC起動時に自動適用されるようにしました。

https://wiki.archlinux.org/title/xmodmap#Custom_table
GSAPでサイドバーを固定しながらスクロール追従

GSAPのScrollTriggerのピン留め機能を使用したら簡単に実装できました。

## デモ
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="powXXVM" data-user="miyakezaka" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/miyakezaka/pen/powXXVM">
  GSAPでサイドバーを固定しながらスクロール追従</a> by miyakezaka (<a href="https://codepen.io/miyakezaka">@miyakezaka</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## GSAPを使う利点
- 実装が簡単で動作も安定している
- スクロールの対象のエリアのみ処理が行われるためブラウザ負荷が少ない
- IE11にも対応している

## その他の方法で実装した場合
GSAPを使用しないでサイドバーを固定する方法だと主に以下が考えられます。

### CSSプロパティのposition: sticky;で実装
position: sticky;を紹介した記事をたくさん目にしますが、使用する場面が限られると思いました。

- サイドバーに要素が多いと実装できない
- IE11に対応していない（ポリフィル読めば対応できるらしい）

### JS処理を組み合わせて実装
こちらは実装と他コンテンツの考慮などとにかく大変でした。

- ページによってコンテンツの有無で高さが異なるなど、上手く設計してメンテしないと表示崩れが起きやすい。
- スクロールの対象のエリア外でも常に処理が行われるため負担がブラウザ負荷がかかる

## コード解説
JS部分のコードの解説に入ります、GSAPの基本的なところは省きます。
まずはGSAP本体とScrollTriggerの２つを読み込みます。

#### HTML
```
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/ScrollTrigger.min.js"></script>
```

ScrollTriggerを設定していきます。
ポイントはendTriggerキーに固定を解除したい要素を指定して、endキーに指定要素のどの位置で解除するかを指定します。
マーカーで位置を確認しながら進めるとやりやすいです、狙った箇所で簡単に固定 〜 解除ができました。

#### JS
```
gsap.to('.sidebar', {
  scrollTrigger: {
    trigger: '.sidebar',
    start: 'bottom 100%',
    end: 'bottom 100%',
    endTrigger: 'main',
    pin: true,  
    markers: true
  }
});
```