OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】SwiftFormatをSwiftPMで導入する

# はじめに

https://qiita.com/SNQ-2001/items/c56658193d54c040c1fb

以前、「SwiftFormatをSwiftPMで管理する」という記事を書きました。

今回はSwiftPMでプロジェクトに直でパッケージをいれる？方です？笑

これ呼び方の区別どうやってするんですかね？

# インストール
① 「File」を選択します
② 「Add Packages...」を選択します
![スクリーンショット 2023-03-13 22.20.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/9b77b140-b923-55b5-04db-f57e3a8380d7.png)

③ `https://github.com/nicklockwood/SwiftFormat`を検索します
④ 「Dependency Rule」を設定します
⑤ 「Add Package」を選択します
![スクリーンショット 2023-03-13 22.22.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/c72ea8a9-b0f3-e155-19bc-baa585bce39d.png)

⑥ 「SwiftFormat」を選択します
⑦ 「Add Package」を選択します
![スクリーンショット 2023-03-13 22.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/ac831f71-eb54-5ac5-4f0f-fea4690e6ae5.png)

# 実行
とりあえず、コードをメチャクチャにします
![スクリーンショット 2023-03-13 22.40.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/6705fe1a-a2fa-63cc-b1a4-c37fa850c85e.png)

① プロジェクトを右クリックします
② 「SwiftFormatPlugin」を選択します
![スクリーンショット 2023-03-13 22.40.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2ab7dc2f-e8b5-1700-f299-a5e1f38fe858.png)

③ 「Run」を選択します
(Argumentsでオプションを設定できます。今回はオプションなしで実行します)
![スクリーンショット 2023-03-13 22.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/391d7baa-d0ad-509a-cf2c-e318ef6e9711.png)

コードが綺麗になりました！
![スクリーンショット 2023-03-13 22.43.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/c2446ab6-992b-22d2-c3f7-4be002826d54.png)

# おわり
ビルド時に実行されるプラグインも欲しいです。
SwiftFormatは本当に便利です。
Vue3の reactive なリストの中でcomputedを使ってみる

Vue3の reactive なリストの中でcomputedを使ってみる

# reactiveの中にcomputed・・・

```typescript
import dayjs from 'dayjs';
import { reactive, computed, ref } from 'vue';

const state = reactive({
  listA: {},
})

const appendListA = () => {
  const ts = dayjs().format('YYYY-MM-DD HH:mm:ss.SSS');
  state.listA[ts] = {
    data: { a: 0, b: 0 },
    sum: ref(0),//初期値はrefを格納
  };
  state.listA[ts].sum = computed(() => {
    console.log('listA', ts, 'computed', state.listA[ts].data);
    return state.listA[ts].data.a + state.listA[ts].data.b;
  });
};

```

## stateの型定義的はこんな感じ
```typescript
interface State {
  listA: {
    [key: string]: ListRowA;
  };
}

interface ListRowA {
  data: { a: number; b: number };
  sum: ComputedRef<number> | Ref<number>;
}
```

## あとはaとbを操作するテンプレートを用意すれば・・・

### aを20に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3270885/79ef819e-441b-002f-ce28-a2251acffdf9.png)

### bを35に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3270885/6d7903ec-bf65-e99e-1ffb-130d2f843f1a.png)


**sumが55に変わった！**
しかも画面描画の度に再計算されずちゃんとキャッシュを保持してくれてます。

# 他の実装方法

以下の実装は画面描画の都度再計算されるのでコスパ悪い
* v-forのループ内で関数を呼び出す
* Vue2系からGoogle検索で見かけたcomputedに引数
    ```typescript
    //例
    interface ListRowB {
      data: { a: number; b: number };
    }
    interface State {
      listB: {
        [key: string]: ListRowB;
      };
    }
    const state = reactive<State>({
      listB: {},
    });
    const sumListB = computed(() => (ts: string, row: ListRowB) => {
      console.log('listB', ts, 'computed', row);
      return row.data.a + row.data.b;//rowは一応Proxyオブジェクト
    });
    ```
    上記computedでsumを計算した場合
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3270885/7038a779-be1a-2463-deb9-c4286794e93a.png)
    一つの値を操作すると操作していない方も再計算される。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3270885/9a01197a-673e-6d35-b8fa-776af3a6a565.png)
    



一般的には値をdeepにWatchして変更時にreactiveなオブジェクト内に計算結果を保管？でしょうか。

もしくは集計用配列をcomputedで作るとか？
```typescript
//集計用・・・・これもcomputedに引数と一緒で再計算されますね・・・・・
const sumList = computed(() => {
    return Object.keys(state.listB)
        .map((key) => {
          return {
            key: key,
            value: state.listB[key].data.a + state.listB[key].data.b,
          };
        })
        .reduce((ret, row) => {
          ret[row.key] = row.value;
          return ret;
        }, {} as { [key: string]: number });
});
```





# 最後に
ちなみにサンプルコードがキーバリューなリストにしているのはたまたまです。
ArrayだとRefの部分にcomputedを代入するときnumberで型エラーが・・・記事書いてて気づいた。
回避策未確認。


ProxyなreactiveオブジェクトってClass内に設置してClassの関数からthis経由で触ってもVueが変更検知できたり意味不明レベルでストーカーな監視体制なのビックリですね・・・・・
ほんとに雑に扱っても監視されるw
※Classの中でreactiveを使う例
```vuejs
<script setup lang="ts">
import { reactive } from 'vue';
class Hoge {
  public state = reactive({ step: 0 });
  public step() {
    this.state.step += 1;
  }
}
const hoge = new Hoge();
</script>
<template>
<div class="" @click="hoge.step()">hoge{{ hoge.state.step }}</div>
</template>
```
    



# GitHubにサンプル上げてます

https://github.com/hare-systems-ryo/vue-sample-1


# ついでにGitHubにデモページも・・・

https://hare-systems-ryo.github.io/vue-sample-1/
ビヘイビア駆動開発

## 駆動開発の種類
下記のように駆動開発は数多くあり、本記事ではビヘイビア駆動開発について紹介する。
* 締め切り駆動開発(DDD)
　開発の各工程のデットエンドまで時間をかけて開発をすること。
* 文書駆動開発(DDD)
　ドキュメントの整合性を中心に設計や開発をすること。
* ドメイン駆動開発(DDD)
　ソフトウェア化する対象を抽出してから開発をすること。
* チケット駆動開発(TiDD)
　課題解決を中心に設計や開発をすること。
* テスト駆動開発(TDD)
　先にテストを用意してから開発をすること。
* 受け入れテスト駆動開発(ATDD)
　受け入れテストを中心に設計や開発をすること。
* ビヘイビア駆動開発(BDD)
　シナリオテストを中心に設計や開発をすること。
* ユーザー機能駆動開発(FDD)
　ユーザが使う機能を中心に設計や開発をすること。
* モデル駆動型開発(MDD)
　ドメイン固有言語(DSL)で設計してから開発をすること。

## ビヘイビア駆動開発とは
* 振る舞い試験の一種。
* テスト駆動開発を拡張したもの。
* 1つのシナリオ試験を深掘りする形で行う。
* ビジネスサイドや品質管理サイドも理解できるように記述することが望まれている。
* Gherkin記法を用いて記述される。

## ビヘイビア駆動開発の長所短所
### 長所
* 開発サイド以外の意見も取り入れるため、実装漏れに繋がる。
* 目的が明確化しやすく、ユニットテストがしやすくなる。

### 短所
* シナリオテストが複雑になると、ユニットテストが乱立してしまい、独立したはずのユニットテストが依存関係を持ってしまう可能性がある。
* シナリオテストに含まれないユニットテストが漏れやすくなる。

## Gherkin記法
* 「こういう状態のとき、こういう動作を行えば、こうなることが期待される」という形で表される。
* WhenやThenの部分でテスト駆動開発の手法が用いられる。

* 書式
~~~
As：〜として
Given：前提条件
When：どの様な操作や入力
Then：操作や入力の後に期待すべき結果は
 And：かつ
 But：しかし
~~~

## 例題
* 満足条件
  * 再生プレイヤーにて再生中にシャッフルボタンを押下した際、再生中の楽曲を再生リストの1曲目としてリストが生成される
  * 再度シャッフルボタンを押下すると元に戻る
~~~
Feature：○○音楽プレイヤー(シャッフル再生)
Scenario Outline：シャッフル再生
AS ○○音楽プレイヤーのプレイリスト利用者として
GIVEN 3曲以上のプレイリストがあり、リスト２曲目を再生中
AND  再生中にシャッフルボタンを押下して＜ボタンの状態＞にする
WHEN  再生リストをタップして、リストの状態を確認する
THEN 再生中の楽曲が＜再生リスト位置＞にある
~~~
~~~
Examples:
|ボタンの状態  |再生リスト位置|
|活性(ON)      |　　 　 1曲目|
|非活性(OFF)   |        2曲目|
~~~

## 参考
* [駆動開発の様々な種類を言えますか？](https://zenn.dev/miya_tech/articles/707757332608ec)
* [アジャイル開発における「TDD」と「BDD」](https://shiftasia.com/ja/column/%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Btdd%E3%81%A8bdd/)
* [BDDとユニットテストの流派](https://qiita.com/YUM_3/items/b7c1cd1be9da92625143)
* [Gherkin記法を使ったテスト設計](https://qiita.com/y-kiyosaki/items/800695c96892925a8758)
FirebaseプロジェクトでApp Checkを利用する

https://datumstudio.jp/blog/1115_firebase_app_check/

これと公式ドキュメントを見れば実装できた。

## 起きた問題
現在開発しているプロジェクトでは、Cloud FunctionsからCloud Storageに画像をアップロードする処理を行っているのだが、Storageに対してApp Checkを有効にする場合ファイルに対するアクセストークンが無いと拒否されてしまう。

そのため、

https://www.sentinelstand.com/article/guide-to-firebase-storage-download-urls-tokens

これを見て
```ts
await bucket.file(thumbnailPath).setMetadata({
  metadata: {
    firebaseStorageDownloadTokens: uuid,
    // ...
  },
});
```
このようにした。
作成しておいたuuidをURLに含めてFirestoreに保存すればしっかりアクセスできる。

トークン無しでアクセスすると
```
{
  "error": {
    "code": 401,
    "message": "Firebase App Check token is invalid."
  }
}
```
このようなエラーが表示され、しっかりApp Checkが働いていることが分かる。

##
攻撃に怯えて作ったプロジェクトを公開できないのもどうかと思ったので少しセキュリティ周りについて調べているが、どこまでやればいいのかとか、どのようなものを防げているのかよくわかっていない。
すごくふんわりしている。
セキュアコーディング備忘録

アプリ開発のセキュリティについて備忘録。Java前提。

## まずはIPAのサイトを見るべき
[安全なウェブサイトの作り方](https://www.ipa.go.jp/security/vuln/websecurity.html)

## 要約
* ユーザの入力を信用するな
* ユーザが入力できる部分を信用するな
* ブラウザが実行するイメージを持とう
* JSON使え
* 同一オリジンポリシーえらい([過去記事](https://qiita.com/codela/items/56a892776e27e7ce3bc7))

## XSS
Cross-Site Scripting。
同一オリジンポリシーがあるならそのサイト自体に悪意あるスクリプトを発行させればいいじゃない、な攻撃。

掲示板にスクリプトを書き込み、ロードした他人のブラウザで実行させるイメージだったが、それ(Stored)以外にもある。
Reflected, Stored, DOM-basedの3種で、どうやってそのサイトが発行したことにするかが異なる。

Reflected, DOM-basedの説明を読んで、自身のブラウザが送信した/持っているスクリプトが自身のブラウザで実行されるだけなので何が問題か分からなかった。
以下のサイトで、リンクを踏ませる時に`?q=`や`#paragraph`で意図しない情報を付加させるイメージが掴め、理解できた。

https://www.tohoho-web.com/ex/xss.html

## Open Redirection
要はXSSと同じで、`?q=`とかの手打ちできる部分を元に動的に処理すると、攻撃者によって意図しないリダイレクト先のリンク作られちゃうよという話。

(ページが)リダイレクト先の情報を動的に決めていると、(攻撃者が作成した)変なリンクによって、(善意のユーザが)変なページにリダイレクトされてしまう、という感じで主語がたくさんある手法なのでイメージを整理しておきたい。

「外部ページだけど大丈夫？」という確認ページ挟むが対策の一つ。

Javaの場合は[URLクラス](https://docs.oracle.com/javase/jp/8/docs/api/java/net/URL.html)を使ってURLの検証が可能。


## Click Jacking
`<iframe>`で他のページを埋め込んで誤クリックさせる。

意図しない埋め込まれ方をしないよう、HTTPヘッダで以下の制御を行う。
* X-Frame-Options
* Content-Security-Policy: frame-ancestors

一瞬悪意があるならヘッダを無視して埋め込まれてしまうのでは？と思ったが、
埋め込まれるかではなく、善意のユーザのブラウザ上でそれが描画されるかがポイントだと理解した。

## Insecure Deserialization

#### 📞😾＜どうしてシリアイズデータをユーザ側に渡したんですか？

シリアライズデータは改竄されうるからJSON使おうね。



## XXE攻撃

XML External Entity攻撃。なんでXEEじゃないんだと最初思った。

XMLがデータ構造を定義(DTD: Document Type Definition)できるのは基本情報でやった記憶があるが、定義中で外部リソースを読み込める仕様であるらしい。
そのためDirectory Traversalのような機密情報へのアクセスや、再帰参照によるDoS攻撃の恐れがある。
DTDを無効化して対策できる。

**結論：JSON使おう**

## Directory Traversal
Javaの場合、Path#normalizeでキレイにできる。
```normalize.java
String BASE = "/app/files/";
String fileName = getInput();
// Path#normalize によって /app/files/.././hoge は /app/hogeになる
Path filePath = Paths.get(BASE, fileName).normalize();
// パスがBASE以下であるかをPath#startsWithでチェック
boolean isValid = filePath.startsWith(BASE);
```

## OS Command Injection
シェルに引数を渡すときに攻撃者が余計なコマンドをくっつけて実行させる攻撃。

Javaの`Runtime.getRuntime().exec({"ls"});`ではシェルを呼び出さず、指定した実行ファイルを直接実行するので安全だが、`.exec({"sh", "-c", "ls"})`のようにシェルに渡すのは危険。

~~シェルに慣れていなければ必然アプリでなんとかするので安心~~


## SSRF

Server Side Request Forgery。Open Redirection、XXE攻撃、OS Command Injectionなどにより、外部公開されていないサーバにアクセスすること。



## CSRF

Spring Securityを使う場合CSRFトークンを埋めこんでくれるらしい。
手動でやるなら都度UUIDで遷移の正当性確認。

## メモ
* Forgery：偽造(物)。 CSRF、SSRFのF。

* (非Stored)XSSもOpen Redirectionも、攻撃者は変なリンク作ってるだけだから攻撃感ないなと思った。ユーザがいじれる値は信用しちゃだめということに加えて、リンクは攻撃者がいじった上でユーザに渡せるというイメージを膨らませておくのが重要そう。

* 重要な操作は確認画面入れるとユーザの意図に反した挙動を防げがち。

* Springの[@CookieValueアノテーション](https://spring.pleiades.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/CookieValue.html)を知ったのでCookieが使えるようになった。もともとイメージはあったけど、改めてこれ勝手に送られてきてるのか...と思ったし、ClickJacking対策のオプションもだけどHTTPヘッダについて深堀りしたい。新人研修でSessionはやるけどそれが可能になってる仕組みについてはやらないんだよね。

* JavaのURLクラスは「ポート番号が無い」も「ポート番号に-1を指定した」も-1になるらしい...([参考](https://kaworu.jpn.org/java/Java%E3%81%A7URL%E3%82%92%E3%83%91%E3%83%BC%E3%82%B9%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95))。

* JSONはセキュリティ上のメリット大きいんだなと思った。AjaxがxmlじゃなくJSON使うようになったのもそういうこと？

* OS Command Injectionで、Javaのファイル操作使って安全にしようとして、Java Gold取ったことでファイルIO周りの知識が整理されてるのを実感した。
ポートフォリオ制作に使える無料素材サイト【写真・イラスト・アイコン・動画】

ポートフォリオサイト制作の際に、使ってほしい無料素材サイトをまとめました。

## 写真
### Unsplash
https://unsplash.com/

### Pexels
https://www.pexels.com/

### Pixabay
https://pixabay.com/

### StockSnap
https://stocksnap.io/

### 写真AC 
https://www.photo-ac.com/

### ぱくたそ
https://www.pakutaso.com/


## イラスト

### Linustock
https://www.linustock.com/

### スコスト
https://soco-st.com/

### ダ鳥獣ギ画
https://chojugiga.com/

### Tech Pic
http://tech-pic.com/

### storyset
https://storyset.com/


## アイコン

### icooon-mono
https://icooon-mono.com/

### icon-rainbow
https://icon-rainbow.com/

### FLAT ICON DESIGN
http://flat-icon-design.com/

## 動画
### Pixabay
https://pixabay.com/ja/videos/

### Pexels
https://www.pexels.com/ja-jp/videos/
【Laravel】ルーティングに対する基礎知識

## アジェンダ
* PHP[Laravel]の基本機能の一つ、ルーティングについて基礎理解を深める。
* ルーティングに用いられている基本的な関数についても理解を深める。

## ルーティングとは
ある特定のアドレスにアクセスした際に、何のHTTPリクエストを要求されたら、どの処理を実行するかを管理・設定する仕組みです。

ルートディレクトリをアクセスし、GETリクエストを要求すれば単純にトップページを表示させたい場合や、投稿フォームページからPOSTリクエストをした場合は、入力情報をDBへ保存する処理を実行させたい、などと、Laravelで最も基本的な仕組みの一つとなります。

## 何が起きているのか
### 基本
Laravelを導入すると、デフォルトで設定されているルーティングがあります。
こちらから見てみます。

```web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});
```
##### Routeクラス
Laravelのルーティング機能は、ルートファイルに定義されたRouteクラスを記述する事で処理を定義していきます。

##### ::（スコープ演算子）
静的メソッドやインスタンス化されていないクラスのプロパティを呼び出す演算子です。似たような演算子に、 **->（アロー演算子）** があります。

##### HTTPメソッド
ここで設定されているget()メソッドは、Laravelで定義されているRouteクラスのHTTPメソッドの一つで、スコープ演算子によって呼び出されます。Laravelでよく使われるHTTPメソッドは以下があります。
* GET()
* POST()
* PUT()

##### ($url, $hogehoge)
第1引数に特定のアドレスを指定し、第2引数に関数を指定します。デフォルトでは、第1引数は`'/'`で、ルートディレクトリを指定しています。第2引数には`function(){return view('welcome')}`と **無名関数** を記述し、 **view** という関数で引数に指定した'welcome'テンプレートをレンダリングしブラウザに返しています。

:::note warn
無名関数とは
関数名を指定しない関数。クロージャーとも言う。通常の関数は、`function hogehoge(引数)`のように関数名を指定するが、無名関数では`function(引数)`のように関数を指定しない。その場でしか使う必要が無い場合に用いる関数。
:::
:::note warn
view関数とは
ビューを表示させる関数。引数にファイル名を指定することで、HTML,CSS,PHP,JSなどで構成された該当のbladeテンプレートファイルをレンダリングし、ブラウザに表示させる関数。
:::

まとめると、デフォルトのルーティングは、ルートディレクトリにアクセスし、GETリクエストを要求した場合に、'welcome'というテンプレートファイルをレンダリング処理し、ブラウザに表示させる処理を実行するように設定されている事になります。

### 定石
デフォルトの例では、処理したい内容はview関数でwelcomeというテンプレートをreturnする事でした。

Laravelでルーティングを活用するために、特定のコントローラーのメソッドを呼び出して処理を実行したい場合に、HTTPメソッドの第2引数にコントローラーを指定する記述ができます。

```web.php
Route::post('/post', 'App\Http\Controllers\PostController@store');
```
上記例は、`/post`ディレクトリにアクセスしていて、POSTリクエストを要求すると、`'App\Http\Controllers\PostController@store'`を呼び出して実行させるルーティングの設定になります。

デフォルトのルーティングと異なる点は以下。
* HTTPメソッドをget()からpost()
* 第1引数を'/'から'/post'
* 第2引数を「無名関数でview関数を実行」から「~~~PostController@store」

第2引数にコントローラーを指定することで、LaravelのMVCモデルに則った実装ができます。特定のURLにおいて、特定のHTTPメソッドを要求した場合に、特定のコントローラーのメソッドを呼び出すルーティングを行う事で、動的な処理を使い分けて実行できるようになります。

ここで言う第2引数の`'App\Http\Controllers\PostController@store'`はあくまで例ですが、別途作成したPostController内にあるstoreメソッドを呼び出す記述となっています。

このstoreメソッドには、ユーザーがビューで入力した情報を、DBに保存する仕組みが記述されている前提だとします。

すると、ユーザーは`/post`にアクセスし、何らかの投稿フォームが表示されていて、そこに情報を入力し`POSTリクエスト（ユーザー側からすると、送信ボタンを押す、など）`を行うと、上記のルーティングによって、PostControlleのstoreメソッドが実行され、ユーザーが入力した情報がDBに保存される流れになります。

そのような仕組みを、リクエストや条件で柔軟に実行する処理を分岐できます。またLaravelのMVCモデルに基づいた実装は非常に便利で、コントローラーを活用することでバリデーションチェックやDB操作を容易に実装できます。

これらの組み合わせで、複雑なWEBアプリ開発を実現することができます。

今回はここまで。
ご指摘事項等あれば、是非ご教授ください。励みになります。

お時間いただきありがとうございました。
Git ,GitHub ,GitHub desktop インストール＆基本操作（個人開発用）

# 【動画】インストール＆基本操作①
https://twitter.com/yota_okabe/status/1635258160331235329?s=20
# 【動画】　基本操作②
https://twitter.com/yota_okabe/status/1635261594136621056?s=20
JAVA学習の記録④　【カプセル化】

前回までの学び　[JAVA学習の記録③　【ゲッターとセッター】](https://qiita.com/rion0726ittoti/items/97784b6e9bdb06ce4341)

## カプセル化とは
クラスが持つデータ（JAVAではフィールド）とそのデータを直接操作する処理をクラス内に限定し、独立性を高める考え方のこと。

カプセルなしの場合![2023-03-11 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3185982/c4bc4045-7831-1762-7724-3ca533f13072.png)
カプセル化をすると!![2023-03-11 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3185982/24a58aed-54d9-0252-480c-cedf239598e6.png)
イメージ的にはこんな感じです。カプセルでクラス全体を包み込んで直接フィールドの値を変更するのを防ぐ感じです。

カプセル化の基本的なやり方としては、
***・フィールド変数のアクセス修飾子をprivateにする。***
***・メソッドのアクセス修飾子をpublicにする。***
です。そして、フィールド変数の値を変更するためのメソッドとして、ゲッターとセッターを用いて行います。
## アクセス修飾子とは
アクセス修飾子とは、public、protected、privateといった修飾子の総称で、クラスやそのメンバーがどこからアクセス可能であるかを決定する。
***アクセス修飾子を指定したフィールドの定義***
```java
private int num;
アクセス修飾子 フィールドの型 フィールド名;
```

***アクセス修飾子を指定したメソッドの定義***
```java
private void setAge(int dogAge){
  //処理
}
アクセス修飾子 戻り値の型 メソッド名 引数リスト {
   //処理
}
```
## アクセス修飾子によるアクセス許可の範囲
|アクセス修飾子|アクセスを許可する範囲|
|:---|:---:|
|private|クラス内のみ|
|記述なし|同じパッケージ内のクラス|
|public|すべてのクラス|
|protected|現在のクラスとサブクラスからアクセスできる|

## カプセル化の原則にしたがったクラス
```java:Dog.java
public class Dog {
  private String name; //フィールドはprivate
 
  public void setName(String dogName){ //publicなセッター
    name = dogName;
  }
  public String getName() { //publicなゲッター
    return name;
  }
  
}
```
```java:Dogcapsulation.java
public class DogCapsulation {
  public static void main(String[] args) {
    Dog pochi = new Dog();
    pochi.setName("ポチ"); //setNameメソッドを呼び出す
    System.out.println(pochi.getName()); //getNameメソッドを呼び出す
  }
}
```
出力結果
```
ポチ
```

フィールのアクセス修飾子をprivateにし、セッターを用いて値の設定、ゲッターを用いて値の取得を行いました。

参考文献
「いちばんやさしいJAVAの教本」著者　石井真
VSCodeのおすすめ拡張機能

VSCodeには、数多くの拡張機能が用意されており、エディタの機能を拡張したり、開発の効率を向上させたりすることができます。以下は、VSCodeのおすすめ拡張機能です。

## Japanese Language Pack for Visual Studio Code
Japanese Language Pack for Visual Studio Codeは、VSCodeを日本語化する拡張機能です。この拡張機能をインストールすると、VSCodeのUIとメニューが日本語に変更され、より親しみやすくなります。
https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-ja

## Live Server
Live Serverは、Web開発者にとって非常に便利な拡張機能であり、Webページをリアルタイムで更新することができます。この拡張機能を使用すると、Webページの変更を行うたびに手動でリロードする必要がなくなり、より迅速な開発が可能になります。また、Live Serverは、ブラウザに表示されるページに対してローカルサーバーを作成するため、開発者はローカルでWebサイトをテストすることができます。

https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer


## indent-rainbow
indent-rainbowは、コードのインデントを視覚的にわかりやすくする拡張機能です。この拡張機能を使用すると、各レベルのインデントが異なる色で強調表示され、コードの階層構造を簡単に把握することができます。indent-rainbowは、複雑なコードを書く場合やコードの読みやすさを重視する場合に役立ちます。

https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow

## Trailing Spaces
Trailing Spacesは、コード内に存在する不要なスペースを強調表示する拡張機能です。この拡張機能を使用すると、コード内の不要なスペースを検出し、不要なスペースが原因で発生するエラーを防ぐことができます。

https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces

## Atom One Dark Theme
Atom One Dark Themeは、モダンで洗練されたテーマの一つであり、VSCodeのUIを変更する拡張機能です。このテーマは、ダークモードに最適化されており、コードを読みやすくするために色合いが調整されています。

https://marketplace.visualstudio.com/items?itemName=akamud.vscode-theme-onedark

## Material Icon Theme
Material Icon Themeは、アイコンの種類を拡張し、ファイルやフォルダーを分かりやすく表示する拡張機能です。この拡張機能を使用すると、ファイルやフォルダーのアイコンがより直感的になり、コードの管理が簡単になります。

https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme
Visual Studio Codeのシェルのパスを変更する

新しくM2のMacBook Airに買い替えた際にVS Codeのシェルの設定が違うために，ターミナルが開けなかったので解決策を残す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/4309234d-fc86-5569-ed03-100ba1dc95c8.png)
このエラーはVS Codeに設定してあるシェルのPathがないため，ターミナルが開けないエラーである．
そのためにはシェルのパスを変更する必要がある．

1. Cmd + ,でSettingsを開く．
2. setting.jsonを開く
3. "terminal.integrated.shell.osx"のPathを変更する．
    シェルのPathを確認するには echo $SHELL を実行するとシェルのPathが確認できる．
```setting.json
"terminal.integrated.shell.osx": "/bin/zsh"
```
これでVS Codeのターミナルが開ける．

## まとめ
やはり公式のDocumentを読むのが一番速い解決策である．

## Reference
https://code.visualstudio.com/docs/supporting/troubleshoot-terminal-launch
Bing の AIチャットを Node.js で試す(Node.js v18以上)

# はじめに
Bing AIチャットの順番待ち登録が済んでいる事が大前提となっています。

# やっておくと楽な行為
Cookie に関する操作があるので、Edgeアドオン『[Cookie Editor](https://microsoftedge.microsoft.com/addons/detail/cookie-editor/ajfboaconbpkglpfanbmlfgojgndmhmc?hl=ja)』を使って Cookie を閲覧すると作業が楽になります。

https://microsoftedge.microsoft.com/addons/detail/cookie-editor/ajfboaconbpkglpfanbmlfgojgndmhmc?hl=ja

<!-- 各チャプター -->
# 導入部分
```
npm install bing-chat dotenv
```

```diff_json:package.json
{
+  "type": "module",
  "name": "bing-chat-qiita-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "bing-chat": "^0.2.1",
    "dotenv": "^16.0.3"
  }
}
```

```.env
BING_COOKIE="Cookie「_U」 の Value をここに設置してください。"
```

# コード
```js:main.js
import dotenv from 'dotenv'
import { BingChat } from 'bing-chat'

dotenv.config();

(async () => {
  const api = new BingChat({
    cookie: process.env.BING_COOKIE
  });

  const res = await api.sendMessage('こんにちは');
  console.log(res.text);
})();
```

```text:output
こんにちは、Bingです。どうぞよろしくお願いします。😊
```

# 注意
非公式ライブラリを用いての実装の為、Bing Chat 自体の仕様変更により動作不能になる恐れがある事をご了承ください。
STREAM DECKにWindowsストアアプリを登録する簡単な方法、ついでにアプリを終了するボタンの作り方のメモ

# STREAM DECKにWindowsストアアプリを登録する簡単な方法

1. `Win + R` ⇒ `shell:appsfolder`
2. アプリのアイコンを見つけて ⇒ 適当なフォルダーへ右ドラッグなどからショートカットを作成
3. STREAM DECKで`システム`/`開く`をボタンに配置し、ショートカットファイルを指定

# ついでにアプリを終了するボタンの作り方

- `cmd /c taskkill /im GenkiArcade.exe /F`

※例: Nintendo Switch などの画面キャプチャーガジェットのストアアプリ Genki Arcade を終了させる場合。
Googleデジタルマーケティング＆Eコマース：ターゲット・オーディエンスを特定する

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/24ea32fb-2fb3-bdb2-462a-4ffc4d60a96f.png" width="800">

# ターゲット・オーディエンスを特定する

[キャンペーンのゴール][goal]を設定したら、ソーシャルメディア戦略構築の次のステップは、ターゲット・オーディエンスを定義することです。

[goal]: https://qiita.com/mapami/items/597bcd09e5c8a250762e

***<font color="MediumVioletRed">『ターゲット・オーディエンスとは、あなたが作成しようとしているコンテンツ、製品、およびサービスに最も興味を持つ可能性が高い人々のこと』</font>***


です。彼らは、あなたが解決したい問題を抱えた人たちです。

ターゲット・オーディエンスを正確に理解することにより、

- マーケティングの指針となり、何を、どこで、いつシェアするのかを決めるのに役立ちます。
- お金と時間をどこに費やすのがベストなのかを判断することもできます。

# ターゲット・オーディエンスを特定するステップ

### <font color="MediumBlue">1.現在の顧客に関する情報を収集する</font>

ターゲット層は、年齢や居住地など、何らかの共通の特徴をもっている可能性があります。ソーシャルメディアのターゲット層を決定するには、現在の顧客やフォロワーに関する情報をまとめることから始めます。この情報の一部は、調査部門、アナリスト、あるいは他のマーケティング担当者など、組織内の他の人から収集することができるかもしれません。

#### 年齢

- 年齢
- 年代
- 世代
- ライフステージ

など、人口統計学的な情報を検討します。

#### 場所

- お客様の多くはどこに住んでいるのでしょうか？

これにより、どの地域をターゲットにするか、また、ソーシャルメディアの投稿や広告のスケジュールをいつにすれば、最高の視認性を確保できるかを理解することができます。

#### 言語

- ターゲット層とのコミュニケーションに使用する言語は何ですか？

なかには、あなたの言語を話さない人や、家庭でその地域の支配的な言語とは異なる言語を話す人がいるかもしれません。

#### 興味

- 彼らは何をするのが好きなのか？
- 何が好きなのか？
- 何に関心があるのか？

#### ニーズ

- 顧客はどんな問題に悩んでいるのか？
- あなたの製品やサービスが解決できる問題は何ですか？

### <font color="MediumBlue">2.ブランドと人々の関わり方を評価する</font>

- 人々はあなたのブランド、製品、サービスについて何を言っていますか？
- 彼らは、あなたのブランド、製品、サービスのどこが好きで、どこが嫌いなのでしょうか？
- なぜオーディエンスはあなたをフォローしているのか？
- オンラインでは他にどんなことを話しているのか？

人々がどのような情報を探しているかを理解することは、ターゲット・オーディエンスを理解し、彼らのニーズを特定し、ソーシャルメディア上で彼らとどのように関わるべきかを決定するのに役立ちます。

ソーシャルリスニングツールを使用すると、ソーシャルメディア上であなたのブランドに関するこれらの会話を見つけることができます。[ソーシャル・リスニング][listen] とは、あなたのブランドについての言及や会話について、あなたのソーシャルメディアプラットフォームを追跡することを指します。

[listen]: https://qiita.com/mapami/items/46c1a6c8c753d358fd3a

### <font color="MediumBlue">3.ターゲット層がどのようなソーシャルメディアを使っているか調査する</font>

最大のインパクトを与えるには、ターゲット・オーディエンスがソーシャルメディア上で最もアクティブな場所に到達することを目指す必要があります。

- 例えば、ターゲット・オーディエンスがLinkedInにほとんどの時間を費やしている場合、Pinterestに定期的に投稿することは意味がありません。

### <font color="MediumBlue">4.競合を観察する</font>

最後に、競合が何をしているかを観察することで、ターゲット層について多くを学ぶことができます。あなたのターゲット層は、競合のターゲット層と類似している可能性が高いです。

- 競合は誰をターゲットにしているのか？
- どのようにターゲットにアプローチしているのか？
- うまくいっていること、そうでないことは何か？
- どれくらいの頻度で投稿しているか？
- どのようなコンテンツ形式を使用しているか？

ターゲットが明確であれば、その人に合ったコンテンツを開発することができます。そうすることで、彼らのロイヤリティを獲得することができるのです。
GitPodワークスペースをWebstorm（というかGateway）で開く

# さくっとやり方説明

1. GatewayにGitpodのツールを導入
2. https://gitpod.io/#https://github.com/<ユーザー名>/<リポジトリ名>をブラウザに入力して実行

正常にツールがインスコされてれば自動的に開くと思います、、、

ただGatewayは回線状況がわるいと遅延がひどいので自宅での作業はきつい。。。
スパムかどうかの判定方法

Qiitaで、コメントがスパムかどうか判定する機能がある。

ちょっと間違えて、こんな報告をした。

>定型的な広告。コメントの一覧を表示する機能があれば、スパムかどうか確認できるかもしれません。よろしくお願いします。

投稿者が、どういうコメントを投稿したかは、「コメントした記事」で確かめられた。　

課題は、コメント投稿数が少ない段階では、スパムかどうかわからない。　

# スパム　

スパムは、SPAMの広告で、SPAM、SPAM,　SPAM　と同じ言葉を繰り返すことから来たと聞いている。　

## 内容よりもブランド　

選挙の候補者の連呼は、ある程度市場効果があることがわかっている。
商品名の連呼も、音程、背景、雰囲気を間違えなければ、拒否反応があるとは限らない。

## 同じ文章の再利用　

広告のスパムに類似した行為として、同じ文章の再利用をスパムと呼ぶことがある。　


# 判定方法　

機械学習で、スパムの候補を出す方法。　
人が判定したスパムとスパム以外を機械学習させる方法。　
二つの方法の合併。
スプレッドシートにChatGPT(gpt-3.5-turbo)

スプレッドシートに、ChatGPTでテキスト表示させるやつ。(gpt-3.5-turbo)

![](https://pbs.twimg.com/media/FrGOJBdaIAAkIhK?format=png\&name=small)

備忘録で載せておく

***

# スプレッドシートの拡張機能からGASを開く

以下コードを書く

<pre><code>const SECRET_KEY = "OPENAIで取得したAPI";
const MODEL_NAME = "gpt-3.5-turbo"; // more structured and deterministic: for data

function GPT(prompt="どうもChatGPTです", max_tokens=30) {
  const url = "https://api.openai.com/v1/chat/completions";
  const payload = {
    model: MODEL_NAME,
    messages: [{role: "user", content: prompt}]
  };

  const options = {
    contentType: "application/json",
    headers: { Authorization: "Bearer " + SECRET_KEY },
    payload: JSON.stringify(payload),
  };

  const res = JSON.parse(UrlFetchApp.fetch(url, options).getContentText());
  return res.choices[0].message.content.trim();
}
</code></pre>

prompt は、おはよう、なら朝っぽい返事になる。とか、そういうことらしい　by ChatGPT

***

# スプレッドシートのセル

以下の場合

C2 = IF(ISBLANK($B2),"",GPT($B2&"の"\&C$1&"を教えてください:",3000))

D2 = IF(ISBLANK($B2),"",GPT($B2&"の"\&D$1&"を教えてください:",3000))

のようになってます

![](https://pbs.twimg.com/media/FrGOJBdaIAAkIhK?format=png\&name=small)
WEBスクレイピングの注意点

# 初めに
個人的にスクレイピングを行う機会があったため、注意すべき点をまとめました。
私自身のメモ程度のアウトプットです。


## サイトの利用規約を確認する

サイトの利用規約を確認することが一番大切です！
対象サイトのルートドメイン直下のrobots.txtを確認することで、詳細が確認できます。
（例：https://qiita.com/robots.txt)

以下が、Robots.txtファイルに書かれている詳細です。
    
    User-agent：クローラーの名前
    Disallow：クロール不可ページやディレクトリのパス
    Allow：クロール可能ページやディレクトリのパス
    Crawl-delay：クロールのインターバル（単位は秒）

## 法律に違反する可能性

スクレイピングは、法律に違反する場合があります。
個人情報や知的財産権の侵害につながる可能性がある場合や、
過度なアクセスにより、サーバーに負荷をかける可能性があるので、十分に注意が必要です。

:::note warn
悪意はなくても、刑事事件に発展したケースもあるので十分気をつけましょう！
:::

https://ja.wikipedia.org/wiki/%E5%B2%A1%E5%B4%8E%E5%B8%82%E7%AB%8B%E4%B8%AD%E5%A4%AE%E5%9B%B3%E6%9B%B8%E9%A4%A8%E4%BA%8B%E4%BB%B6

## エラー処理や例外処理を実装する

スクレイピングには、エラー処理や例外処理を実装する必要があります。スクレイピング中にエラーが発生した場合には、自動的に処理を停止するなど、適切な対処を行うことが重要です。

## データの利用

スクレイピングで取得したデータは、利用目的に合わせて加工し、利用規約に従って利用することが必要です。
また、スクレイピングで取得したデータを、第三者に提供する場合には、サイトの所有者から正式な許可を得ることが必要です。


# 終わりに
以上がスクレイピングの注意点でした！！
最後までご覧いただきありがとうございました。
ディレクトリ名・ファイル名の（部分）一致するファイルを削除するコマンド（Windows PowerShell）

# 概要
特に外向けに難しいことを発信しようとしたわけでもなく、今後もたまに使いそうだと思った、ファイルの一括削除＠Windowsローカル環境のコマンドを備忘しておきます。

# 指定階層の任意のディレクトリ配下のファイルをまとめて消す

## 一階層下

こういう感じ。

```
Remove-Item -Path 'C:\（パス）\*\（ファイル名）.TXT' -Recurse -Force
```

## 二階層下

まあ当たり前か。ディレクトリが一個増えます。

```
Remove-Item -Path 'C:\（パス）\*\*\（ファイル名）.TXT' -Recurse -Force
```

# 終わり

いい感じに「*」が思ったとおり（？）動いてくれるのは楽で良い。
Rspec モデルスペックの基本

### モデルスペックで行うこと
+ モデルのバリデーションの検証
+ クラスメソッド、インスタンスメソッドの検証

### discribe,context,itの使い分け
+ discribe
モデル内のモデル内の機能（メソッド）のテストをする際に使用する。
+ context
場合分けの際に使用する（〜な時、〜じゃない時）
+ it 
テストする処理、期待する結果を記述する。
またit一つにつき、期待する結果も一つが望ましい。
なぜなら、テストが失敗した時に問題が起きた処理を特定することができるから。

Noteモデルの検索メソッドをテストする場合
```ruby:user_spec.rb
describe '検索結果を検証' do

  context '一致するデータが存在する場合' do

    it '検索ワードに一致するデータを返すこと'
    end

  end

  context '一致するデータが存在しない場合' do

    it '空の配列を返すこと' do
    end

  end
end
```
システム割り当てIDではなく、ユーザ割り当てIDを使ってKeyVaultにアクセスしたいときに使うコマンド

# システム割り当てIDではなく、ユーザー割り当てIDを使ってKeyVaultにアクセスしたいときに使うコマンド

通常AppServiceからKeyVaultの値を参照する場合、システム割り当てIDを使用してアクセスします。
しかし様々な理由のもと、システム割り当てマネージドIDではなく、ユーザー割り当てIDを使用したい場面があります。
その場合は、AppServiceに対してコマンドを実行し設定値を変更する必要があります。
なお、Azure Portal上のUIからは変更できないため、次のコマンドをCloud Shellなどを使用して実行します。

```powershell
# リソースグループ名
$myResourceGroupName = ""
# 作成したマネージドIDのリソース名
$myAssignedIdentityName = ""
# ユーザー割り当てIDを使用したいAppService or Functionのリソース名
$myAppServiceName = ""

# それぞれのIDを取得
$userAssignedIdentityResourceId = Get-AzUserAssignedIdentity -ResourceGroupName $myResourceGroupName -Name $myAssignedIdentityName | Select-Object -ExpandProperty Id
$appResourceId = Get-AzFunctionApp -ResourceGroupName $myResourceGroupName -Name $myAppServiceName | Select-Object -ExpandProperty Id
$Path = "{0}?api-version=2021-01-01" -f $appResourceId

# プロパティを変更する
Invoke-AzRestMethod -Method PATCH -Path $Path -Payload "{'properties':{'keyVaultReferenceIdentity':'$userAssignedIdentityResourceId'}}"
```

# 参考
- [ユーザー割り当て ID を使用してコンテナーにアクセスする](https://learn.microsoft.com/ja-jp/azure/app-service/app-service-key-vault-references?tabs=azure-powershell#access-vaults-with-a-user-assigned-identity)
github.ioにapple-app-site-associationを公開してUniversalLinksを検証する

# はじめに

iOS14以降でUniversal Linksの実装を行う場合、Apple CDNがapple-app-site-association[^1] (以下AASA)を参照できるようにファイルを公開しておく必要があります。
しかし、業務のステージング環境ではIP制限などによって外部から参照出来ない状況となっていることも多いですよね。
[^1]:https://developer.apple.com/documentation/xcode/supporting-associated-domains

Universal Linksの起動確認のみを行いたい場合にわざわざステージング環境の外部公開の手続き・作業を行うのもコストが掛かりすぎるため、GitHub PagesでAASAを公開してUniversal Linksの起動確認を行ってみました。
その手順をまとめておきます。

# GitHub Pagesにapple-app-site-association(AASA)を配置する

## GitHub Pagesの作成

まずは下記を参考にGitHub Pagesサイトを作成し、{username}.github.ioのドメインを取得しましょう。

https://docs.github.com/ja/pages/getting-started-with-github-pages/creating-a-github-pages-site

疎通確認のためにリポジトリの最上位のディレクトリに index.html を置いておき、 `{username}.github.io` でアクセス出来るか確認してみましょう。

続いて、`.well-known` ディレクトリを作成し、AASAを配置します。
AASAは下記のようなJSONフォーマットで配置します。

```json
{
  "applinks": {
    "details": [
      {
        "appIDs": [ 
          "ABCDEFGHIJ.jp.co.myapp"
        ],
        "components": [
          {
            "/": "/*",
            "comment": "Any comments"
          }
        ]
      }
    ]
  }
}
```

## AASAに最低限記載する項目

### appIDs

```json
        "appIDs": [ 
          "ABCDEFGHIJ.jp.co.myapp"
        ],
```

`appIDs`にはDevelopment team　ID[^2]とBundle identifierを連結したAppIDを記載します。
検証AppであればEnterpriseのアカウントのTeam IDである必要があります。

[^2]:https://developer.apple.com/jp/help/account/manage-your-team/locate-your-team-id/

### components

```json
        "components": [
          {
            "/": "/*",
            "comment": "Any comments"
          }
        ]
```

Appを起動させたいパスを記載します。
`{username}.github.io` (ドメインそのまま)で起動させたい場合には `/*` を許可するよう指定します。

## `.nojekyll` を忘れずに

ただし、上記のファイルのみだと `.well-known/` 配下のファイルが　404 となってしまいAASAが参照できません。

リポジトリに最上位に `.nojekyll` を配置しておく必要がありました。

https://zenn.dev/ihasq/articles/52b525c7579c64

最終的にこのようにファイルを配置しておきます。

![スクリーンショット 2023-03-13 20.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231066/2c1d0ddd-3173-2c30-2fe6-660454893b49.png)
![スクリーンショット 2023-03-13 20.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231066/1838a22f-8ff4-057e-6f7b-edc61c03d3fb.png)

なお、この状態にしてすぐにドメインへアクセスしてもUniversal Linksは発火しません。
ここまでの作業を行った上で、数十分〜数時間程度待つ必要があります。
夜にやっておいて翌日に確認するのが確実かもしれませんね。

# AppのEntitlementの修正

あとはiOSプロジェクトのEntitlementに指定したいドメインを記載します。
指定するドメインに `?mode=developer`を付与することにより、開発用プロファイルでビルドしたAppでもUnversal Linksを使用することが出来るようになります。

```xml
  <key>com.apple.developer.associated-domains</key>
  <array>
    <string>applinks:username.github.io?mode=developer</string>
  </array>
```

参考にしたサイトはこちら

https://www.wantedly.com/companies/wantedly/post_articles/305303

# あとがき

サーバーサイドの環境が自由に変更出来ない場合でも、github.ioのみで無事Universal Linksの起動確認が出来ました。
反映待ちの時間が不定などちょっと不便さがありますが、急ぎ出ない場合などはこの方法でも十分かと思います。
大きさが不明の集合からランダムに要素を選ぶアルゴリズムReservoir sampling

要素数$n\$の配列からランダムに重複を許さずに$k\$個を選びたい場合、例えば、配列をシャッフルしてから最初の$k\$個を選ぶことで達成できます。
特に$k=1\$のときはシャッフルをせずに、ランダムに$1\$以上$n\$以下の整数を生成し（配列の添え字が1始まりの場合）、そのインデックスの要素を返すことでも達成できます。

では、要素数が不明な場合や$n\$がとても大きい場合はどうしたらいいでしょうか？
そのような場合に使えるアルゴリズムにReservoir samplingがあるので解説したいと思います。

# 参考文献

https://en.wikipedia.org/wiki/Reservoir_sampling
https://gregable.com/2007/10/reservoir-sampling.html

# Reservoir sampling

擬似コードで書くと以下のようになります。
便宜上、入力の配列`source`の要素数を$n\$としましたが、`source`の要素を逐一処理していくので$n\$が不明でも実行できます。

```
入力: 要素数nの配列sourceと、n以下の整数k
出力: 要素数kの配列result

resultにsourceの最初のk個の要素をそれぞれ代入する
iをk+1からnまで増加させながら、以下を実行する (配列の添え字が1始まりとする)
  rに1以上i以下のランダムな整数を代入する
  rがk以下ならば、result[r]にsource[i]を代入する
```

配列をシャッフルするアルゴリズム[Fisher–Yates shuffle](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%83%E3%82%B7%E3%83%A3%E3%83%BC%E2%80%93%E3%82%A4%E3%82%A7%E3%83%BC%E3%83%84%E3%81%AE%E3%82%B7%E3%83%A3%E3%83%83%E3%83%95%E3%83%AB)とよく似ているのがわかります。

Javaでの実装はこんな感じになります。長さが不明でも実装できることを明確にするためにイテレータを入力としました。

```java
public <T> List<T> reservoirSampling(Iterator<T> source, int k) {
    List<T> result = new ArrayList<>(k);

    for(int i = 0; i < k && source.hasNext(); i++) {
        result.add(source.next());
    }

    Random random = new Random();
    int i = k+1;

    while(source.hasNext()) {
        T element = source.next();
        int r = random.nextInt(i);
        if(r < k) {
            result.set(r, element);
        }
        i++;
    }

    return result;
}
```



## 具体例

`source = [A, B, C, D]`、`k = 3`を例にとります。期待する結果は、`source`から重複しない3つの要素をそれぞれ等しい確率$\frac{3}{4}\$で選ぶことです。

まず出力の配列が`result = [A, B, C]`で初期化されます。

次に乱数$1 \leqq r \leqq 4 \$を生成します。要素`D`が選ばれるのは$r \leqq k\$のとき、つまり$r=1, 2, 3\$のいずれかの場合で確率は$\frac{3}{4}\$です。
$r=4\$の場合は選ばれないことを意味し、確率は$\frac{1}{4}\$です。

このとき要素`A`が`result`に残る、つまり`A`が`D`によって上書きされない確率は以下の和事象の確率です。
- `D`が選ばれない確率$\frac{1}{4}\$
- `D`が選ばれて、`[A, B, C]`のうち`B`または`C`を上書きする確率$ \frac{3}{4} \times \frac{2}{3}\$

従って`A`が`result`に残る確率も$\frac{1}{4} + \frac{3}{4} \times \frac{2}{3} = \frac{3}{4} \$であることがわかります。

要素`B` `C`についても同様なので、`A` `B` `C` `D`のいずれもが等しい確率$\frac{3}{4}\$で選ばれることがわかります。

## 証明

$i \ge k\$とし、入力配列の$i\$番目の要素$x_i\$の次の要素$x_{i+1}\$を処理する直前の時点で、$i\$番目以下の要素$ \\{x_1, x_2, ..., x_i\\} \$のいずれもが等しい確率$ P_i = \frac{k}{i} \$で選ばれていると仮定します。

$i=k\$のとき$ P_k = 1 \$であり、アルゴリズムの定義より、入力配列の最初の$k\$個の要素が全て選ばれていることから成り立つことは明らかです。

$i=j\$のとき$ P_j = \frac{k}{j} \$が成り立つと仮定します。

$i=j+1\$のとき$P_{j+1} = \frac{k}{j+1}\$で成り立つことを示します。
まず要素$x_{j+1}\$が選ばれる確率はアルゴリズムの定義より$\frac{k}{j+1}\$です。
要素$x_{j+1}\$を処理したあと$j\$番目以下の要素$ x_l \in \\{x_1, x_2, ..., x_j\\} \$が選ばれている確率は、
(A) 要素$x_{j+1}\$を処理する前にすでに$x_l\$がすでに選ばれていて、かつ
(B) $x_l\$が$x_{j+1}\$によって上書きされない確率です。

(A)の確率は、仮定より確率$ P_j = \frac{k}{j} \$です。
(B)の確率は、$x_{j+1}\$が確率$\frac{k}{j+1}$で選ばれ、かつ$k\$個の中から$x_l\$が選ばれる事象の、余事象の確率$1 - (\frac{k}{j+1} \frac{1}{k}) = 1 - \frac{1}{j+1} = \frac{j}{j+1}\$です。

よって要素$x_l\$が選ばれる確率は(A)と(B)の積事象の確率で、これも$\frac{k}{j}\frac{j}{j+1} = \frac{k}{j+1}\$ であることがわかりました。

以上より、要素$x_{j+1}\$と$x_l\$がともに確率$\frac{k}{j+1}\$で選ばれることから$P_{j+1} = \frac{k}{j+1}\$であることがわかりました。

数学的帰納法より正しいことが示されました。
在庫管理アプリzaico使い方

@2023/03/13

# プラン

- エントリー 980/月
- スタンダード 2980/月
- ビジネス 98800/月
- エンタープライズ

# 試してみる

今回試したプラン: `31日無料お試しプラン`


## 初期設定

1. アカウント作成 (メールアドレス,パスワード,組織名等の設定)
2. プランの選択(今回はエントリーを選択)

## 在庫登録

- 左上`+新規データ追加`をクリック
- 製品名，状態，保管場所，数量，写真等の設定

追加できた
![Screenshot from 2023-03-13 20-04-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/af692006-c1c0-5f41-0f5d-bebeffc76598.png)

## 入庫

1. `在庫情報` > `在庫一覧`から入庫する製品のチェックマークをつける 

2. `入庫登録`をクリック.個数，単価を記入してすすむ

3. 状態`入庫前`をクリック,`入庫済み`にへんこう

## 出庫

1. `在庫情報` > `在庫一覧`から入庫する製品のチェックマークをつける 

2. `出庫登録`をクリック.

## 取引先追加

` データ管理` > `新しい取引先の追加`

## 一括出庫
何か製品用に出庫したい時,きまった材料が複数ある.一括で出庫できたら楽.

- やり方

1. csv形式のファイルを作成

```
番号,物品名,取引先名,出庫数量,納品単価,状態,QRコード・バーコードの値,摘要・備考,出庫予定日,出庫日
100,テレビ,A社,1,100,出庫前,tw201812141120306229184,備考は特になし,2019/1/1,
100,掃除機,A社,1,100,出庫済み,tw201901111622299698940,,,2019/4/1
200,掃除機,A社,10,100,出庫済み,tw201901111622299698940,,2019/2/10,2019/2/10
```

この中で必須なものは以下．詳細は参考urlから.

![Screenshot from 2023-03-13 21-05-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/c76275ca-1027-e97b-3777-13196c93f5ba.png)

![Screenshot from 2023-03-13 20-53-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/a61311c9-7047-e2dd-3d7b-503d481b4ed2.png)

(Q&A)
番号って何? --- 
状態って何? --- 

2. csvファイルのアップロード

![Screenshot from 2023-03-13 21-00-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/bea88f54-f6cf-5a6a-6757-0b5e84dc535a.png)

![Screenshot from 2023-03-13 21-00-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589906/cd566805-cd68-ce84-4ae5-1d3ec9bae22b.png)



※ ネットショップ「BASE」「STOERES」の注文情報csvファイルもアップロードできる
!

(一括出庫: 参考)
https://support.zaico.co.jp/hc/ja/articles/4406630218137--WEB-CSV%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E5%87%BA%E5%BA%AB%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E4%B8%80%E6%8B%AC%E7%99%BB%E9%8C%B2%E3%81%99%E3%82%8B-%E5%87%BA%E5%BA%AB%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88-
Lazy修飾子についてまとめた結果

## Lazyとは
- Lazy Stored Proparty(遅延格納プロパティ)が正しい名称。
- 初期化を遅延させることによって不要なメモリー消費の回避、パフォーマンスの低下を抑えることができる。
- lazyという修飾子を使用することで最初に利用されるまで`初期化処理を走らせない`ようにする。
  - 一度初期化処理が走ると、値がメモリに保存されるため、再度処理は走らない。
    - ただし、マルチスレッドで同時にアクセスされたとき（初期化処理が終わる前に同時アクセスなど）、２回目も呼ばれてしまう（意図しない処理）可能性もあるため注意が必要。


## 使用例
- 初期値がインスタンス生成後の状態に依存している。
    - インスタンスを生成した後の状態によって初期値を変えたい（的な）。
- 初期化にコストがかかり、且つ、使われるまで初期化する必要がないとき。
    - 初期化時に値を与えず、必要とされた時に初めて値を決定することができる。

## コード
```swift:Swift
//Calenderクラスの初期化
class Calender {
    private lazy var formatter: DateFormatter = {
        print("カレンダークラス（formatter）が呼ばれたよ")
        let formatter = DateFormatter()
        formatter.dateStyle = .short
        formatter.locale = Locale.init(identifier: "ja_JP")
        return formatter
    }()
    
    var today: String {
        print("カレンダークラス（today）が呼ばれたよ")
        //todayプロパティ経由で呼び出すformatterプロパティ
        return formatter.string(from: Date())
    }
}
//lazyを付けているため、Calenderインスタンスを生成した時点（初期化時）ではformatterプロパティは呼ばれない
let c = Calender() //Calenderの中はLazyで初期値を与えることを遅延させているためnil
```
![スクリーンショット 2023-03-13 16.49.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2915639/ef234f4b-9147-4bf6-713e-6ea78e359417.png)
```swift:Swift
//しかし、todayプロパティ経由でformatterに初めてアクセスした時点で初期化処理が始まる
c.today
//カレンダークラス（today）が呼ばれたよ
//カレンダークラス（formatter）が呼ばれたよ

//二回目を呼んでみる
c.today //カレンダークラス（today）が呼ばれたよ >>> formatterは一度しか呼ばれない
//なぜなら、一度初期化処理が走ると値がメモリに保存されるため、再度処理は走らない
```

## おわりに
誤り等ございましたらコメント欄にてご指摘ください。

## 参考記事
[【Swift】Lazyプロパティの使い方に気をつける(ドキュメントの確認は大事)](https://qiita.com/shiz/items/782979bd8a539c9d2291)

[lazy stored property (遅延格納型プロパティ)とは？-Swiftを理解する](https://shuhey-hashimoto.com/swift/lazy-stored-property%E3%81%A8%E3%81%AF-swift%E3%82%92%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B/)

[[増補改訂第3版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plusシリーズ)　](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-Swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E7%9B%B4%E6%84%9F%E7%9A%84%E3%81%AA%E6%96%87%E6%B3%95%E3%81%A8%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E5%85%BC%E3%81%AD%E5%82%99%E3%81%88%E3%81%9F%E8%A8%80%E8%AA%9E-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4297112132)
↑引用元
石川 洋資 (著), 西山 勇世 (著)
発行者：片岡 巌
出版社：技術評論社
印刷/製本：日経印刷株式会社

## 開発環境
- Xcode-13.4.1
- Swift version 5.7
ping で linux kernel の capabilities の実験を成功させるためのメモ

数年前の書籍で linux kernel の capabilities(7) の実験で ping を使ったサンプルが載ってたんですが、手元の centos stream 8 で試したらそのとおりにならなくて調べたメモです。

## 結論

- `net.ipv4.ping_group_range` でping可能なグループID範囲を設定していて、この範囲が広いと `CAP_NET_RAW` や `setuid` 無しで実行できるようになってる。
- 少なくとも手元の centos stream 8 や ubuntu 20 では `0   2147483647` となっているため、capabilities なしでも一般ユーザで ping できる。
- もし `CAP_NET_RAW` や `setuid`が必要な状況を再現したければ `sudo sysctl -w net.ipv4.ping_group_range="1 0"` する。

```
[centos stream 8 のデフォルト]
$ uname -r
4.18.0-448.el8.x86_64

$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0   2147483647

[ubuntu 20.04 LTS のデフォルト]
$ uname -r
5.4.0-144-generic

$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0   2147483647
```

## 実験例

実際に centos stream 8 上で試した例です。

```
## (1) 現在の net.ipv4.ping_group_range を確認
$ sysctl net.ipv4.ping_group_range
net.ipv4.ping_group_range = 0   2147483647

## (2) kernel document でも記載している通り ICMP_PROTO を作れなくする "1 0" に変更
$ sudo sysctl -w net.ipv4.ping_group_range="1 0"
net.ipv4.ping_group_range = 1 0

## (3) /bin/ping を ./myping にコピーし、root所有にして setuid もする。
$ cp /bin/ping ./myping
$ sudo chown root ./myping
$ sudo chmod +s ./myping
$ ./myping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.157 ms
...
(root +s なら動く模様)

## (4) ./myping を一般ユーザ権限に戻す。
$ cp /bin/ping ./myping
$ ./myping 10.0.2.2
ping: socket: Operation not permitted

## (5) setcap(8) で CAP_NET_RAW を許可 -> ping 成功
$ sudo setcap cap_net_raw=ep ./myping
$ getcap ./myping
./myping cap_net_raw=ep
$ ./myping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.094 ms
(...)
(-> 一般ユーザ権限で動作していることを ps euf で別セッションから確認済み)

## (6) net.ipv4.ping_group_range の設定値を復元
$ sudo sysctl -w net.ipv4.ping_group_range="0   2147483647"
net.ipv4.ping_group_range = 0   2147483647
```

## 参考資料

linux kernel の capabilities(7) について:

- `第42回　Linuxカーネルのケーパビリティ［1］ | gihyo.jp`
  - https://gihyo.jp/admin/serial/01/linux_containers/0042
- `capabilities(7) - Linux manual page`
  - https://man7.org/linux/man-pages/man7/capabilities.7.html
- `いますぐ実践! Linuxシステム管理 / Vol.183`
  - https://www.usupi.org/sysad/183.html

ping の capabilities について:

- `ping を実行するのに CAP_NET_RAW は必要なくなっていた`
  - https://blog.ssrf.in/post/ping-does-not-require-cap-net-raw-capability/
- `ICMP sockets - TenForward`
  - https://tenforward.hatenablog.com/entry/2019/11/27/022547
- `Changes/EnableSysctlPingGroupRange - Fedora Project Wiki`
  - https://fedoraproject.org/wiki/Changes/EnableSysctlPingGroupRange
- `https://github.com/torvalds/linux/blob/3cb12d27ff655e57e8efe3486dca2a22f4e30578/Documentation/networking/ip-sysctl.rst
自動テストのmysql TooManyConnectionsエラーを解消する

## エラー事象

業務のソースコードはgitにpushすると自動でテストコードが実行される
ローカル環境でテストコードを実行したときは成功したのに自動テストでは `TooManyConnections` エラーが発生してしまうことがあった

利用技術は以下の通り

* kotlin + SpringBoot
* mysql

## これで解決

テストコード実行時に参照されるapplication.ymlを作成して最大コネクション数を設定すればOK

```yaml:src/test/resources/application.yml
spring:
  datasource:
    mysql:
      maximum-pool-size: 1
```
0からはじめるPython ~ポアソン到着モデルによる待ち時間のシミュレーション~

# はじめに


こんにちは、現在0からPythonを学んでいる初心者エンジニアです。
この投稿は私が学んだことのアウトプットの場として、そして私と同じ初心者エンジニアさんの少しでも役に立てればと思い、投稿しています。私自身も全くの初心者なので、感想やアドバイスあれば、気軽にコメント頂けると幸いです。

# ポアソン到着モデルとは
今回はポアソン到着モデルによる待ち時間シミュレーションに関して解説したいと思います。

ポアソン到着モデルとは待ち行列理論における待ち行列シミュレーションモデルのひとつで、待ち行列理論とはシステムにおける待ち行列を数学的に分析するための理論であり、待ち行列とは複数の要求や仕事が処理されるために待機している状態を表すモデルです。具体的には、コールセンターでの電話や、カフェの注文、工場の製品などが挙げられます。

ではこの待ち行列をどう数学的に表すのか、待ち行列シミュレーションモデルの1つにポアソン分布を用いた今回解説する**ポアソン到着モデル**があります。

ポアソン到着モデルとはお客さんの到着時間に、統計的性質である定常性、独立性、希少性が成り立つものと考え、到着の様子をポアソン分布で表現する方法である。ポアソン分布の説明に関しては[こちらの記事](https://qiita.com/0karaPython/items/d6d1edfbbf045f64b4bb)を参考にして頂きたいです。

ある一定の$t$時間あたりに到着するお客さんの数がポアソン分布に従う時、
```math
P(k)=e^{-\lambda t}\frac{(\lambda t)^k}{k!} \tag{1}
```
と表すことができ、ここでkは到着するお客さんの数、$\lambda[{人} / s]$は平均到着率（t時間あたりに到着するお客さんの数の平均値)で、要するにこの式は「t時間以内にk人のお客さんが到着する確率」を表します。この到着のことを**ポアソン到着**といいます。

例えば、単位時間（t=1）あたり平均5人（$\lambda$=5）のお客さんが来るお店で、７人（k=7）のお客さんが来る確率は
```math
P(7)=e^{-5}\frac{5^7}{7!}\approx 0.104 \tag{2}

```
となります。

# 到着時間の分布

実際に、到着時刻はどのような分布に従うかを考えます。
結論から言うと、ポアソン到着の時、お客さんの到着時間の間隔は指数分布に従います。
こちらがその証明です。

**証明**
時間間隔Tの間に事象が一回も起きない（1人もお客さんが到着しない）確率は
```math
P(0)=e^{-\lambda T} \tag{3}
```
であり、従って、事象が起きる時間間隔がT以下(あるお客さんが到着してからT時間以内で次のお客さんが到着する)の確率は余事象を使い
```math
P(k\geq1)=1-p(0)=1-e^{-\lambda T} \tag{4}
```
となり、(4)を微分すると
```math
\left(1-e^{-\lambda T}\right)'=\lambda e^{-\lambda T} \tag{5}
```
となります。これは指数分布の確率密度関数の一種であるため、ポアソン到着の時、お客さんの到着時間は指数分布に従うことがわかります。

# ポアソン到着モデルによる待ち行列のシミュレーション

シミュレーションを行うにあたって、確率変数であるTを発生させたい場合(4)の式をTに関して解いて
```math
T=-\frac{1}{\lambda}\log \left(1-P(k\geq1)\right) \tag{6}
```
となることがわかります。
今回は(6)の式中 $P(k\geq1)$に一様乱数 $U(0,1)$を与えることでTを生成し、50人分のお客さんの到着時刻をシミュレーションするコードを示します。($\lambda$=1とする)


```python
import numpy as np  # ベクトル演算などに用いる
import matplotlib.pyplot  as plt  # グラフの生成に用いる
from scipy.stats import uniform  # 一様分布を用いるため

N=50  # 人数を入力
arrive=np.zeros(N)  # 値が0の要素をN個持つ配列を定義（求めた値を保存する場所を用意）
lamb=1  # lambdaの値を入力

sum=0  # 今後使う関数の初期値を定義
for i in range(N):  # 0からN-1までiをループさせる
    sum-=(1/lamb)*np.log(1-uniform.rvs(size=1))  # (6)の式を用いて到着時刻をを計算
    arrive[i]=sum  # 到着時刻を配列に入力

fig,ax=plt.subplots(figsize=(8,5))  # 表示するグラフのサイズを指定
ax.vlines(arrive,ymin=0,ymax=1)  # 到着時刻に縦線を引く
plt.xlabel('time')  # x軸のラベルにtimeと表示
plt.show()  # グラフを表示
```
そして実行結果が
![スクリーンショット 2023-03-13 18.48.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3249825/4eff00d7-ee48-88f5-e486-9cd63a51b506.png)
となり、50人分のお客さんの到着時刻をシミュレーションすることができました。

# 待ち行列理論の目的

最初にも少し触れましたが、このポアソン到着モデルを用いた待ち行列理論をどのようなことに利用しているかを紹介したいと思います。
まず代表的な例が銀行などの窓口の数です。お客さんの待つ時間が大きくなることはサービスとして良くないですが、窓口の数を増やしすぎても余計に人件費などがかかってしまいます。このような問題の解決方法として、窓口の数を効率的にするために、待ち行列理論が使われています。
上の例以外にも会社などで快適にネットワークが使えるようになるためのサーバ数を決めたりなど様々な場面で使われている待ち行列理論に皆様も興味を持っていただけたでしょうか？

# まとめ
以上が、ポアソン到着モデルによる待ち時間シミュレーションに関しての解説になります。
最後まで読んで頂きありがとうございました。引き続き私と一緒に研鑽していきましょう。

# 参考
橋本洋志,牧野浩二."データサイエンス教本 Pythonで学ぶ統計分析・パターン認識・深層学習・信号処理・時系列データ分析".オーム社,2018
[ポアソン過程の到着間隔～指数分布](http://taustation.com/poisson-process-exponential-distribution/)
[0からはじめるPython ~ポアソン分布とは~](https://qiita.com/0karaPython/items/d6d1edfbbf045f64b4bb)
pythonでコーディング問題を解く6


https://qiita.com/tosei/items/27adb9886fce0b6b228e

続き

### 問題1 050 - Stair Jump

https://atcoder.jp/contests/typical90/tasks/typical90_ax

```
stairs, steps = list(map(int, input().split(' ')))

# 0段目から移動するパターンもあるため、階数+1で初期化する必要がある
patterns = [0] * (stairs + 1)

for i in range(len(patterns)) :
    # 0段目は必ず1
    if i == 0 :
        patterns[i] = 1
    # stepsより小さい段数は1段ずつ上っていく以外に到達方法がないので1になる
    elif i < steps :
        patterns[i] = patterns[i - 1]
    # steps以上の場合
    # 1段前から1段上るか、steps数段前からsteps段登るかの2パターンがある
    # つまり、1段前に到達する方法と、steps数段前に到達する方法の合計が、今の段に到達する方法になる
    else :
        patterns[i] = patterns[i - 1] + patterns[i - steps]
        
print(patterns)
```

### 問題2 C - Typical Stairs

https://atcoder.jp/contests/abc129/tasks/abc129_c

```
stairs, broken_stairs_count = list(map(int, input().split(' ')))

patterns = [1] * (stairs + 1)
broken_stairs = []
MOD = 1000000007

for i in range(broken_stairs_count) :
    broken_stairs.append(int(input()))
    
print (broken_stairs)

# 1段目が壊れている場合、1段目に到達する方法は0
patterns[1] = 0 if 1 in broken_stairs else 1

# 2段目以降は、
# 壊れていなければ、ひとつ前と二つ前の段に到達する方法の合計
# 壊れていれば、その段に到達する方法は0
for i in range(2, len(patterns)) :
    if i in broken_stairs :
        patterns[i] = 0
    else:
        patterns[i] = patterns[i - 1] + patterns[i - 2]

print(patterns[-1] % MOD)
```
pythonでコーディング問題を解く5

https://qiita.com/tosei/items/58e56b9c7dd587468f34
続き

動的計画法で気になった問題を解いてみた

### 問題1

A Frog1

https://atcoder.jp/contests/dp/tasks/dp_a

```
import numpy

count = int(input())
# スペースで区切ってint型のmapにする
# mapの戻り値は配列ではないので、listで配列に変換する
heights = list(map(int, input().split(' ')))
dp = list(numpy.full(count, 0))

# 一番最初の隣の柱に移動した時点では、必ず|2番目 - 1番目|がスコアになる
dp[1] = abs(heights[1] - heights[0])

# 2番目以降は、一つ前から移動した場合と、二つ前から移動した場合のスコアを比較し、小さいほうを設定するのを最後まで繰り返す
for cur in range(2, len(dp)) :
    dp[cur] = min(dp[cur - 1] + abs(heights[cur] - heights[cur - 1]), dp[cur - 2] + abs(heights[cur] - heights[cur - 2]))
    
print(dp)
```


### 問題2

B Frog2

https://atcoder.jp/contests/dp/tasks/dp_b

```
import numpy

count, maxStep = map(int, input().split(' '))
heights = list(map(int, input().split(' ')))
dp = list(numpy.full(count, 0))

dp[1] = abs(heights[1] - heights[0])

for cur in range(2, count) :
    # 一段前から上ったときの合計値をdpにセットする
    dp[cur] = dp[cur - 1] + abs(heights[cur] - heights[cur - 1])
    
    # 2段以上前から登った時の合計値をdp[cur]と比較し、小さいほうで更新する
    # rangeは(x, y)としたとき、x<=val<yなので、maxStep+1とする
    for step in range(2, maxStep + 1) :
        # maxStepが現在地点よりも大きい場合、マイナスになりアクセス違反が起きるのを防ぐため
        if cur - step >= 0:
            dp[cur] = min(abs(heights[cur] - heights[cur - step]) + dp[cur - step], dp[cur])
    
print(dp)
```
Stimulus 公式ハンドブックの次に読むものは?

(この記事はあくまで私の主観です。)

Stimulusの公式ドキュメントはそれなりに充実しています。

しかし今のところStimulusの起源(origin)や挙動(reference)に関する記述がありますが設計についての実践的なところはあまり記述されていません。

あなたが次に読む最適なものは何でしょう？

## 信頼できるのは作者だけ

いろんなリソースにたどり着くかもしれません。 

Better StimulusJS? Hotwire Discussion? Qiita?

しかし私が本当におすすめしたいのは、作者である37signals(旧Basecamp社)がどのようにこのStimulusを使ってるかを観察することです。

37signalsはBasecampというプロジェクトマネジメントツールやheyと呼ばれるメールサービスをリリースしています。

そしてそれらのプロダクトはStimulusで動いています。

それらがStimulusを学習する上で最も素晴らしい学習リソースだと私は信じています。

ソースをのぞき見ることに背徳感がありますか？

安心してください、DHHはこう言っています。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">No need to whisper. Steal whatever Stimulus controllers you please from <a href="https://twitter.com/heyhey?ref_src=twsrc%5Etfw">@heyhey</a> ✌️. We ship source maps for all of it. Hope to turn most of the generic ones into a Stimulus stdlib at some point too. <a href="https://t.co/EZxA0j9gK2">https://t.co/EZxA0j9gK2</a></p>&mdash; DHH (@dhh) <a href="https://twitter.com/dhh/status/1334933646806028288?ref_src=twsrc%5Etfw">December 4, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

heyのソースを読んでコントローラを拝借してるといった人に対するDHHのコメントです。

「小声でそれをいう必要はない。heyから好きなコントローラをもっていってくれ。 sourcemap付きで出してるよ！」という具合です。

過去のツイートや記事を読むと

「OSSによって育てられた私はJavaScriptを難読化するようなことはしない。　プロダクション環境でもsource mapsをつけて輸出する」 的なことも言ってます。

https://m.signalvnoise.com/paying-tribute-to-the-web-with-view-source/

心が洗われますね。

Stimulusのコミッターは37signalsの中の人であれ外の人であれ大概heyのコードを読んでるっぽい発言をちょいちょいしてます。

## heyのソースを読む

できることならheyサービスに課金してあげるとよいのですが、アカウントを持っていなくてもログイン画面からソースは読めます。

https://app.hey.com/sign_in

見るべき場所はproduction.hay-stack-assets.com/assets/controllersの中です。

![devtoolsのsourcesパネル production.hay-stack-assets.com/assets/controllersの中にコントローラが列挙されている。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12806/aa23754b-e842-c5b7-c1e7-9c0c8e16df71.png)

以前はbundleされてたのでどのページでも全てのコントローラが読めましたがRails7がリリースされ、stimulus-autoloaderができたタイミング(厳密には少し後)にbundle運用が終わったため、ページで必要な分だけの読み込みになっており少し少ないです。

もっと読みたい方は課金してログイン後のページのソースを読みましょう。(一応メニューのTry it Freeから無料でお試しアカウントをつくることもできますが)

このページから読めるコードで最もアツいコードはfocus-trapコントローラでしょうか。

これはモーダルダイアログなど、独立したタブシーケンスを持つようなUIを構築する時によく使うものになります。

dialog要素を使えば同等のことがネイティブでできますが、ios15系をサポートするなどの制約がある場合はこの辺の実装を自前で行う必要があり、そういった時にこのコードを参考、拝借することができます。

こういったコードを読みながらコントローラの粒度・設計のあり方を学ぶことができます。

他のJavaScriptライブラリを使ってきた方はコントローラをUI単位で書いてしまうことが多いと思います。

heyのコードから読み解けるコントローラの単位はUIではなく"振る舞い"です。

表示と振る舞いを切り離すことで再利用性を高めるというノウハウをここから学ぶことができます。


## まだハンドブックを読んでません。

もしあなたがまだハンドブックを読んでいないのであればまずはThe Origin of Stimulusを読みましょう。

37signalsがなぜStimulusを作ったのか。何を実現したかったのかが記述されています。

これを理解した上で読み進めるといろんなことがすんなり受け入れられるようになるんじゃないかと思います。

https://stimulus.hotwired.dev/handbook/origin

また同じく背景を説明した記事に拙作ですが妄想的DHH理解というのもあります。よければご参照ください。

https://qiita.com/nazomikan/items/eab3352dbd5e2b79724b