OmniAICreator/Qiita-1.07M huggingface dataset:
Googleデータアナリティクス：効果的なビジュアライゼーション

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/05522c3b-515a-bc49-aaa3-a0489a6b12b1.png" width="800">

# 効果的なビジュアライゼーション

最適なデータ ビジュアライゼーションを選ぶ際、 一つの問いに行き着くことがあります。それは、

***<font color="MediumVioletRed">『ユーザーに最も理解しやすいのはどれか？」』</font>***

ということです。

分析結果がどんなに複雑だったとしても 聞き手にとっては目の前にあるものが いかに簡単に理解できるかが問題です。 分析が完了したら、それぞれのタスクについて どのビジュアライゼーションが自分と聞き手の ニーズを満たすかを判断する必要があります。 

データ ビジュアライゼーションでは 常に聞き手を第一に考え、聞き手にどのように 見えるかを理解することが重要です。 また、すべては脳から始まります。 ビジュアライゼーションの情報を処理するとき 私たちの脳はパターンを見つけようとし、 コンテキストを探ろうとします。 データアナリストは、 人間の視覚システムを理解することで より良いビジュアルを作成できます。 ビジュアライゼーションを作成する際には それを念頭に置き、 聞き手が情報を処理しやすく、 見たものを記憶しやすいようにしましょう。 

ビジュアル・ジャーナリストの ドナ・ウォン氏は 効果的なビジュアライゼーションには 3 つの必須要素があるとしています。 

### <font color="MediumBlue">1.明確な意味を持たせる</font>

優れたビジュアライゼーションは、 意図したインサイトを明確に伝えます。 

### <font color="MediumBlue">2.コントラストを巧みに利用する</font>

脳が自然に探す視覚的コンテキストを利用して 最も重要なデータを 他のデータから切り離すのです。 

### <font color="MediumBlue">3.洗練された実行力</font>

細部にまで注意を払って洗練された ビジュアルを実現することです。 線、形、色、明度、スペース、ムーブメントなどの ビジュアライゼーションの要素を駆使します。 

:::note info
多くのビジネスでは、まず顧客を満足させることが 原則ですが、データアナリティクスも同じです。 顧客となるのは、おそらくマネージャーや その他のステークホルダーですが データ ビジュアライゼーション作成の際には 常に彼らのことを第一に考えるべきです。 5 秒ルールを思い出してください。 データビジュアライゼーションを見やすく、 すばやく理解できるものにできれば その時点でほぼ役目は果たせています。 顧客もあなたも満足することができるでしょう。 
:::

# データは美しい
【Ruby】空配列がtrueになるんですが。。。

# はじめに
Qiita初投稿です！
Rubyの勉強を始めてもうすぐ1ヶ月になります。サンプルコードだけでなく、自身でロジックを考えながら書くようになってきました。そんな中、他の言語ベースの知識と混同していた事があったため共有と自身の備忘録も兼ねて残しておきたいと思います。
# 配列とは？
以下のように大括弧[]に囲まれた要素をカンマで区切ったものを言います。
```
array = [123, '文字列', true, nil]
```
また、多次元配列で要素を格納することもできます。
```
nest = [[123, 'りんご', true], [456, 'ぶどう', false], [789, 'いちご', false]]
```
# 問題のコードと検証
### 今回やりたかったこと
2つの配列があり、それらを比較して1つでも一致した時はtrue、１つも一致しなかった時はfalseを返したかったため、以下のように書いていました。
```
if !!([1, 2, 3] & [1, 2, 3]) #=> true
if !!([1, 2, 3] & [4, 5, 6]) #=> falseのはず？
```
:::note info
ここで使用している&はビット演算のANDをしています。
:::
:::note info
!!はtrueかfalseのみを返すために使っています。
!ひとつでは元の状態から反転した状態で真偽値が返ってくるので、それをさらに反転させることで元の値をtrueかfalseのみで返すようにしたい時に使います。
:::
### irbに入れて結果を確認してみよう
```
irb(main):001:0> !!([1, 2, 3] & [1, 2, 3])
=> true #わかる
irb(main):002:0> !!([1, 2, 3] & [4, 5, 6])
=> true #わからないｗ
```
::: note info
irbは対話型評価環境(REPL:Read-eval-print loop)です。
Rubyをインストールしている場合、デフォルトで入っています。
ターミナルやコマンドプロンプトで「irb」と入力して実行することで起動します。
:::
### なぜ空配列はtrueが返るのか？
今回のケースでは、以下のRubyにおける真偽値の扱いを知っておく必要がありました。
- Rubyでは**false**と**nil**以外は全て真 ~~、つまり**true**~~ として扱われる。
- 空配列は、大括弧の中身は**空**であるものの、~~配列そのものは存在しているので**true**が返る~~nilでもfalseでもないので真になってしまう。
# なぜ空配列はfalseになると決めつけていたのか？
以前、Pythonでスクレイピングをしていたときにlistを扱っており、Rubyの配列に似た構造を持っていたため、Pythonの時と同じように空の配列は**falseが返ってくるはず**と安易に考えていたことが原因でした。
以下、Google Colaboratoryでの実行例です。
### listに何か入っている場合
```
list = ['なにか', '入っている']
if list:
  print('あるよ')
else:
  print('ないよ')
# =>あるよ
```
### listに何も入っていない場合
```
list = []
if list:
  print('あるよ')
else:
  print('ないよ')
  # =>ないよ
```
# どうすれば良かったのか？
### 解決したコード
any?メソッドを用いて、全ての要素が偽である場合にfalseを返すようにしました。
```
[1, 2, 3].any? { |element| [4, 5, 6].include?(element) }
```
### そもそもの学習の進め方について
つよつよエンジニアの人の中には、
- プログラミング言語の違いは方言の違い
- 書き方が少し違うだけだから、他の言語を使えるならすぐ覚えられる
- 難しいところは特にないし、すぐ出来るようになる

などと、こちらの気持ち、感覚とは逆のことを言ってくる人がいたりします。そういった言葉を鵜呑みにしてすぐに習得できるものだと勘違いしたり、技術書を早く読み終えて学習を**終わった事**にしようとしたり、オリジナルコードを書かずにサンプルコードを試して**分かった気**になっていたりすると今回の私のようになります。

つまり、基礎をしっかりと築き上げるために、***言語の差分の理解に努められるようになるまでは、技術書を使い最初から最後まで体系的に学び、小さくても良いのでオリジナルコードを書いて試すこと***をおすすめします。
# あとがき
今回の失敗は、こうなるだろうという**思い込み**が招いた結果でした。他の言語ではこう書いていたからなどと考えずに、流用して良い知識とダメな知識をしっかりと使い分けていきたいと思います。
最後に誰もが知っているであろう名言で終わりたいと思います。

***「プログラムは思った通りには動かない。書いた通りに動くのだ。」***

うっ…、頭が…。
Jiraで複数のプロジェクトのタスクを１つのボードに表示する

# 概要
複数のJiraプロジェクトにあるタスクをまとめて１つのカンバンボードに表示する方法のメモ。

**手順概要**
* 表示したいタスクを抽出するフィルターを作成する
* そのフィルターを使ってカンバンボードを作成する

# 手順
### フィルタの作成
"Filters" -> "Advanced issue search"を開く
![Screen_Shot_2023-04-19_at_13_47_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/ee68dd8b-1027-0560-3e25-5b07abc7fefb.png)

フィルタ作成画面にて条件を選択してフィルタを作成する。より高度な条件を作成したい場合は"Switch to JQL"をクリックして、JQL (Jira Query Language) を使用して条件を記述できる。
![Screen_Shot_2023-04-19_at_13_54_32-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/8798c08b-1fa4-5512-9734-0df42b8e6d02.png)



自分の場合、下記の条件のフィルタを作成した。
* 特定のプロジェクトを除外（GS, GSTS）
* 自分のタスク
* 未完了のタスク、または、８週間以内に完了したタスク

この条件は下記のようなJQLになる。
```
project not in (GS, GSTS) AND assignee in (currentUser()) AND (resolved > -8w OR resolved is EMPTY) order by created DESC
```

フィルタができたら "Save as" で保存する。
![Screen_Shot_2023-04-19_at_14_04_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/b9f20778-5c0e-4a74-95b7-58285307af31.png)

## カンバンボードの作成
"Your work" -> "Boards" -> "View all boards" でボード一覧画面を開く。
![Screen_Shot_2023-04-19_at_14_09_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/d5d7509c-425e-0143-ee28-f9666d3ca29b.png)

ボード一覧にて"Create board"をクリック。
![Screen_Shot_2023-04-19_at_14_11_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/bffd0e7b-b325-b612-2976-5a4134fe93fa.png)

"Create a Kanban board"をクリック。
![Screen_Shot_2023-04-19_at_14_12_31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/84ed338b-a2ab-8145-c474-511712d1f63f.png)

"Board from an existing Saved Filter"を選択し、Nextボタンをクリック。
![Screen Shot 2023-04-19 at 14.15.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/6d9dcd16-da2d-6170-5c29-9f63c55c50e1.png)

任意のボード名を入力、先ほど作成したフィルタを選択、Locationも選択しから任意の場所を選択。
"Create board"ボタンをクリックして完了。
![Screen Shot 2023-04-19 at 14.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/5245dae3-9593-8809-c497-920e0dd19545.png)

これで複数のプロジェクトのタスクを表示するなど、任意の条件のタスクを１つのボードに表示することができた。
（下のスクショはたまたま１つのプロジェクトのタスクしか写っていない）
![Screen_Shot_2023-04-19_at_14_20_56-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138322/8c5b60e1-9287-d386-47ba-1e66f581bf6c.png)

いつでも "Your work" -> "Boards" から開くことができる。
Zodのstrictを使ってバリデーションしてみる

# 前提
本配属されて最初にやったのがTypeScriptのオンボーディングでした。その中で[Zod](https://github.com/colinhacks/zod)の`strict()`でバリデーションすると便利だったので紹介します。

# 使用例
まずはインポート
```index.ts
import { z, ZodError } from 'zod';
```

次のような型でjson入力を受け取りたいので、zodを使って正しい型入力になっているかチェックしたい。
- `name`：string
- `age`：number
- `friend`：Friend
    - `friendName`：string
    - `friendAge`：number

```request.json
{
    "request":{
        "name": "Alice",  // string型
        "age": 10,  // number型
        "friend": [
        	{
        		"friendName": "Bob",
        		"friendAge": 10
        	}
        ]
    }
}
```

この場合は次のように実装してバリデーションする。
```index.ts
const _Friend = z.object({
  friendName: z.string(),
  friendAge: z.number()
})

type Friend = z.infer<typeof _Friend>


const _Menber = z.object({
  name: z.string(),
  age: z.number(),
  friend: z.array(_Friend)
}).strict()

type Event = z.infer<typeof _Menber>  // 未使用


const _Request = z.object({
  request: _Menber
}).strict()

type Request = z.infer<typeof _Request>
```

`strict`であらかじめ決められた型に合致しなければエラーを吐き出す関数を使って型を用意する。

- `string()` `number()`
  - 指定した型に合致するか判定
- `object()`
  - ここではリクエスト構造を定義
- `infer<>`
  - 値として定義した構造を型に変換

また、ZodErrorを使うために次のように実装します。
```ts
try{
    //処理内容
} catch (e: unknown) {
    console.log(e)
    if (e instanceof ZodError) {
      return res.status(400).json(
        e
      )
    } 

```

すると次のように出力されました。
成功時：想定の挙動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3077345/d0b49301-13be-c1c4-1c0c-6aa88fd5a05a.png)

失敗時：`age`をstringで入力した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3077345/a556d0ff-800a-1b3c-996b-75c721c90704.png)

**`z`をcatchしてjsonでreturnすればエラー内容が一括で出力されるのがかなり便利だと思いました。**
みなさんも使ってみてください。
MacでPHPの古いバージョンを使う


仕事の関係でPHPのバージョンを7.1に下げる必要がありました。
割と正規のやり方ではない？と思いますが、PHP7.1を使用することに成功したので備忘録的に書いておきます。

まず、Macのターミナルを開いて
`brew search php`でインストールできるPHPのバージョンを確認しました。
結果はこんな感じでPHP7.4より前のバージョンにできないことがわかります。
![スクリーンショット 2023-04-19 12.49.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961306/28dde73c-2756-1a62-c0bb-0dc40665bcf1.png)


## 解決方法
```
brew tap shivammathur/php
brew install shivammathur/php/php@7.1
brew link --overwrite --force shivammathur/php/php@7.1
```
これをやったらとりあえず動きました

### 参考記事
https://github.com/shivammathur/homebrew-php
jestでのテストコード実行時、警告が出て処理が終わらない問題の解決

## 状況
jestでテストコード実行したところ、以下のような警告が出て処理が終わらない状態になった。Ctrl + Cをしたら終わらせることは出来る。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/bd486527-3f23-c6af-45e6-97a893564a05.png)

## 原因
expressモジュールのapp.listenは、サーバーを起動し、接続待機中の状態にする非同期処理です。Jestはこの非同期処理が終了するのを待機してしまっている。

## 解決方法
メインのプログラムの中で「app.listen」しているところは戻り値がもらえるので、変数に代入する形に変更

```javascript:hoge.js
const server = app.listen(
```

さっき代入した変数のclose()を使えばサーバー終了できるので、それをするメソッドを作成。

```javascript:hoge.js
const closeServer = () => {
  server.close();
};
```

テストコード側で、テストケースごとのメソッドの中の最後の最後に以下のようにさっき作ったcloseServerメソッドを呼び出す
※hogeModuleという名前の変数にエクスポートしたメソッドを入れた場合

```javascript:hogeTest.js
hogeModule.closeServer();
```
[AWS Q&A 365][Redshift Spectrum]AWSのよくある問題の毎日5選 #34

# 1. Amazon Redshift Spectrumとは何ですか？
答え：Amazon Redshift Spectrumは、Amazon S3のファイルから構造化および半構造化データをクエリして取得できる機能で、Amazon Redshiftテーブルにデータをロードする必要がありません。

# 2. Redshift Spectrumはどのようにクエリを実行しますか？
答え：Redshift Spectrumクエリは、大規模なデータセットに対して非常に高速に実行されるマッシブな並列処理を利用します。処理の大部分はRedshift Spectrumレイヤーで行われ、データのほとんどはAmazon S3に保持されます。

# 3. Redshift Spectrumを使用する利点は何ですか？
答え：Redshift Spectrumを使用することで、Amazon S3上のファイルから直接データをクエリでき、Amazon Redshiftテーブルにデータをロードする必要がなくなります。これにより、時間とリソースを節約でき、さらに大規模なデータセットをクエリできるようになります。

# 4. Redshift Spectrumテーブルを作成する方法は？
答え：Redshift Spectrumテーブルは、ファイルの構造を定義し、それらを外部データカタログに登録することで作成します。外部データカタログは、AWS Glue、Amazon Athenaに付属するデータカタログ、または独自のApache Hiveメタストアのいずれかです。

# 5. Redshift Spectrumの外部テーブルをパーティションに分割できますか？
答え：はい、外部テーブルを1つ以上の列でオプションでパーティションに分割できます。外部テーブルの一部としてパーティションを定義することで、パフォーマンスが向上し、Amazon Redshiftクエリオプティマイザがクエリのデータを含まないパーティションを除外できます。
[AWS Q&A 365][Redshift Spectrum]Daily Five Common Questions #34

# 1. What is Amazon Redshift Spectrum? 
Answer: Amazon Redshift Spectrum is a feature that allows you to query and retrieve structured and semi-structured data from files in Amazon S3 without having to load the data into Amazon Redshift tables. 

# 2. How does Redshift Spectrum perform queries? 
Answer: Redshift Spectrum queries employ massive parallelism to run very fast against large datasets. Much of the processing occurs in the Redshift Spectrum layer, and most of the data remains in Amazon S3. 

# 3. What is the benefit of using Redshift Spectrum? 
Answer: Redshift Spectrum allows you to query data directly from files on Amazon S3 without having to load the data into Amazon Redshift tables. This can save time and resources, as well as enable you to query larger datasets. 

# 4. How do you create Redshift Spectrum tables? 
Answer: You create Redshift Spectrum tables by defining the structure for your files and registering them as tables in an external data catalog. The external data catalog can be AWS Glue, the data catalog that comes with Amazon Athena, or your own Apache Hive metastore. 

# 5. Can you partition external tables in Redshift Spectrum? 
Answer: Yes, you can optionally partition external tables on one or more columns. Defining partitions as part of the external table can improve performance, as the Amazon Redshift query optimizer eliminates partitions that don't contain data for the query.
【SwiftUI】CSVファイルからデータを取得する方法

## はじめに
現在作成中のクイズアプリで、CSVファイルからデータを取得する必要があったのでその方法をメモします。
また、SwiftUIでCSVファイルからデータを取得する方法はいくつかありますが、今回は、`SwiftCSV`というライブラリを使用します。
おそらくこの方法が一番簡単にCSVファイルからデータを取得できると思います。

## 実装方法
### STEP1
プロジェクトにCSVファイルを追加します。

::: note warn
注意
ここで注意して欲しいのが、CSVファイルにデータを入れる際に下記のようにカラムも入れてください。なぜカラムを追加するかと言うと、SwiftCSVが自動的に一番先頭の行をカラムと判断してしまうため、後でうまくデータを取得できない可能性があるからです。
あくまで私の解釈なので、間違っていたらすいません。。
:::

```swift
// 悪い例
1,りんご
2,オレンジ
3,ブドウ
// 良い例
No,果物
1,りんご
2,オレンジ
3,ブドウ
```
### STEP2
SwiftCSVをCocoaPodsなどのパッケージマネージャを使用して、SwiftCSVをインストールします。
CocoaPodsでインストールする場合は、podファイルに以下のように`SwiftCSV`を追加してください。

```terminal:Podfile
target 'YourProjectName' do
  use_frameworks!
  pod 'SwiftCSV'
end
```
もしCocoaPodsの使用方法がわからない方は、以下の記事がわかりやすいので参考にしてください。

https://tech.amefure.com/swift-cocoapods

### STEP3
SwiftCSVをインポートします。
```Swift
import SwiftCSV
```
### STEP4
STEP1で作成したファイル名を以下のコードの**forResource**に設定すればCSVデータを取得できます。

```Swift
let path = Bundle.main.path(forResource: "ファイル名", ofType: "csv")!
do {
    // csvファイルからデータを取り出す
    let csv:CSV = try EnumeratedCSV(url: URL(fileURLWithPath: path))
    // 行を取得
    let rows = csv.rows
} catch {
    print("Error reading CSV file: \(error)")
}
```
今回、行ごとに格納されるように取得しましたが、連想配列のように取得したり、カラム名のみを取得したりなども可能です。
詳しくは、下記から参照してください。

https://github.com/swiftcsv/SwiftCSV

## おわりに
私の調べ方が悪かったためか、カラムが無い場合のcsvデータ取得の方法を見つけることができませんでした。もし、うまい解決方法があればコメントで教えていただけると嬉しいです！
また、今回SwiftCSVを使用してcsvファイルからデータを取得しましたが、他にもっと良い方法があれば合わせてコメントで教えていただけると幸いです！
nmcli ipv6 複数IPアドレス 設定時メモ

# 概要
設定するたびに設定方法何だっけってなってしまうので、自分用にメモ。

# 環境
| | |
|:-:|-|
| メモリ | 1GB |
| CPU | 2コア |
| SSD | 100GB |
| OS | RedHat系 |
| ネットワーク | 100Mbps共有 |
| グローバルIPアドレス | IPv4アドレス 1個、IPv6アドレス17個 |

[スペック・料金詳細のPDFはこちら｜料金｜VPSならConoHa](https://www.conoha.jp/vps/pdf/conoha_spec_ja.pdf)

# NMCLI

## Primary address 
```sh
sudo nmcli connection modify eth0 ipv6.method manual ipv6.addresses {ipv6_hostaddr01}
sudo nmcli connection modify eth0 ipv6.gateway {ipv6_gateaddr01}
sudo nmcli connection modify eth0 ipv6.dns 2001:4860:4860::6464
sudo nmcli connection modify eth0 +ipv6.dns 2001:4860:4860::64
```

下記の値はそれぞれ自分の環境に合わせる。
`{ipv6_hostaddr01}` --> `fe80::1`
`{ipv6_gateaddr01}` --> `fe80::fe`

DNSの項目にすでに書いちゃったけど、`+`が大事
ちなみに、DNSサーバのアドレスみたいにアドレス複数あるやつのうち、一つだけ消す時は`-`でいいみたい。

```sh
sudo nmcli connection modify eth0 +ipv6.dns 2001:4860:4860::64
sudo nmcli connection modify eth0 -ipv6.dns 2001:4860:4860::64
```

## Secondary address 
```bash
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr02}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr03}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr04}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr05}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr06}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr07}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr08}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr09}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr10}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr11}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr12}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr13}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr14}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr15}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr16}
sudo nmcli connection modify eth0 +ipv6.addresses {ipv6_hostaddr17}
```

## NIC の再起動で変更反映
downだけだと今設定している sshも落ちるので`;`でコマンドつなげて実施（`&&`じゃないのは `down`失敗しても`up`試行してくれるようにするため。`||`で条件色々やってったり，`if [ $? -eq 0 ] ; then ～ ; fi` するのも面倒）

```bash
sudo nmcli connection down eth0 ; sudo nmcli connection up eth0
```

# 参考

https://support.conoha.jp/v/setipv6/

https://qiita.com/liqsuq/items/1474702cb01c9cc9e781
chatGPTでやってみたいこと

# chatGPTでやってみたいことがあります。

それは、以前途中までやったオリジナルアプリのコードのバグ修正。

無料版なので、どこまで出来るかは分かりませんが、多少改善できれば良いと思っています。

# 最後に
オリジナルアプリ作成が止まっていることが我慢できないので、前進できれば。
docker-composeを使う上でホストとコンテナのユーザーIDとグループIDを揃える

## はじめに
　「docker…めっちゃ便利やん…！」となっている初心者です。dockerを使い始めて、「rootユーザーでコンテナは立ち上げないように」というのをちらほら見かけました。ユーザー変更せずに開発していたので改めないと…と調べてたどり着いたものをまとめます。使用しているdocker-composeでの方法です。初心者の備忘録ゆえ、間違いあればご指摘嬉しいです。


## Dockerfileとdocker-compose.ymlの書き方
　当たり前になりますが、「ユーザーとユーザーグループをローカルIDで追加して、そのユーザーを使用する」というものです。

```dockerfile:Dockerfile
ARG UID
ARG GID
ARG USERNAME
ARG GROUPNAME
RUN groupadd -g ${GID} ${GROUPNAME} -f && \
    useradd -m -s /bin/bash -u ${UID} -g ${GID} ${USERNAME}
USER ${USERNAME}
```


```yml:docker-compose.yml
version: "3"
services:
    web:
        restart: always
        build:
            context: .
            args:
                - UID
                - GID
                - USERNAME=user
                - GROUPNAME=user
        working_dir: "/workspace/"
        volumes:
            - .:/workspace
```

bashで以下のコマンド打ち、コンテナを立ち上げて完了です。

```sh
docker-compose build --build-arg UID="$(id -u)" --build-arg GID="$(id -g)" && docker-compose up -d
```

　`groupadd -g ${GID} ${GROUPNAME} -f`でグループを、`useradd　-m -s /bin/bash -u ${UID} -g ${GID} ${USERNAME}`でユーザーを作成します。`USER　＄｛USERNAME｝`で作ったユーザーを使用します。
　ARGコマンドで変数を宣言し、同じ名前の変数をdocker-composeのargsで定義します。これでdocker-composeのbuildコマンドで、指定したIDの値をDockerfileに流し込むことができます。

　コンテナを立ち上げる際は、buildコマンドのオプション`--build-arg`を使いargsに書いた変数に値を入れます。ローカルのユーザーおよびグループIDと一致させたいので、`${id -u}` `${id -g}`で引っ張ってきます。


## おわりに
　ローカルのIDを自動で入れるのにどうしたら良いんだと探し始めてから、`--build-arg`っていうオプションに辿り着くまで大分時間がかかりました…。あと、bashで長々としたコマンドを打たないといけないの面倒ですよね。素直に`docker-compose up --build -d`だけで出来るよう模索したけれどわかりませんでした…。


## 参考記事
[dockerでvolumeをマウントしたときのファイルのowner問題 - Qiita](https://qiita.com/yohm/items/047b2e68d008ebb0f001)
[Dockerコンテナに一般ユーザーを追加するときのDockerfileの設定 - Qiita](https://qiita.com/Spritaro/items/602118d946a4383bd2bb)
[ローカルとdockerコンテナ側のUID,GIDを揃える - やる気がストロングZERO](https://yaruki-strong-zero.hatenablog.jp/entry/docker_container_uid_gid)
Ubuntu 22.10 から 23.04 へのアップグレードの仕方

# 1. まず現在の Ubuntu 22.10 を最新状態にします。
```
$ sudo apt update 
$ sudo apt full-upgrade
```

# 2. 次に不要物を全消しします
```
$ sudo apt autoremove
```

# 3. 更新の設定をします。
`/etc/update-manager/release-upgrades` を開いて、`Prompt`を`normal`に設定します。

```
# Default behavior for the release upgrader.

[DEFAULT]
# Default prompting behavior, valid options:
#
#  never  - Never check for a new release.
#  normal - Check to see if a new release is available.  If more than one new
#           release is found, the release upgrader will attempt to upgrade to
#           the release that immediately succeeds the currently-running
#           release.
#  lts    - Check to see if a new LTS release is available.  The upgrader
#           will attempt to upgrade to the first LTS release available after
#           the currently-running one.  Note that this option should not be
#           used if the currently-running release is not itself an LTS
#           release, since in that case the upgrader won't be able to
#           determine if a newer release is available.
Prompt=normal
```

# 4. 最後に 23.04 へのアップグレードを実行します。
```
$ sudo do-release-upgrade
```
いつも通り数時間、時間がかかりますので、余裕をもって作業してください。

アップグレード後、23.04になっていることを確認します。
```
$ cat /etc/issue
Ubuntu 23.04 \n \l
```

お疲れさまでした。
【Swift】Array(repeating:count:)の使い方

# はじめに

`Array(repeating:count:)`は、同じ値を指定した回数分繰り返して配列を生成する機能です。この機能を使用することで、簡単に初期値が設定された配列を生成することができます。

# 使用方法

以下のように、 `repeating`に値を指定し、`count`に回数を指定することで初期値付きの配列が生成されます。

```swift
// [0, 0, 0, 0, 0]
let array = Array(repeating: 0, count: 5)
```

上記のコードは、 `0` を `5` 回繰り返した配列を生成し、`array`に代入しています。

# 型を明示する場合

型を明示する場合は、このように書きます。

```swift
// ["default", "default", "default"]
let stringArray = [String](repeating: "default", count: 3)
```

上記のコードは、 `String`型の `"default"` を `3` 回繰り返した配列を生成し、`stringArray`に代入しています。

# まとめ

`Array(repeating:count:)`を使用することで、同じ値を指定した回数分繰り返した配列を簡単に生成することができます。

---

ご覧いただきありがとうございました。

🐦 [Twitter: @shota_appdev](https://twitter.com/shota_appdev)

📱 [個人アプリ: Symbols Explorer](https://apps.apple.com/jp/app/symbols-explorer/id1612933742)
Railsでの定期実行

会員サイトなどで期限つきの有料プランがあるサービスは最近たくさんあります。
イメージで言うとAmazon PrimeとかNetfixなどですね。

こういう類のサイトを利用していると、
「あと〜日で期限が切れます。」
「あと〜日でポイントが無効になります。」
などのメッセージが届きますよね。

これをrailsでも実装したい場合はどうしたら良いのかというお話。（実際にコードは書いていません。方向性を示しています。）

そのためには、代表的なgemでwheneverというものを使ってみたいと思います。

```
gem 'whenever', require: false
```

このgemをbundleインストールしたら以下を実行しましょう。
```
$ bundle exec wheneverize .
```

すると、config/schedule.rbが作成されます。

そして、このファイルに定期実行したい処理や期間を記述していけばOKです。

例えば、以下のように書くことで１日おきにrakeタスクを実行できます。
これはauto_renewタスクを実行しています。

```config/schedule.rb
# day以外にも 1.minute, :hour, :day, :month, :year, :reboot :weekend, :weekdayなどがある。
every 1.day do
  rake 'auto_renew'
end
```

もし、ディレクトリ配下にある場合は、以下のようになります。
```config/schedule.rb
# day以外にも 1.minute, :hour, :day, :month, :year, :reboot :weekend, :weekdayなどがある。
every 1.day do
  rake 'directory:auto_renew'
end
```


rakeタスクを作成するためには、以下のコマンドでauto_renewというタスクを作成します。
```
$ rails g task auto_renew
```
すると、rakeファイルが　
./lib/task/配下に作成されます。


そして、以下のように記述していきます。
もしtasksディレクトリ直下にある場合は、namespaceは不要です。（今後、たくさんタスクをこのファイルに作成していくのであれば、管理しやすいようにnamespaceをつけても良いです。）
```lib/tasks/test.rake
  # descはタスクの説明を書けば良いです。
  desc 'autorenewを作成してみました。'
  # taskの実行時の名前をつけます。:environmentと記述すると実際の環境で実行できます。
  task auto_renew: :environment do
    #実行したいコマンドをここに入力
  end
```

ディレクトリ直下ではなく、
tasks/directory/test.rake
のようになっている場合は、namespaceが必要で以下のようになります。

```lib/tasks/directory/test.rake
namespace :directory do
  desc 'autorenewを作成してみました。'
  task auto_renew: :environment do
    #実行したいコマンドをここに入力
  end
end
```

最後に以下のコマンドを実行すれば、このファイルの設定を読み込みます。

```
#ターミナル
$ bundle exec whenever --update-crontab
```

実行の取り消しは以下の通り。
```
#ターミナル
$ bundle exec whenever --clear-crontab
```


以上になります。
cronを使っても良いですが、wheneverを使うと簡単に実装できますね。
あとはどんなタスクを実行したいか、どのように記述するかを考えていくことが中心になるかと思います。

有効期限などに応じて、メールやメッセージを送るにはどうすれば良いのか、検討したいと思います。

# 補足説明
taskファイルを作成して、descという記述がありましたが、
以下のコマンドを実行すると現在のタスク一覧を表示できるのですが、
```
bundle exec rake -T   
```
その際に以下のように説明がタスク名と一緒に表示されます。
ですので、後から他の人が見てわかりやすいような説明を入れておくと良いです。
```
rake autorenew   # autorenewを作成してみました。

#ちなみにディレクトリ配下の場合は以下のようになります。
rake directory:autorenew
```

タスクは以下のコマンドで実行できるので、作成してうまくできているか試してみましょう。
もしタスク名に何を入れればよいか分からない場合は、先ほどのタスク一覧で確認できます。
```
$ bundle exec rake タスク名
```
【Rails】 deviseの「resource」とは

## はじめに
deviseを使っていて、デフォルトで登場する「resource」の意味が分からなかったのですが、調べてみて多少理解が進んだので記述していきます。
devise内部まで理解しているわけではないので、表面的な解釈になります。
間違いがありましたらご指摘ください！
## 環境
ruby 3.2.1
rails 6.1.7.3
devise 4.9.2

## resourceとは
```erb
<%= form_for(resource, as: resource_name, url: registration_path(resource_name) do |f| %>
```
+ modelのインスタンス。「user」とすることが多いが、モデル名がuser以外の場合でも対応できるように抽象化している。
+ `as:`によって`resource_name`が`resource`を参照できるようにしている。

そのため、以下の二つは同じURIを意味する。
```erb
registration_path(resource_name)

user_registration_path
```
+ どちらの書き方でも動作する。
+ 汎用性が高いのは一つ目のURI。
+ 具体的でURIが何を示しているのかが分かり易いのは二つ目のURI。

## 参考
https://teratail.com/questions/139633
python備忘録1（型変換の注意）

# キャストについて
pythonを昨日学び始めた学生です
わからないことが多く、自分は忘れやすいので備忘録をつけることにします。

### 今回のコードの内容
c_1,c_2が与えられ、それはアルファベット大文字一文字あるいは数値である
両方とも数値であった場合和演算し、それ以外ならそのまま結合する

```python:最初書いた間違ったコード
c_1 = input()
c_2 = input()
if c_1.isdigit() and c_2.isdigit():
    int(c_1)
    int(c_2)
    sum = (c_1 + c_2)
    print(sum)
else:
    print(c_1 + c_2)
```

キャスト（型変換は）宣言した変数を変えるのではなく
その答えを返す？だけなのでそれ以降のコードに影響がない

具体的には

```text:入力値
1
9
```
```python:コード
int(c_1)#str->int
int(c_2)#str->int
#この時点で型変換をした答えを返したが受け取れていないので以降に影響がない
sum = (c_1 + c_2)
print(type(c_1))
print(type(c_2))
print(sum)
```
```text:結果
<class 'str'>
<class 'str'>
19
```

となり、先頭でいくらキャスト（型変換）してもそのあとのコードには影響されていないことがわかる。

```python:修正したコード
c_1 = input()
c_2 = input()
if c_1.isdigit() and c_2.isdigit():
    print(int(c_1) + int(c_2))
else:
    print(c_1 + c_2)
```

出力するprint関数内でint()を記述した
（sumいらなかった）

### python所感
勝手に色々やってくれる
演算なしで出力する場合int,char,floutとか意識しないでそのままinput,printできたとき感動した。

### さいごに
解釈が間違っていたり、こうしたほうがいい、
などご意見あったらお願いします
No15_ググったこと投稿(5分)_DBの違い

みなさん、DBと聞くと何が思いつきますか？
- MySQL
- PostgreSQL
- SQLite

僕がパッと思いつくのはこれくらいです・・
普段何気なく使ってると思うのですが（自分だけ）、違いって気にしたことありますか？

最近Udemyで勉強していたら、「SQLite/PostgreSQLでテーブル定義〜」と、
そんなに使い分け必要なん？ MySQLでいいんじゃないの？って思ったり思わなかったり。

なのでそれをざっくり調べたのでまとめようかと

## PostgreSQL/MySQL/SQLite 違い
- PostgreSQL
    - 市場シェア
        - 4位（古いかも）
    - メリット
        - 標準SQLに沿った実装なので、独自の書き方が少ない
        - 大量のデータを捌くには処理が早い
        - 多機能（有償DBがもつ機能を搭載）
            - トランザクション
            - サブクエリ
            - トリガ
            - 関数
        - GISデータ（地理情報システム）を格納可能
        - テーブル結合のアルゴリズムの数がMySQLより多く、結合によって最適アルゴリズムを切り替える
        - 堅牢性が高い
            - MySQLには暗黙的に実施される型変換や、文字列比較の厳格さがゆるい
                - 例）
                - 日付型の「2019-09-01」から数字の「1」を引くと、「20190900」という整数が返える

- MySQL
    - 市場シェア
        - 2位
    - マルチスレッド対応
        - 一気に複数のプロセスを流せる？
    - PosgreSQLと似てる
    - 大量のデータでも、SELECTで数十件単位だとMySQLが早い
    - UPDATEは直接上書きし早い（PosgreSQLだとINSERTに近い動きをする）
    - 
- SQLite
    - ソフトウェアに内蔵される組み込み形式
        - MySQLやPostgreSQLはサーバー処理を行い、クライアントと接続処理が必要
    - コンパクト
        - 本体サイズが600kb且つ、消費メモリも少ない
    - 処理が高速
        - 参考記事）
            - https://cypher256.hatenablog.com/entry/20121013/p1
Azure DevOpsのPermission周りで困ったことメモ

# はじめに

AzureDevOpsのPermission周りの設定、世界でいちばん難しい。
循環参照ありの階層構造になってて、テキトーにやってると人間の管理できる範囲を簡単に凌駕してくる。

今後のためにも、困ったこととその対応をメモします。

※随時追加予定です。

# Teamを作った時は

[Project Settings]-[Permissions]-[Group]tabに、Team名のgroupがあるはず。
それに全員追加しておく。

チームメンバー一律で設定できるので、これをやっておくと楽です。
Teamの中で権限を分けたい（例えば、会社Aの人と会社Bで権限を分けたり、新人さんだけは別にしたり）場合は、Groupをそれぞれ作り、TeamのPermission Group配下にメンバーとして登録すれば良いかと。

# Repositoryが見えないんだけど

[Project Settings]-[Repositories]-[Security]tab
該当するユーザもしくはGroupに、`Read`のPermissionをつける。

`Contribute`や`Create branch`できないと開発がままならないので、一緒につけてあげよう。

参考

https://blog.beachside.dev/entry/2022/02/22/190000

# Boardsのチケットが何も見えないんだけど

[Project Settings]-[Project configuration]-[Areas]tab

権限をつけたいAreaのSecurity設定に進み、`View work items in this node`をつけます。
`Edit work item comments in this node`や`Edit work items in this node`は最低限ないと、、、という感じですね。

参考

https://learn.microsoft.com/ja-jp/azure/devops/organizations/security/set-permissions-access-work-tracking?view=azure-devops#create-child-nodes-modify-work-items-under-an-area-or-iteration-path
JavaScript new Date(), date-fns, date-fns-tz周りの日付を跨ぐタイムゾーンの扱い

以下の環境でJavaScriptを実行し、日付を跨ぐタイムゾーン周りがどのように出力されるかまとめる
- Chrome: 112.0
- date-fns: 2.29.3
- date-fns-tz: 2.0.0


### ChromeのタイムゾーンはAsia/Tokyo(+9)
```javascript:javascript
import { parse, format } from "date-fns";
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";

console.log(new Date());
// Tue Apr 18 2023 19:15:38 GMT+0900 (日本標準時)
console.log(utcToZonedTime(new Date(), "Asia/Tokyo"));
// Tue Apr 18 2023 19:15:46 GMT+0900 (日本標準時)
console.log(utcToZonedTime("2023-04-18", "Asia/Tokyo"));
// Tue Apr 18 2023 00:00:00 GMT+0900 (日本標準時)
console.log(zonedTimeToUtc("2023-04-18", "Asia/Tokyo"));
// Tue Apr 18 2023 00:00:00 GMT+0900 (日本標準時)
console.log(parse("2023-04-18", "yyyy-MM-dd", new Date()));
// Tue Apr 18 2023 00:00:00 GMT+0900 (日本標準時)
console.log(format(new Date(), "yyyy-MM-dd"));
// 2023-04-18 
```

### ChromeのタイムゾーンはPacific/Kiritimati(+14)でAsia/Tokyoから翌日になるケース
```javascript:javascript
import { parse, format } from "date-fns";
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";

console.log(new Date());
// Wed Apr 19 2023 00:18:42 GMT+1400 (GMT+14:00)
console.log(utcToZonedTime(new Date(), "Asia/Tokyo"));
// Tue Apr 18 2023 19:18:49 GMT+1400 (GMT+14:00)
console.log(utcToZonedTime("2023-04-18", "Asia/Tokyo"));
// Mon Apr 17 2023 19:00:00 GMT+1400 (GMT+14:00)
console.log(zonedTimeToUtc("2023-04-18", "Pacific/Kiritimati"));
// Tue Apr 18 2023 00:00:00 GMT+1400 (GMT+14:00)
console.log(parse("2023-04-18", "yyyy-MM-dd", new Date()));
// Tue Apr 18 2023 00:00:00 GMT+1400 (GMT+14:00)
console.log(format(new Date(), "yyyy-MM-dd"));
// 2023-04-19 
```

### ChromeのタイムゾーンはPacific/Pago_Pago(-11)でAsia/Tokyoから前日になるケース
```javascript:javascript
import { parse, format } from "date-fns";
import { utcToZonedTime, zonedTimeToUtc } from "date-fns-tz";

console.log(new Date());
// Mon Apr 17 2023 23:27:14 GMT-1100 (サモア標準時)
console.log(utcToZonedTime(new Date(), "Asia/Tokyo"));
// Mon Apr 17 2023 23:27:48 GMT-1100 (サモア標準時)
console.log(utcToZonedTime("2023-04-18", "Asia/Tokyo"));
// Mon Apr 17 2023 04:00:00 GMT-1100 (サモア標準時)
console.log(zonedTimeToUtc("2023-04-18", "Pacific/Pago_Pago"));
// Tue Apr 18 2023 00:00:00 GMT-1100 (サモア標準時)
console.log(parse("2023-04-18", "yyyy-MM-dd", new Date()));
// Mon Apr 17 2023 04:00:00 GMT-1100 (サモア標準時)
console.log(format(new Date(), "yyyy-MM-dd"));
// 2023-04-18
```
ParrotOS 5.2 でハッキングラボをつくってみる 1 導入編

# 記事の目的
- IPUSIRON著の『ハッキングラボのつくりかた』の勉強のため
- 以前、同書の内容がKaliLinux2022.1でも通用するか検証した。今回からは、同じペネトレーション用のOSであるParrotOSでも通用するかどうかの検証したい
- 他に同書を利用して、ハッキングラボの構築のための勉強をしている人に参考となる情報を提供するため

## 当方の環境の説明
同書に従い、ハッキングラボはOracleのVirtualBoxを利用した仮想マシン上に構築する。
物理マシンのホストOSと仮想マシンのゲストOSの環境は、次の通り。
- ホストOSの環境
FerenOS 2022.03 64bit版(Ubuntu20.04 focalと同等)
メモリ: DDR4-2133 16GB
CPU: Intel core i5-6500 @3.20Ghz

- ゲストOSの環境
ParrotOS5.2 Security版(64bit版)

- VirtualBox
6.1.42 r155177

環境設定は、[公式サイト](https://www.parrotsec.org)からISOをダウンロードして、仮想マシンにインストールした。
仮想マシンに設定については、公式サイトの情報を参考にした。

今回は、VirtualBoxのインストールは省略する。理由は、ホストOSごとにインストール方法が違うため。
ちなみに、どの環境でもVirtualBox Extension Packのインストールは推奨です。
[ダウンロードページ](https://www.virtualbox.org/wiki/Downloads)

## ParrotOSのインストール
[公式サイト](https://www.parrotsec.org)からISOをダウンロード
ダウンロード後に、VirtualBoxを起動する。
Parrot用の新規仮想マシンを作成する。
仮想マシンの作成マニュアルが、公式サイトにあるので、それを参考にして仮想マシンを作成した。

:::note warn
私の環境だと、OSのインストールの際のパーティション構成の設定で、スワップをスワップファイルとして設定すると、インストールに失敗した。
スワップをスワップパーティションに分けてみると、インストールが成功した。
:::

:::note
以前と同様、ウィンドウタイトルやボタンの値などはかぎかっこ付きで示す。
:::

今回は、ここで終わり。
管理者権限の付与（VB.NET）

# この記事の注意事項
この記事の内容は[こちらの記事](https://qiita.com/portfoliokns3/items/9000ab0b7e3111b24941)の開発の続きです。

# この記事で実施していること
- ユーザーごとに管理者権限を付与する機能
- 管理者権限に応じて、機能を制御する機能

# 追加機能の仕様
1. ユーザー情報テーブルに、管理者権限のカラムを追加
1. 管理者権限に応じて、管理者用の機能を制御する処理を追加
1. アカウント追加時に、管理者権限を選択できるように機能を追加
1. アカウント追加時に、管理者権限がDB側に登録されるようにSQLを修正

## 1. 管理者権限のカラムを追加
SSMSでカラムを追加し、初期データを入力します。データの数にもよりますが、クエリを実行すれば、効率よく、登録できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/b5f14191-c018-84bd-bd71-23086c31859a.png)
**サンプルコード**
```SQL
Update UserInfo Set admin_flag = 'False';
```

## 2. 管理者専用の機能を制御
ユーザーに管理者権限が付与されているかを確認するため、以下のSQLを実装し、実行します。

**サンプルコード**
```SQL
SELECT CASE WHEN EXISTS
     (
       SELECT 1 
       FROM USERINFO  
       WHERE user_id = @userID 
       AND admin_flag = 'True' 
     )
THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT) END AS isAdmin
```

SQLの実行結果に応じて、管理者用の機能の使用を制御しています。
**管理者権限がある場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/8f25ad8b-608a-eb3b-023e-eff7c3687162.png)
**管理者権限がない場合**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/7341153f-b886-a8ca-cd1d-79c7ba80202a.png)


## 3. アカウント追加画面に、管理者権限が選択できるようにデザインを修正
単純に、管理者権限を付与できるよう、デザインを修正しただけになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/88714ae8-08b4-5e52-e866-b1a40c182fd3.png)

## 4. アカウント追加時のSQLを修正
アカウント追加時に、管理者権限をふよするために、既存のSQLを修正します。
```SQL
INSERT INTO UserInfo (id, user_id, password,revoke_count, revoke_flag, admin_flag) 
VALUES (@id, @userID, @password, 0, 'False', @admin_flag); 
```

# 注意事項
- この記事では、SQL Server、SSMS、visual studioを使用しているので、試してみたい方は事前に準備が必要です。
- 本記事に掲載されているコードは掲載用にサンプルとして掲載しているものです。したがって本記事を参考にし、コーディングを進める場合は作成しているアプリに応じて、各自で判断して、適応してください。
- 関連する記事の一覧は[こちら](https://qiita.com/portfoliokns3/items/7c789b7e1ba40500abbb#%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E6%89%B1%E3%81%A3%E3%81%A6%E3%81%84%E3%81%8D%E3%81%9F%E3%81%84%E4%BA%BA%E5%90%91%E3%81%91%E3%81%AE%E8%A8%98%E4%BA%8B)。
※参照先のリンクが切れている場合は、[トップページ](https://qiita.com/portfoliokns3)から確認してください。

# この記事は誰向けの記事か？
- VB.NETやSQL Serverに触れたことがない人
- リボークの実装について、一通りの流れを確認したい人

# 環境
- OS：Windows10
- [SQL Server](https://www.microsoft.com/ja-jp/sql-server/sql-server-downloads)
- [SQL Server Management Studio（SSMS）](https://learn.microsoft.com/ja-jp/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-ver16):v19.0.2
- [visual studio 2022](https://visualstudio.microsoft.com/ja/vs/)
- [ChatGPT](https://chat.openai.com/chat)

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。
- この記事の内容では、一部、ChatGPTを利用しております。
Junit5　＠MethodSourceについて

このメソッドソースアノテーションはパラメータライズトテストで使用されるメソッドソースを定義するために使用される

よって、引数に渡されるデータを生成するためのメソッドを指定することができる

このメソッドの注意点が３つ

・静的であること
・そのメソッドがテストクラス内に存在すること
・戻り値の型が、ストリーム、イテレーター、イテラブル、配列のいずれかである
この型に関しては、JUnitがStreamに変換するので確実に変換できる型である必要があるため

このメソッドソースで生成されるデータがテストメソッドの引数に渡され、それぞれの引数の組み合わせでテストメソッドが複数回実行される

これにより異なるデータを使用して同じテストメソッドを繰り返し実行することができる
Overleafで好きなフォントを使う方法

環境：Google Chrome

1. 拡張機能「Stylebot」をインストール
1. Overleafのあるプロジェクトを開き、Stylebotをクリック
1. 「Stylebotを開く」
1. 「コード」でcssファイルが開かれるので設定する

例：
```
body {
  font-family: "HackGen35", "Ubuntu Mono", monospace;
}

/* main text */
div.cm-line {
  font-size: 12.5px;
}

/* sidebar */
button.item-name-button {
  font-size: small;
}
button.outline-item-link {
  font-size: small;
}
```

こんな感じでHackGenやUbuntu Monoが使えたり、フォントのサイズを変更できる。
Animation Eventの表示の違い

# Animation Event
簡単にAnimation Eventの説明をすると、Animation ClipにEventというものを仕込むことで、Animationから関数を呼び出すことが出来る機能です。ネットを調べると、会話イベントの制御なんかをやってるかたもいらっしゃいます。

# はじめに
では、以下の２つの画像を見て下さい。

![スクリーンショット 2023-04-19 114030.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67270/5f6efa2f-252a-3751-384f-2a31b535bfc6.png)
![スクリーンショット 2023-04-19 114201.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67270/378c820b-152c-a9c6-7d3d-26b51437798a.png)

上はFunctionなどの項目がテキストエリアですが、下はプルダウン表示になっています。
今回はこの２つの違いについて短くお話します。

# 簡潔に
簡単に申し上げると、違いはAnimation Clip(を持つAnimator)をアタッチしているオブジェクトを通してアクセスしたか否かです。
大雑把に書くと以下の通り。

## 上の画像
1. ProjectタブのAssetsの中からAnimation Clipを選択
2. AnimationタブからEventを選択

## 下の画像
1. HierarchyのAnimatorからAnimation Controllerを選択
1. Animatorタブから対象Animation Clipの登録されたノードを選択
1. InspectorのMotionの項目からAnimation Clipを選択し、Animationタブを開く
1. AnimationタブからEventを選択

# おわり
挙げた例以外にもプルダウン表示する方法はありますが、今回は割愛します。
大事なのは、Animation Clipを使用しているオブジェクトを選択しているか否かです。

# 今回使用したコード (追記)
書く必要もないとは思いますが、一応
``` cs
using UnityEngine;

public class Dummy : MonoBehaviour
{
	void Call(Test test) => Debug.Log(test);
}

public enum Test
{
	A,
	B,
}
```
AtCoderを始めてみる


# 経歴・Atcorderを始めようと思ったきっかけ
自分は最近就活が落ち着いたM2の学生です。就活は、大手SIerに内定いただいて、内定承諾したってところです。

就活も終わって研究を頑張って行きたい気持ちと同時に、「なんかコード書く力つけたいな」というフワッとしたモチベも出てきました。そこで、大学1年の時にちょっとかじって終わってたAtcoderをもう一度やってみようかなと思った次第です。

# 目標
とりあえず茶色に到達したいが、まずは何回か続けてみるところから。
緑色までは確実に行きたくて、入水出来たら最高。

# 設定
### 開始時期
2023/04/19〜

### 言語
Python3

普段の研究もPythonでコード書いているのと、授業とかで一番使ってて馴染み深いのでとりあえずPythonで。
壁にぶち当たったらC++とかも勉強するかも。

## 当分やりたいこと
とりあえず
[レッドコーダーが教える、競プロ・AtCoder上達のガイドライン【初級編：競プロを始めよう】](https://qiita.com/e869120/items/f1c6f98364d1443148b3)
[【AtCoder】中卒の主婦が青コーダーになったおはなし【競技プログラミング】](https://qiita.com/mayocorn/items/4edff486428240864808)
などの記事を参考にAtcoderの楽しさを味わって行く。
必死に勉強！っていうよりコード書いて遊ぶみたいな気持ちを大事にする。

あと通学時間でBBC Learning Englishとかもやりたい。

# 最後に
自分は割と飽きっぽいので、モチベーション維持のためにもこういう記事を書き残したい。
バックエンドエンジニアへの精進 #1

　これが初投稿になります。自分が学んだことをまとめておこうと思ったときに、Notionなどのノートテイキング用appでも良かったのですが、歪であっても何かしらの形に残る方がいいかなと思ってQiitaを選択しました。基本的には自分の復習用ですが、たまたまこれを見かけた方の糧にもなるようなまとめにしていきたいと考えています。

　このシリーズは「バックエンドエンジニアへの精進」と銘打ちまして、バックエンド知識をほとんどもっていない私が成長していく過程をお楽しみいただければと思います。

## そもそもなぜバックエンドなのか
　話は数日前に遡りまして、高校の同級生（以下、A君）と久しぶりに会うことになりました。私は１年浪人しておりまして、A君は現役合格。私は就活を始めたばかりで、彼は終活しているという状況です。そんなA君に就活のアドバイスをもらおうと話を聞くと、彼はバックエンドエンジニア（ソフトウェアエンジニア）として内定を勝ち取ったそうなんです。・・・・・そうです、触発されたんです。A君は、私に「悔しい」「負けていられない」という感情をストレートに抱かせてくれる数少ない人物でして、前からバックエンドの知識欲しいなぐらいには思っていたのですが、今回の件で火が点きました。というのが、バックエンドを学ぼうと思ったきっかけです。

## 自己紹介
　では、私はどういう人間なのかということで、研究分野やスキルについてまとめたいと思います。
### 研究分野
認知神経科学（ヒトの意思決定について、機械学習モデルを構築してヒトの行動との整合性を調べます）
### スキル
Python
\- numpy
\- scipy
\- pandas
\- polars（pandasから移行中）
\- matplotlib
\- seaborn
\- tensorflow（勉強中）
\- pytorch（勉強中）
\- PsychoPy（神経科学の行動実験用アプリケーション）

C（授業で触ったくらい）
VBA

## まとめ
今回は初回ということでここまでです。次回からは、A君に教えてもらった「テクパロ」さんのサイトを参考に学習を進めたいと思います。以下にリンクを貼ります。
https://tech-parrot.com/engineer/backend-engineer-roadmap-and-skills/#i-2

ここまで読んでくださりありがとうございました。
ご意見・ご感想もいただけますと幸いです。
では、また次回会いましょう！
gitチートシート

Gitは、分散型のバージョン管理システムで、プロジェクトのソースコードの履歴を追跡し、変更を管理するのに役立ちます。以下に、よく使うコマンドについての基本的な説明を示します。

* `git init`

このコマンドを使用して、新しいGitリポジトリを初期化します。現在のディレクトリに.gitフォルダが作成され、リポジトリのメタデータが格納されます。

* `git remote add origin git@bitbucket.org:user/repo-name.git`

リモートリポジトリを設定します。この例では、originという名前でBitbucket上のリモートリポジトリのURLを指定しています。

* `git add . -A`

リポジトリ内のすべての変更されたファイルを、次のコミットで追跡するようにステージングエリアに追加します。

* `git commit -m "initial commit"`

ステージングエリアに追加された変更を、リポジトリにコミットします。このコマンドに続くメッセージは、コミットに関する説明です。

* `git push -u origin main`

ローカルリポジトリの変更をリモートリポジトリ（origin）のmainブランチにプッシュします。-uオプションは、今後のプッシュやプルでデフォルトのリモートブランチとしてmainを設定します。

* `git status`

リポジトリの現在の状態を表示します。変更されたファイル、ステージングされていない変更、ブランチ情報などが表示されます。

* `git pull`

リモートリポジトリから最新の変更を取得し、ローカルリポジトリにマージします。

* `git checkout -b "new-branch"`

新しいブランチ（この例ではnew-branch）を作成し、そのブランチに切り替えます。

* `git log`

リポジトリのコミット履歴を表示します。各コミットのハッシュ、作者、日付、コミットメッセージが表示されます。

* `git diff`

ワーキングディレクトリとステージングエリアの差分を表示します。これにより、変更されたファイルや追加・削除された行がわかります。

* `git checkout main`

ブランチを切り替えます。この例では、mainブランチに切り替えています。
【Python】selenium-webdriverをヘッドレスモードで起動させる（Edge）

# 目的
スクレイピングツールで、画面表示しながら動いていたものをヘッドレスモードに変更しようとした時に、少しハマったので備忘として記録。

# エラー内容
`driver.get('https://xxxxx.jp/') `したときに以下エラーが発生。
```
unknown error: net::ERR_CONNECTION_TIMED_OUT
```

```python:sample.py（実行したときのコード）
        from msedge.selenium_tools import Edge, EdgeOptions

        # Edgeのオプション
        options = EdgeOptions()
        options.use_chromium = True
        options.add_argument('--headless')
        
        # webdriver起動
        edgepath = "C:\xxxxx\msedgedriver.exe"
        driver = Edge(edgepath, options = options)

        # 情報取得
        driver.get('https://xxxxx.jp/') ←★ここでエラー！！
```


# 原因
ツール実行環境がプロキシサーバ経由で、インターネットにアクセスしている。
画面表示して実行する場合だとWindowsの設定を参照してスクレイピング対象のWebサイトにアクセスできていたが、ヘッドレスモードで起動するとプロキシ設定が参照されない模様。
以下のようにオプションにプロキシサーバの設定を追加することでエラーが解消された。

# 対応
EdgeOptionsにプロキシサーバの情報を設定
```python:sample.py（対応後のコード）
        from msedge.selenium_tools import Edge, EdgeOptions

        # Edgeのオプション
        options = EdgeOptions()
        options.use_chromium = True
        options.add_argument('--headless')
        
        # プロキシサーバの設定を追加
        proxy_address = "xxx.xx.xx.xx:8080"
        options.add_argument('--proxy-server={}'.format(proxy_address))
        
        # webdriver起動
        edgepath = "C:\xxxxx\msedgedriver.exe"
        driver = Edge(edgepath, options = options)

        # 情報取得
        driver.get('https://xxxxx.jp/')
```

# 最後に
AWSを使ったサーバーレスアプリの開発方法を紹介しています。
こちらもぜひご覧ください。

https://z-a-k-i.com/2024/03/28/aws-lambda-dynamodb-serverless-update/

https://z-a-k-i.com/2023/09/03/python-exe/

https://z-a-k-i.com/
スマホ実機を使った手動テストを効率化する方法

E2Eテストにおいても自動化が進んでいますが、様々な要因で完全に自動化までされているわけではないのが現状です。
そんな中でも特にスマホを利用したテストの場合、PCに比べると小さな画面でかつアプリの同時起動が限られている状況では時間がかかりやすいのは明白です。
世の中にあるアプリなど利用すればもっと楽にできることはあるかもしれませんが、ここでは最小限スマホの標準機能を利用することで広いOSで準備の手間も小さくできる方法をいくつか紹介します。

**簡単に結論から言うと、「QRコード」を利用するということになります。**

では比較的利用する順番で使用するものを紹介します。
## Wi-Fi設定
:::note info
iOSでは初期設定時にWi-Fi設定をスキップすることができず、その段階ではQRコード読み取りによるログインもできない模様です。
（androidは初期設定内のWi-Fi設定スキップ可、初期設定時QRコード読み取りからのログインも可能です）
:::
多分これが一番認知度低くて、かつ毎回面倒だと感じるものかと思います。
特に頻繁にスマホを初期化するような状況の場合、専用のQRを読むだけでSSIDの選択、パスワードの入力が不要です。
SSIDもあまり知られたくないということでステルスにしている場合にも有効なのは特に重宝するはずです。
※対応OSがandroidは10以上、iOSは11以上となっているようです。
（あくまで標準カメラアプリを使用した場合の想定で、特にandroidの場合は端末によって状況が変わる可能性があります）
### 自身で文字列を作成する
```
WIFI:S:<SSID>;T:<WPA|WEP|nopass>;P:<password>;;
```
`<SSID>`アクセス先のSSID
`<WPA|WEP|nopass>`設定されている暗号化認証方法いずれか指定（WPAには2や3もありますがWPAでOKです）
`<password>`設定されているパスワード

例：SSIDがAAA、パスワードがBBB、認証方法がWPA2の場合
```
WIFI:S:AAA;T:WPA;P:BBB;;
```

### webサービスを利用する
こちらのほうが楽に作成できると思います。
``QRコード作成 wi-fi``などで検索すると上位にいくつか候補が出てくると思いますので、好みや利用したいオプションなど確認して利用してみてください。

こちら頻繁にSSIDなどが変更になるパターンは少ないかと思いますので、1度作成したら保存しておくことで毎回作成する手間は不要になると思います。

## URL
テスト対象がwebサービスの場合はこちら一般的にもよく知られているので説明はほぼ不要かと思いますが念の為。
### BASIC認証
テスト対象はサービスインしていない場合が多く、BASIC認証で制限かけられている場合も多いかと思います。
こちらは後に説明する文字列コピーで対処できる部分もありますが、URL内にBASIC認証のIDとパスワードを入れ込むことで更に効率化できます。
アクセスするURLのドメイン部分に以下のようにid、パスワード情報を入力すればアクセスする度に入力求められずアクセスできます。
```
https://<id>:<password>@abc.com/
```
BASIC認証のidがaaa、パスワードがbbbの場合のURLは以下
```
https://aaa:bbb@abc.com/
```

## 各種入力文字列
こちらも意外と知られていないような感じがしていますが、こちらもQRコードで解決できます。
特定の文字列（IDやパスワード、ちょっと長めの指定されたものなど）も毎回手打ちは時間がかかることと、キー入力エリアが狭いためにタイプミスしやすいという問題があります。

目的のQRコード作成は一般にあるwebサービスを利用するところは他と変わりありません。
ここで1点気をつけたいのが、**テキスト情報のQRコードは多くのスマホ標準読み取りで認識できなかったり、表示までできるものの、コピーできなかったりという状況で目的が果たせないものが多い**状況です。
そこで利用するのがQRコード読み取りできるwebサービスです。
こちらも検索すればいくつかサービスが出てきます。
ブラウザからカメラを制御してQRを読み取り、結果をブラウザ上に表示してくれるので、あとは必要なところをコピペして利用するという流れです。
ちなみに私がよく利用しているのはこちらです。
https://qrcode.onl.jp/
ターミナルの一行目を変えてみた

ターミナルがデフォルトだとみにくいので、以下のように変更しました。
カーレントディレクトリと現在のgitブランチ名が表示され、
改行したところからコマンドを入力できます。

:::note
bashではないので注意してください。bashの場合は書き方が異なります。
:::

``` 
 ~/Desktop/current_directory (test)
% ここから入力が始まる
```

# 方法
以下コマンドで、vimで.zshrcのファイルを開く
```
$ vim ~/.zshrc
```
表示されたら、"i"を入力したらインサートモードで編集できるようになります。

そこで一番下に以下を入力。
```
autoload -Uz vcs_info
precmd() { vcs_info }
zstyle ':vcs_info:git:*' formats '(%b)'
setopt prompt_subst
PS1='%F{yellow} %~%f ${vcs_info_msg_0_}
%#'
```

終わったら、"esc"を押して、":wq"としてエンターを押す。

このあと、ターミナルで以下を実行すると変更が反映されます。
もし、何かしらエラーが出た場合は上の記述が間違っている可能性があります。
```
source ~/.zshrc
```

vimの細かい操作については、以下の記事を参考にしてください。

https://qiita.com/et_good_eng/items/96603b753eb438a7c5c3
ブックマークレットで外部スクリプトを実行するためのワンライナー

# 結論

```js
javascript:document.body.appendChild(Object.assign(document.createElement("script"),{src:"https://exam.pl/example.js"}))
```

`https://exam.pl/example.js` を自分のスクリプトのパスに置き換えてください。

# 何をしているの？

```js
document.body.appendChild(
    Object.assign(
        document.createElement("script"),
        {src:"https://exam.pl/example.js"}
    )
)
```

`html` の `body` に `script` タグを挿入しています。

### `Object.assign` って？

```js
const tag = Object.assign(
    document.createElement("script"),
    {src:"https://exam.pl/example.js"}
)
```

は以下と等価です。

```js
const tag = document.createElement("script");
tag.src = "https://exam.pl/example.js";
```

# もっと短くできたら教えてください！

もっと短くできたら教えてください！
Windowsマシンからリモートデスクトップマシンに一括でICMPエコー要求してみよう

実行結果
```powershell
PS > .\hoge.ps1 .\hosts.txt
host1 1
host2 0
host3 1
```

hoge.ps1
```powershell
Param($file)
$hosts = Get-Content $file
$count = 3
$timeout = 3
foreach ($h in $hosts) {
    $result = Test-Connection $h -TimeoutSeconds $timeout -Count $count -Quiet 
    Write-Output "$h $($result -as [int])"
}
```

参考資料
https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.management/test-connection?view=powershell-7.3#-timeoutseconds
Googleデータアナリティクス：決定木でデータを成長させる

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/05522c3b-515a-bc49-aaa3-a0489a6b12b1.png" width="800">

# 決定木でデータを成長させる

多くのビジュアライゼーション方法が存在する中で、データを表現する最適な方法をどのように判断すればよいのでしょうか。

***<font color="MediumVioletRed">『決定木は、ビジュアライゼーションの重要な判断においてアナリストの意思決定を支援するツール』</font>***

以下は、どのビジュアライゼーションがストーリーを伝える上で最も適しているか、データ主導の意思決定ができるガイドとなるものです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/2b4f1381-3ae0-d076-0d4d-72fd1a96d78b.png" width="750">

まず、あなたが持っているデータを分析し、最適なビジュアライゼーションの方法を決定するために、一連の問いに答えることから始めましょう。

### <font color="MediumBlue">データに含まれる数値の変数は 1 つだけですか？ </font>

もし、データの変数が 1 つの連続した数値であれば、そのようなカテゴリーデータを表すのにはヒストグラムや密度プロットが最適な方法です。データ型によっては、棒グラフの方が適している場合もあります。例えば、生徒グループの身長に関するデータがある場合、各身長範囲に何人の生徒がいるかをビジュアライゼーションするのには、ヒストグラムを使用するとよいでしょう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e7b7d7d6-f624-0608-bba0-a5c3cc03dbf3.png" width="750">

### 複数のデータセットを扱っていますか？

### <font color="MediumBlue"></font>

複数のデータを扱う場合は、データを正確に表現するために折れ線グラフや円グラフを使用するとよいでしょう。折れ線グラフは、複数のデータを一本の連続した線でつなぎ、時間の経過とともに数値がどのように変化したかを表すことができます。円グラフは、全体を複数のカテゴリーやパーツに分割するのに適しています。例えば、会社の四半期ごとの売上を計測する場合に使用します。以下は、このデータを折れ線グラフと円グラフの両方で表した例です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/9ad36571-fa98-fa25-cb64-b0377c155980.png" width="750">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7a0fd6d1-43d5-cda9-e467-72605fb04b5d.png" width="750">

### <font color="MediumBlue">時間の経過に伴う変化を測定していますか？</font>

時間の経過とともに変化するトレンドを表すには、一般的に折れ線グラフが適しています。しかし、変化が大きすぎる場合は、棒グラフを使用すると良いでしょう。例えば、過去 6 ヶ月間のニューヨークの旅行

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/74a207b1-3423-faa4-c2fd-b81c67c759e9.png" width="750">

### <font color="MediumBlue">データ間の関連性を示す必要はありますか？  </font>

1 つのデータセットに 2 つの変数がある場合、一方が他方にどのように影響するかを挙げることが重要です。対になる変数は、散布図で表すのが最適です。しかし、データポイントが多すぎると、変数間の関係が不明瞭になる場合があります。その場合はヒートマップがより良い表現方法となります。例えば、アメリカの 50 州の人口を測定する場合、データポイントは数百万になるので、ヒートマップを使用することになるでしょう。単純に例えば勉強時間と成績の関連性を示すのであれば、データは以下のようになります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/ba4de104-48b5-ca99-bf87-619dd3b84529.png" width="750">

# 適切なデータビジュアライゼーションを選択するためのインサイト

https://d3c33hcgiwev3.cloudfront.net/5719A00ATXO9fQNNAP1zcw_9ea687aa01c445678f39f4efaed622a1_tetahisiyuaraisesiyonno-Xuanhi-Fang.pdf?Expires=1682121600&Signature=Ww9nTC1YEm4ED0lMaGA-ZWEOjcIZTo7qHN1idZSY2NZVjsjScRNrD3YT00AYJuUgSk2MyyfdlCUJvfqMdCQH91bYuaUX3MdSQFWi0n60~Q8KFK~BsIqkQpdc7y~6cMhTRtVZJFscN8UjimWecNxVPDyBIFw2xjmMi7wuim2Zw~c_&Key-Pair-Id=APKAJLTNE6QMUY6HBC5A
CondaでRubyを使う

AnacondaやMinicondaでRubyをインストールして使いたい場合があるかもしれない。普通に、

```
conda install ruby
```

とすればRubyは使えるようになるけれども、これだとネイティブ拡張を利用したgemをコンパイルしてくれない。ネイティブ拡張を全く使わずにRubyを使うケースはほぼないと思うので、この方法だと実用性があまりない。

では、どうすればいいかというと、conda-forgeからRubyをインストールすればいい。そして、compilerというパッケージも同時にインストールしておく。

```
conda install -c conda-forge ruby
conda install -c conda-forge compilers
```

これで、簡単にAnacondaやMinicondaなどのConda環境から、Rubyを使えるようになる。

この記事は以上です。

参考文献
https://github.com/conda-forge/ruby-feedstock/issues/44
読書研修ーWEBを支える技術　第３章





## アーキテクチャスタイル
1.アーキテクチャスタイルとは
>（マクロ）アーキテクチャパターン」ともいい、複数のアーキテクチャに共通する性質、様式・作法あるいは流儀を指す言葉だ。

2.アーキテクチャスタイル例
<ul>
<li>MVC</li>
<li>ハイプ＆フィルタ</li>
<li>イベントシステム</li>
</ul>

RESTはWebのアーキテクチャスタイルです。
3.重要性：
    <dd>システムのアーキテクチャを決定する際の羅針盤</dd>


4.デザインパターン
    <dd>アーキテクチャスタイルよりも粒度の小さいクラスなどの設計様式</dd>

## アーキテクチャスタイルとしてのREST
1.REST:クライアント/サーバの派生
2.制約
<dd>一般にソフトウエアアーキテクチャは複数のコンポーネントを組み合わせて実現しますが、それぞれのコンポーネントがバラバラに動いているのでは動作しません。そこで、各コンポーネントに制約を課していきます。その結果、全体として各コンポーネントが協調して動作するようになります。</dd>

## リソース

1.リソースとは
<dd>web上に存在する情報

サーバとクライアントの間でやり取りするデータのことを「<strong>リソースの表現」</strong></dd>
<br>
2.リソースの名前としてのURI
<dd>世界中の無数のリソースはそれぞれURIで一意の名前持つ

URIでプログラムはリソースが表現する情報にアクセスできる</dd>
<br>
3.リソースのアドレス可能性
<dd>URIでリソースをかんたんに指し示せること→<strong>アドレス可能性</strong>

きちんと名前をつけており適切な手段でアクセスできる状態にすると、プログラムをとても作りやすくなります</dd>
<br>
4.複数のURIを持つリソース

<dd><strong>一つのリソースは複数のURIを持てます。</strong>

利点：リソースに別名のURIをいくつもつけると、クライアントがリソースにアクセスしやすくなる。
欠点：それが正式なURIなのかがわかりにくくなってしまう</dd>

<br>
5.リソースの表現
<dd>
<strong>一つのリソースは複数の表現を持てます。</strong>

HTML・テキスト・PDFなど違う表現は個別のURIを与えてもいいし、HTTPの仕組み使って一つのURIで複数の表現を返すことできる</dd>
<br>
6.リソースの状態
<dd>時間に経過に従ってリソースの状態が変わると、その表現も変わる</dd>

## スタイルを組み合わせてRESTを構成
### REST=ULCODC$SS
REST とはつまり、次の6つを組み合わせたア-キテクチャスタイルのことなのです。

| スタイル | 作用|補足
|:-:|:-:|:-:|
|  クライアント/サーバ |  ユーザインタフェースと処理を分離する |:-:|
|  ステートレスサーバ |  サーバ側でアプリーション状態を持たない |現実にはステートレスでないWebサ-ビスやWeb APIが多々あります。HTTPをステートフルにする代表格はCookieを使ったセッション管理です。|
|  キャッシュ |  クライアントとサーバの通信回数と量を減らす |古いキャッシュを利用してしまい、情報の信頼性が下がる可能性もあります。|
| 統一インタフェース  |  インタフェースを固定する |統一インタフェース はRESTを最も特徴付けるスタイル|
| 階層化システム  | システムを階層に分離する  |:-:|
|  コードオンデマンド |  プログラムをクライアントにダウンロ-ドして実行する |コ-ドオンデマンドでプログラムをダウンロ-ドし、クライアント側で実行してしまうと、アプリケーションプロトコルの可視性は低下します。|

<br>P2P(Peer to Peer)は代表的なREST以外のアーキテクチャスタイル

## RESTの２つの側面
#### RESTとハイパーメディア
RESTとハイパ-メディア通常私たちWebを使う一連の作業の最小単位は、「Web上のリソース同士か持つリンクたたどる」ことです。<br>
<strong>ハイパ-メディアの基本機能</strong>
<dd>リンクをたどる作業をいくつか経ることで、全体としてはソ-シャルプックマ-クという1っのアプリケ-ションを実現します。</dd><br>
<strong>Webが持つこの特徵</strong>
<dd>RESTでは「アプリケーション状態エンジンとしてのハイパーメディア」(Hypermedia as the engine ofapplication state)と呼びます。<br></dd><br>
<strong>アプリケ-ション状態とは</strong>
<dd><p>たとえばソ-シャルプックマ-クアプリケ-ションの利用者が持つ状態のことです。ハイパ-メディアのリンクをたどる作業によって遷移します。</p></dd><br>
<strong>ハイパ-メディアを用いたアプリケ-ションの利点</strong>
<dd>リソ-スのURIさえわかれば、あるアプリケ-ションが提供しているリソ-スをほかのアプリケ-ションでも簡単に再利用できる。</dd>

#### RESTと分散システム
| RPCやCORBA、DCOMなど | REST |
|:-:|:-:|
 関数やメソッド単位でサ-バ側の処理を呼び出し<br>呼び出し回数が多いとシステム全体の性能劣化を引き起こす|   リンクをたどることでアプリケーションを実現<br>リンクをたどってアプリケ-ション状態を遷移するほうが全体として性能劣化が抑えられます。|
 |  機能を追加してージョンアップするたびに、メソッドが増えたりメソッドの引数や戾り値が変わったりしてAPIの互換性が失われます | 統一インタフエースによってインタフエ-スカ固定されているため互換性の問題は発生しません  |

## RESTの意義
>私たちが作る Web サ-ビスやWeb API はWeb を構成する一部です。個別のWebサ-ビスやWebAPIがRESTful注になると、Webは全体としてより良くなります。