OmniAICreator/Qiita-1.07M huggingface dataset:
ダルビッシュ選手(2021年)の投球データ

引き続き、前回、[pybaseball / MLBデータ分析ライブラリ](https://hide.ac/articles/-JZTuB_RS) にて、MLBの触れるデータを確認した。

今回は、ダルビッシュ選手(2021年)のデータを見ていった。2022年はまた今度。

***

# 2021データ

## 投球内訳

| variey of pitches | Description     |
| ----------------- | --------------- |
| FC                | cutter          |\
| SL                | slider          |\
| FF                | 4-seam fastball |\
| SI                | sinker          |\
| FS                | splitter        |\
| CU                | curveball       |\
| KC                | knuckle curve   |\
| CH                | changeup        |\
| CS                | screwball       |

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

## 月べつ投球内訳

9月は投球パターンがガッツリ変わってたんですね。カッターとファーストボールの見分けが難しかった可能性もあるが。

![](https://pbs.twimg.com/media/FmCKwY2aMAE_Z3K?format=jpg\&name=large)

![](https://pbs.twimg.com/media/FmCLY5KakAIreBx?format=jpg\&name=large)

***

## 球種ごとの球速、スピンレート(平均値mean、バラツキstd)

*   mean_release_speed<br>球速マイル 平均値
*   std_release_speed<br>球速マイル バラツキ
*   mean_spin_rate<br>スピンレート 平均値
*   std_spin_rate<br>スピンレート バラツキ

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

***

## 全体との比較

### 4-seam fastball

*   球速マイル<br>全体の平均くらい。先発なので不利な部分はある
    ![](https://pbs.twimg.com/media/FmCR7tqakAUv76p?format=png\&name=small)

*   スピンレート<br>全体の平均より高い
    ![](https://pbs.twimg.com/media/FmCTC1BaMAAoqDO?format=png\&name=small)

### cutter

*   球速マイル<br>全体の平均くらい。これも先発なので多少不利な部分はあると思う
    ![](https://pbs.twimg.com/media/FmCVxr-akAMHS8n?format=png\&name=small)

*   スピンレート<br>全体で上のほう
    ![](https://pbs.twimg.com/media/FmCdsM1agAAZOH-?format=png\&name=small)

### slider

*   球速マイル

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

*   スピンレート<br>全体より高い回転

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

### sinker

*   球速マイル

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

*   スピンレート

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

### splitter

*   球速マイル<br>スプリットの球速速いほうなんですね

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

*   スピンレート

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

### curveball

*   球速マイル<br>スローカーブ

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

*   スピンレート

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

### knuckle curve

*   球速マイル<br>ナックルカーブも集計されてるのか。スライダーとの見分け難しそう

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

*   スピンレート

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

***

2020、2022年の結果もまとめて、最終的に年度別での比較も出来るようになれるといいな。

という感じ。

# コード

コードはこちらに一部書いてます。<br><https://hide.ac/articles/W56GzplRT>
大谷選手(2021年)の打撃データ / 打球方向&コースごと

引き続き、[pybaseball / MLBデータ分析ライブラリ](https://hide.ac/articles/-JZTuB_RS) にて、MLBの触れるデータを確認した。

今回は、大谷選手(2021年)の打撃データを見ていった。2022年はまた今度。

打撃データと言っても、打球方向、どのコースを打ったのかをざっくりとだけ。

<pre><code>!pip install pybaseball
from pybaseball import statcast
df = statcast(start_dt='2021-04-01', end_dt='2021-12-31')
df_ohtani = df[df['batter'] == 660271]</code></pre>

> 参考:大谷さんのID → <https://baseballsavant.mlb.com/savant-player/shohei-ohtani-660271>

***

# 2021 大谷選手 打撃データ

## <font color="blue">ホームラン方向</font>

<div style="display:inline-block; border-radius:10px 10px 0 0; padding: 8px 24px; color:#fff; font-weight:bold;
background-color:#0066ff; /*背景色を指定*/">
ホームラン方向
</div>
<div style="margin-bottom:30px; padding:20px; border-radius:0 0 10px 10px;
border: solid 4px #0066ff; /*枠の色を指定*/">
全選手のホームランがグレー<br>大谷選手が<font color="red">赤</font>

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

※ フェア線は、いったんざっくり引いてみました</div>

## <font color="green">全部の打球</font>

<div style="display:inline-block; border-radius:10px 10px 0 0; padding: 8px 24px; color:#fff; font-weight:bold;
background-color:#008000; /*背景色を指定*/">
全部の打球
</div>
<div style="margin-bottom:30px; padding:20px; border-radius:0 0 10px 10px;
border: solid 4px #008000; /*枠の色を指定*/">
全選手がグレー<br>大谷選手が<font color="red">赤</font>

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

これだと非常に見づらいですが、1-2塁の間に何か密集していることは確認できます。

</div>

## <font color="red">大谷選手の打球内訳</font>

<div style="display:inline-block; border-radius:10px 10px 0 0; padding: 8px 24px; color:#fff; font-weight:bold;
background-color:#ff0000; /*背景色を指定*/">
打球内訳
</div>
<div style="margin-bottom:30px; padding:20px; border-radius:0 0 10px 10px;
border: solid 4px #ff0000; /*枠の色を指定*/">

ホームラン、1塁打、2塁打、3塁打、その他を凡打としてplotしました。

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

凡打が1-2塁の間に多いことが分かります。打球がそこに多いと言うのと、1-2塁を閉めている大谷シフトの影響かと思います。

あと、ファールフライがほとんどない。超一流はさすが違う。

</div>

## <font color="emerald">投球コースでの結果</font>

<div style="display:inline-block; border-radius:10px 10px 0 0; padding: 8px 24px; color:#fff; font-weight:bold;
background-color:#ff00ff; /*背景色を指定*/">
投球コースでの結果
</div>
<div style="margin-bottom:30px; padding:20px; border-radius:0 0 10px 10px;
border: solid 4px #ff00ff; /*枠の色を指定*/">

キャッチャー側から見た投球コースをplot<br>hit by pitch → デッドボール なのでそこからもキャッチャー側からの視点と判断できると思います。

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

アウトコースの高め、低めが比較的苦手なほうなんですね。

※ストライクゾーンを表示しなくてすいません

</div>

## 参考 : ストライクゾーン

以下はストライクとコールされた投球をplotしたもの

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

***

# コード

メモとして<br><https://hide.ac/articles/jLMEJJJ8L>
【JetpackCompose】Canvasで作った円形の背景にグラデーションを設定する方法

前回は通常の画面の背景にグラデーションを設定しましたが、今回は円形の背景にグラデーションを設定してみようと思います。

```CircleGradation.kt
@Composable
fun CircleGradation() {
    Canvas(
        modifier = Modifier.size(80.dp),
        onDraw = {
            drawCircle(
                Brush.verticalGradient(
                    listOf(
                        Color.Blue,
                        Color.White
                    )
                )
            )
        }
    )
}
```

前回と同じく`Brush`を作成して`drawCircle`設定します。

![スクリーンショット 2023-03-05 12.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/b5e2e031-4556-0949-e019-74a98a3e5b33.png)

こんな感じになりました。
サイズやカラーは自由に変更してください！
Spring WebfluxでCORS無効化

# version
SpringBoot 3.0.3
## 依存
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
```
# 実装
```java
    @Bean
    CorsWebFilter corsWebFilter() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.setAllowedOrigins(List.of("*"));
        corsConfig.addAllowedMethod("*");
        corsConfig.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source =
                new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);

        return new CorsWebFilter(source);
    }
    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http
                .cors()
                ;
        return http.build();
    }
```

なぜか、`cors().disable()`が効かない。
（PostgreSQL）実務でよく使うSQLコピペシート

SQLの書き方が覚えられない自分用にコピペシートを作成しました。
随時更新していく。

# SELECT文
```SQL:オプション全部載せver
SELECT
  別名1.カラム名1, 別名1.カラム名2, 別名2.カラム名1, ...
FROM
  テーブル名1 AS 別名1
  LEFT JOIN テーブル名2 AS 別名2
    ON 別名1.カラム名 = 別名2.カラム名
WHERE
  条件式
  AND 条件式
  OR 条件式
ORDER BY
  カラム名 ASC または DESC
LIMIT
  返す行数の限度
OFFSET
  返す行の開始位置
;
```
## 基本構文
```SQL
SELECT カラム名 FROM テーブル名;
```

## テーブル結合 JOIN
[（PostgreSQL）JOINのLEFT・RIGHT・INNERの結果早見表](https://qiita.com/class_kouta/items/4054589bc0fb9c68c36e)

## 別名 AS
- 「AS」は省略可能
```sql:「AS」省略ver
FROM
  テーブル名1 別名1
  LEFT JOIN テーブル名2 別名2
    ON 別名1.カラム名 = 別名2.カラム名
```

カラムを選択する際に、「テーブル名（別名）.」を付けなくてもSELECTできるが、同一のカラム名が存在する場合にエラーになるため、付けた方がよい

```SQL:エラーケース
-- productテーブル
 id |   name    | price |  description  |         created_at         |         updated_at         
----+-----------+-------+---------------+----------------------------+----------------------------
  1 | product1  |  1000 | description1  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303
  2 | product2  |  2000 | description2  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303
  3 | product3  |  3000 | description3  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303

-- salesテーブル
 id |   name    | price |  description  |         created_at         |         updated_at         
----+-----------+-------+---------------+----------------------------+----------------------------
  1 | product1  |  1000 | description1  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303
  2 | product2  |  2000 | description2  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303
  3 | product3  |  3000 | description3  | 2023-03-05 11:14:59.348303 | 2023-03-05 11:14:59.348303

-- SQL発行
SELECT
  id, name, description -- id がどちらのテーブルにも存在
FROM
  product AS p
  LEFT JOIN sales AS s
    ON p.id = s.product_id;

-- 実行結果
-- ERROR: column reference "id" is ambiguous 

```

## 並び替え ORDER BY
- ASC
昇順（1,2,3,...100）
デフォルト値。「ORDER BY」記述しないと自動的に昇順になる。

- DESC
降順（100,99,98,...1）
新しい順で表示したい時に使うことが多い


# INSERT文
```SQL:１行挿入
INSERT INTO テーブル名 (カラム名1, カラム名2, カラム名3, ... ) VALUES (値1, 値2, 値3, ... );
```
```SQL:複数行挿入
INSERT INTO テーブル名 (カラム名1, カラム名2, カラム名3, ... ) VALUES
(値1-1, 値1-2, 値1-3, ... ),
(値2-1, 値2-2, 値2-3, ... ),
(値3-1, 値3-2, 値3-3, ... ),
(値4-1, 値4-2, 値4-3, ... );
```
# UPDATE文
```SQL
UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2, ... WHERE 条件式 ;
```

# DELETE文
```sql:全行削除
DELETE FROM テーブル名;
```
```SQL:該当行のみ削除
DELETE FROM テーブル名 WHERE カラム名 = '値';
```


# CREATE TABLE
```SQL
CREATE TABLE teble_name (
    -- カラム名 データ型
    id SERIAL,

    -- 外部キー カスケード
    column_name TEXT NOT NULL REFERENCES teble_name (column_name) ON DELETE CASCADE,

    -- デフォルト値設定
    column_name BOOLEAN NOT NULL DEFAULT false,

    -- タイムスタンプ
    created_at TIMESTAMP DEFAULT now(),
    updated_at TIMESTAMP DEFAULT now(),

    -- プライマリーキー
    PRIMARY KEY (id)
);
```

# カラム追加・削除・変更
```sql
-- 追加
ALTER TABLE テーブル名 ADD COLUMN カラム名 データ型;

-- 削除
ALTER TABLE テーブル名 DROP COLUMN カラム名;

-- 変更
ALTER TABLE テーブル名 ALTER COLUMN カラム名 TYPE データ型
```
railsで、レコードが削除されたときに、リレーションしているレコードも一緒に消えるように書くにはどうすれば良い？

（chatGPTの返答メモ）

Railsでは、Active Recordの便利な機能を使って、親レコードが削除されたときに関連する子レコードを自動的に削除することができます。これは、「dependent: :destroy」というオプションを使用して実現できます。

例えば、親モデル Parent と子モデル Child がある場合、以下のように has_many を使って関連付けを行うと、dependent: :destroy オプションを使用して、Parent が削除された場合に、関連するすべての Child も自動的に削除されるようにできます。

```ruby
Copy code
class Parent < ApplicationRecord
  has_many :children, dependent: :destroy
end

class Child < ApplicationRecord
  belongs_to :parent
end
```
dependent: :destroy オプションを指定することで、関連する子レコードを自動的に削除することができます。また、dependent オプションには、delete_all や nullify などの他のオプションもあります。これらは、関連する子レコードを削除するか、または単に親レコードとの関連を削除するかを制御するために使用されます。
ICPの現在価格をLINEヘ送信(GAS)

自分の備忘録シリーズ

# ICPの現在価格(USD建て、JPY建て)を取得し、Lineに送る

必要なAPI

*   coinmarketcap API<br><https://coinmarketcap.com/api/>

*   Line notify<br><https://notify-bot.line.me/ja/>

***

# GASで実施

*   GAS<br><https://script.google.com/home>

GAS は Google Apps Script の略です。Google Apps Script は、Google のサービス (Google Spreadsheet, Google Form, Gmail, Google Drive, Google Calendar, etc.) で簡単なスクリプトを作成、実行、共有することができるプラットフォームです。JavaScript 言語を使用して、Web アプリケーションを開発することもできます。Google Apps Script により、Google のサービスを統合することができ、効率的なワークフローを作成することができます。　※ChatGPTより

## 価格を取得

このスクリプトは、API キーを使用して CoinMarketCap の API から特定の暗号資産 (ICP) の現在の価格を取得し、その価格を米ドルと日本円で表示するもの

<pre><code>var API_KEY = "ここはCoinMarketCapで取得したAPIを書く";

function getCryptoPrice() {
  var responseJPY = UrlFetchApp.fetch("https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ICP&convert=JPY&CMC_PRO_API_KEY=" + API_KEY);
  var jsonJPY = JSON.parse(responseJPY.getContentText());
  var price_jpy = jsonJPY.data.ICP.quote.JPY.price;

  var responseUSD = UrlFetchApp.fetch("https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ICP&convert=USD&CMC_PRO_API_KEY=" + API_KEY);
  var jsonUSD = JSON.parse(responseUSD.getContentText());
  var price_usd = jsonUSD.data.ICP.quote.USD.price;

  Logger.log("Price in USD: " + price_usd);
  Logger.log("Price in JPY: " + price_jpy);
}
</code></pre>

結果を出力

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

***

## Lineに送る

このスクリプトは、CryptoCurrency APIから指定の暗号資産（この場合、ICP）の価格を取得し、その価格をLine Notifyに通知するものです。APIキーとLine Notifyのアクセストークンが必要なことに注意

<pre><code>var API_KEY = "ここはCoinMarketCapで取得したAPIを書く";
var LINE_NOTIFY_ACCESS_TOKEN = "your_line_notify_access_token";

function getCryptoPrice() {
  var responseJPY = UrlFetchApp.fetch("https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ICP&convert=JPY&CMC_PRO_API_KEY=" + API_KEY);
  var jsonJPY = JSON.parse(responseJPY.getContentText());
  var price_jpy = jsonJPY.data.ICP.quote.JPY.price;

  var responseUSD = UrlFetchApp.fetch("https://pro-api.coinmarketcap.com/v1/cryptocurrency/quotes/latest?symbol=ICP&convert=USD&CMC_PRO_API_KEY=" + API_KEY);
  var jsonUSD = JSON.parse(responseUSD.getContentText());
  var price_usd = jsonUSD.data.ICP.quote.USD.price;

  Logger.log("Price in USD: " + price_usd.toFixed(2));
  Logger.log("Price in JPY: " + price_jpy.toFixed(2));

  var message = "ICP Price in USD: " + price_usd.toFixed(2) + "\nPrice in JPY: " + price_jpy.toFixed(2);
  
  var options = {
    method: "post",
    headers: {
      "Authorization": "Bearer " + LINE_NOTIFY_ACCESS_TOKEN
    },
    payload: {
      "message": message
    }
  };
  
  var response = UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
  Logger.log("Response: " + response.getContentText());
}</code></pre>

LINEに送付

![](https://pbs.twimg.com/media/Fo7WmWraIAEHvAz?format=jpg\&name=medium)
whisper API 、ChatGPT API 使って、youtubeそのまま翻訳

盛り上がってるのでwhisper API 、ChatGPT API 使って、youtube翻訳そのまま楽しようと思ったけど、gpt-3.5-turbo というのは文字数制限引っかかったのか (4096 token ？) 最後まで日本語が行かず。

まあよく分からず使ったので勉強します、なのだが、

とりあえず、短い動画で実施した備忘録を書く

以下動画を翻訳。

<iframe width="560" height="315" src="https://www.youtube.com/embed/wEQaG4xMMiw" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

***

# pytubeとopenaiという2つのパッケージをインストール

ここでは、pytubeとopenaiという2つのパッケージをインストールしています。pytubeは、YouTube動画をダウンロードするためのパッケージであり、openaiはOpenAI APIを使うためのパッケージです

<pre><code>!pip install pytube
!pip install openai</code></pre>

***

# YouTubeの動画をダウンロードします

YouTubeの動画をダウンロードします。以下のコードを使用して、youtube_url変数に指定されたURLから音声をダウンロードします。

<pre><code>from pytube import YouTube

youtube_url = "https://www.youtube.com/watch?v=wEQaG4xMMiw"



# YouTubeの動画をダウンロード

yt = YouTube(youtube_url)
yt.streams.filter(only_audio=True).first().download()
</code></pre>

結果、

<pre><code>/content/Welcome to the Sodium Launch Event.mp4</code></pre>

これを次で使う

***

# OpenAIのAudio APIを使用して、ダウンロードした音声ファイルをテキストに変換

OpenAIのAudio APIを使用して、ダウンロードした音声ファイルをテキストに変換します。以下のコードを使用して、OpenAI APIを使用してテキストを取得することができます。

<pre><code>import openai

# APIキーを設定
openai.api_key = "Your API Key"

# 音声ファイルを読み込む
audio_file = open("/content/Welcome to the Sodium Launch Event.mp4", "rb")

# OpenAI APIを使用してテキストに変換する
transcript = openai.Audio.transcribe("whisper-1", file=audio_file)
</code></pre>

***

# 最後に、文字起こしの結果を表示します

<pre><code>print(transcript["text"])</code></pre>

結果

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

***

# ChatGPT API 日本語へ

<pre><code>import openai

# 推論
response = openai.ChatCompletion.create(
  model="gpt-3.5-turbo",
  messages=[
    {"role": "system", "content": "あなたは日本語を英語に翻訳するアシスタントです。"},
    {"role": "user", "content": '以下の日本語のテキストを英語に翻訳してください: “{0}"'.format(transcript["text"])}
  ]
)
print(response["choices"][0]["message"]["content"])
</code></pre>

結果、

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

***

# データ確認用

翻訳結果を整形して出力する

<pre><code>import json

print(json.dumps(response, indent=2, ensure_ascii=False))</code></pre>

***

# Jupyter NotebookやGoogle Colab上で直接表示する方法。

<pre><code>from IPython.display import display, Markdown

display(Markdown("## Transcript:\n{0}\n".format(transcript["text"])))
display(Markdown("## Response:\n{0}\n".format(response["choices"][0]["message"]["content"])))
</code></pre>

結果、

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

***

良い感じ

料金はトライアル18ドルで実施中、まだ確認してない。
2023/3現在　PyTorchのLSTM引数についてまとめる

input_size
入力系列データの変数の数

hidden_size
隠れ状態の変数の数

num_layers
LSTMユニットを何層重ねるか（デフォルト：1）

bias
Falseに設定するとb_ihとb_hhを使わなくなる（デフォルト：True）

batch_first
Trueに設定すると入力するTensorの形を (データ長, バッチサイズ, 特徴量)から(バッチサイズ, データ長, 特徴量)に変更できる，つかうひとのこのみ（デフォルト：False）

dropout
最後のLSTM層を除いて設定した値でDropoutする（デフォルト：0）

bidirectional
Trueに設定すると双方向LSTMに変更できる（デフォルト：False）

proj_size 
正の値を設定すると対応したサイズのprojection layerを使う，おそらくLSTMPになる（デフォルト：0）

参考
https://runebook.dev/ja/docs/pytorch/generated/torch.nn.lstm
system.properties

javaのsystem propertyを確認する方法
System.getProperties()
```java
public class SampleProject {
    public static void main(String[] args) {
        Properties ps = System.getProperties();
        ps.list(System.out);
    }
}
```
```
sun.desktop=windows
awt.toolkit=sun.awt.windows.WToolkit
java.specification.version=11
sun.cpu.isalist=amd64
sun.jnu.encoding=MS932
java.class.path=C:\Users\java\Documents\NetBeansProje...
java.vm.vendor=Oracle Corporation
sun.arch.data.model=64
user.variant=
java.vendor.url=https://openjdk.java.net/
user.timezone=
os.name=Windows 10
java.vm.specification.version=11
sun.java.launcher=SUN_STANDARD
user.country=JP
sun.boot.library.path=C:\Program Files\Java\jdk-11.0.17\bin
sun.java.command=sampleproject.SampleProject
jdk.debug=release
sun.cpu.endian=little
user.home=C:\Users\java
user.language=ja
java.specification.vendor=Oracle Corporation
jdk.module.path=C:\Users\java\Documents\NetBeansProje...
java.version.date=2022-10-18
java.home=C:\Program Files\Java\jdk-11.0.17
file.separator=\
java.vm.compressedOopsMode=Zero based
line.separator=

java.specification.name=Java Platform API Specification
java.vm.specification.vendor=Oracle Corporation
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
user.script=
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
java.runtime.version=11.0.17+10-LTS-269
user.name=java
path.separator=;
os.version=10.0
java.runtime.name=Java(TM) SE Runtime Environment
file.encoding=UTF-8
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
java.vendor.version=18.9
java.vendor.url.bug=https://bugreport.java.com/bugreport/
java.io.tmpdir=C:\Users\java\AppData\Local\Temp\
java.version=11.0.17
user.dir=C:\Users\java\Documents\NetBeansProje...
os.arch=amd64
java.vm.specification.name=Java Virtual Machine Specification
java.awt.printerjob=sun.awt.windows.WPrinterJob
sun.os.patch.level=
java.library.path=C:\Program Files\Java\jdk-11.0.17\bin...
java.vendor=Oracle Corporation
java.vm.info=mixed mode
java.vm.version=11.0.17+10-LTS-269
sun.io.unicode.encoding=UnicodeLittle
java.class.version=55.0
```
javacで英語を使用したい場合、user.languageを使用してシステム値を設定する
```
javac -J-Duser.language=en xxx.java
```
書籍「バンディット問題の理論とアルゴリズム」を読み解く

多腕バンディット問題は、強化学習の中でも特に重要な問題の1つである。多腕バンディットとは、スロットマシンのような複数のアームがある機械を想定し、どのアームを引けばよいかという選択問題を指す。この問題を解決することで、より効率的な意思決定が可能となる。

多腕バンディット問題についての参考書は数多くあり、本稿ではその中でも代表的な書籍である「バンディット問題の理論とアルゴリズム」に基づいて、1章ごとに記事を書いていく。本シリーズを通して、多腕バンディット問題についての基礎的な知識から応用的な解法までを解説し、読者の方々が強化学習における意思決定問題を解決する上での知識を深めていただければ幸いである。

## 各章

### 第1章

多腕バンディット問題の紹介、腕を選択したときの評価方法（リグレットなど）

https://qiita.com/goto2023/items/08c5c724a39a78a25d70

## 書籍

https://www.amazon.co.jp/%E3%83%90%E3%83%B3%E3%83%87%E3%82%A3%E3%83%83%E3%83%88%E5%95%8F%E9%A1%8C%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E6%9C%AC%E5%A4%9A-%E6%B7%B3%E4%B9%9F/dp/406152917X
スクレイピングの実施方法メモ(1)

## スクレイピングの方法
スクレイピングは、


### HTMLのタグの基本
Webページは、HTML（ハイパーテキスト）で書かれており、HTMLはタグで文字の修飾や機能を与えWebページを表示します。そのためスクレイピングを実施する時は、HTMLのタグを最初に理解することが必要です。

| タグ名 | 説明 | 備考 |
|:-----------|------------:|:------------:|
| \<h>       | 見出しの作成で、h1,h2・・        |          |
| \<a>    | リンクの作成     |         |
| \<table>         | 表の作成       |            |
| \<div>       | グループを作る       |        |
| \<ul>    | リスト(箇条書き)を作る     |       |
| \<p>    | 段落を作成する     |       |
| \<form>    | フォームを作る     |       |
| \<button>    | ボタンを作成     |       |

### Webページから要素を取り出す
`find`メソッドで要素を一つ取り出す。

```
#ライブラリーのimport
from pathlib import Path
from bs4 import BeautifulSoup

#ファイルのパスの設定
hfile = Path('flowerpark.html')
#ファイルの読み込み。テキストで読みこむ。
htext = hfile.read_text(encoding='utf-8')

#BeautifulSoupオブジェクトの作成
soup = BeautifulSoup(htext, 'html.parser')

#soupオブジェクトの中からh2タグの内容を変数h2に入れる。h2はタグ全体。textでその中のテキスト。
h2 = soup.find('h2')
print(h2)
print(h2.text)
#soupオブジェクトの中からh2タグの内容を変数h3に入れる。
h3 = soup.find('h3')
print(h3)
print(h3.text)

#<h2>皆様へのお願い</h2>
#皆様へのお願い
#<h3>開園時間</h3>
#開園時間
```

`a`タグの`href`属性の取り出し
`href`属性は、「hypertext reference」でハイパーテキストの参照。
```
a_tag = soup.find('a')
print(a_tag)

#<a href="gallery/flower1.html">
#<img alt="" height="120" src="img/flower1.jpg" width=" 200"/>
#</a>

print(a_tag['href'])

#gallery/flower1.html
```
`id`属性、`class`属性を指定して要素を取り出せる。

```
news = soup.find(class_='block-news')
print(news)

#<div class="block-news">
#<h2>皆様へのお願い</h2>
#<ul>
#<li>駐車場の混雑緩和のため、公共交通機関をご利用ください</li>
#</ul>
#</div>

span = soup.find('span', class_='info-access')
print(span)

#<span class="info-access">○○線「△△」駅下車 徒歩5分</span>
```
`find_all`メソッドで要素を全部取り出す。
`find`メソッドと`find_all`の違い

| 項目 | `find` | `find_all` |
|:-----------|------------:|:------------:|
| 取り出す要素     | 最初の１件        |要素全て          |
| 戻り値 | Tagオブジェクト     | ResultSetオブジェクト        |
| 要素がない場合の戻り値    | None       | 空のResultSetオブジェクト           |

タグは複数設定することで、複数取り出せる。
引数`limit`をつけることで、個数を設定できる。
```
for h2 in soup.find_all('h2'):
    print(h2, '：', h2.text)

#<h2>皆様へのお願い</h2> ： 皆様へのお願い
#<h2>新着情報</h2> ： 新着情報
#<h2>フラワーギャラリー</h2> ： フラワーギャラリー
#<h2>公園の利用案内</h2> ： 公園の利用案内

for h_tag in soup.find_all(['h1', 'h2', 'h3']):
    print(h_tag)

#<h1>フラワー公園</h1>
#<h2>皆様へのお願い</h2>
#<h2>新着情報</h2>
#<h2>フラワーギャラリー</h2>
#<h2>公園の利用案内</h2>
#<h3>開園時間</h3>
#<h3>交通案内</h3>

for h_tag in soup.find_all(['h1', 'h2', 'h3'],limit=2):
    print(h_tag)

#<h1>フラワー公園</h1>
#<h2>皆様へのお願い</h2>


```
引数class属性を設定することで、クラス中のタグを取り出せる。

```
for span in soup.find_all('span',
                          class_='info-access'):
    print(span)

#<span class="info-access">○○線「△△」駅下車 徒歩5分</span>
#<span class="info-access">○○バス「△△」下車 徒歩2分</span>
```
Ruby で解く AtCoder ABC292 E DFS ワーシャル–フロイド法 + bit演算

# はじめに
AtCoder さん、ありがとうございます。

今回は、コンテスト後直ぐに解説放送が始まりました。

https://www.youtube.com/watch?v=18iiVATSWqo

その中のE問題を写経したいと思います。

# E - Transitivity
https://atcoder.jp/contests/abc292/tasks/abc292_e

# DFS
```rb:Ruby
n, m = gets.split.map(&:to_i)
to = Array.new(n) { [] }
m.times do
  a, b = gets.split.map(&:to_i)
  to[a - 1] << b - 1
end
ans = 0
n.times do |sv|
  can = Array.new(n, false)
  q = [sv]
  can[sv] = true
  while q.empty?.!
    v = q.pop
    to[v].each do |u|
      next if can[u]
      can[u] = true
      q << u
      ans += 1
    end
  end
end
puts ans - m
```
いつものごとく、あれを使って**Crystal**
```cr:Crystal
n, m = read_line.split.map(&.to_i)  
to = Array.new(n) { [] of Int32 }   
m.times do
  a, b = read_line.split.map(&.to_i)
  to[a - 1] << b - 1
end
ans = 0
n.times do |sv|
  can = Array.new(n, false)
  q = [sv]
  can[sv] = true
  while q.empty?.!
    v = q.pop
    to[v].each do |u|
      next if can[u]
      can[u] = true
      q << u
      ans += 1
    end
  end
end
puts ans - m
```
あれ

https://github.com/superrino130/crystal-on-paiza.cloud
# ワーシャル–フロイド法(TLE)
```rb
n, m = gets.split.map(&:to_i)
ab = Array.new(n) { Array.new(n, 0) }
n.times do |i|
  ab[i][i] = 1
end
m.times do
  a, b = gets.split.map(&:to_i)
  ab[a - 1][b - 1] = 1
end
n.times do |k|
  n.times do |i|
    n.times do |j|
      ab[i][j] |= ab[i][k] & ab[k][j]
    end
  end
end
puts ab.flatten.count(1) - m - n
```
ワーシャル–フロイド法で距離を全て`1`としますとDFS/BFSの問題を解くことができます。
但し、DFSの計算量は$O(N^{2})$ですが、ワーシャル–フロイド法は$O(N^{3})$ですので、この問題では**TLE**となります。
# ワーシャル–フロイド法 + bit演算
```rb
n, m = gets.split.map(&:to_i)
g = Array.new(n, 0)
n.times do |i|
  g[i] |= 2 ** (n - i - 1)
end
m.times do
  a, b = gets.split.map(&:to_i)
  g[a - 1] |= 2 ** (n - b)
end
n.times do |k|
  n.times do |i|
    g[i] |= g[k] if g[i][n - k - 1] == 1
  end
end
puts g.map { |e| e.to_s(2).count('1') }.sum - m - n
```
bit演算を使用することにより、3重ループを2重ループに落とすことができました。
||DFS(Ruby)|DFS(Crystal)|FW|FW+bitset|
|:--:|--:|--:|--:|--:|
|実行時間(ms)|561|66|TLE|1036|
# まとめ
+ ワーシャル–フロイド法の応用 を学習しました
+ すぬけさんありがとうございます。
記事にコメント機能④

<h1>create actionを実装</h1>

投稿して、保存する。
app/controllers/comments_controller.rb
記事を取得して、コメントして、ビルドする。

      def create
        article = Article.find(params[:article_id])
        comment = article.comments.build()
        comment.save
      end

    private
      def comment_params
      params.require(:comment).permit(:content)
      end
コメントの中のコンテントのしか保存しない

保存されなかった時の処理

    if comment.save
      redirect_to article_path(article)
    else
      flash.new[:error] = '更新できませんでした'
      render :new
    end
redirect_to article_path(article):記事詳細ページに戻るという意味


これで、保存できるはずなので、一旦保存を実施してみる。
保存できているかの確認をするため、
rails コンソール

    $Comment.last
先ほど投稿したものを確認できる。

app/models/comment.rb
コンテントが絶対に入ってないといけないよ！とする。

    validates :content, presence: true
こうすると、記事を何も書かずに保存しようとすると、Contentを入力してくださいとなる。

これで、保存機能実装👍
salesforce:スケジュールトリガフローのスケジュール済パスで1分後に設定する事で解決できた問題

先日、
複数の取引先責任者が紐づく単一の活動（Todoや行動）を画面フローで作成する
https://qiita.com/SHU_/items/e2b28135411604a652b1
という記事をアップしました。

簡単に説明すると、
まずTodoレコードを取引先責任者無しで作成して、
後から取引先責任者との連結オブジェクトレコードを作成して紐づける
という方法です。

で、一つ問題が発生しました。
Todoの作成時に起動するスケジュールトリガフローを設定していたのですが、
このフローはTodoに紐づく取引先責任者を参照するものだったのです。
（ちなみにTodoの親になっているレコードのテキスト項目に取引先責任者名を並べていくフローです。
　親オブジェクトのリストビューで取引先責任者を簡単に一覧できるので便利だと好評です。
　作り方わからないけど知りたいという方はご連絡を。そんなに難しくないです。）


上記記事の方法でTodoを作成すると、
Todo作成時点では取引先責任者は紐づいていないため、
このスケジュールトリガフローでは何の処理もできません。

Todoを作成する画面フローの方にこの処理を入れ込む手もありますが、
他の処理もあるので、スケジュールトリガフロー側でやっておきたい。

ということで先日参加したイベントで紹介されていたスケジュール済パスが頭に浮かびました。
フローがトリガした時点から一定期間が経った後に処理が動くように予約しておく機能です。

最初この機能って１週間後とか１か月後とかに動かすイメージだったのですが、
これを１分後で動かせばええやん、という事に気づいたわけです。

Todoレコードが作成された一分後に、
そのTodoに紐づく取引先責任者を参照した処理を行うように設定。
Todo作成をした画面フローはその直後にちゃんと取引先責任者を紐づけてくれているので、
１分後にはちゃんと処理が出来るわけです。

やー、イベントで話聞いててよかったー。
これ聞いてなかったら多分スケジュールトリガフローを毎晩動かすか、
画面フローの中に処理を入れ込むかを考えてました。
達人プログラマーを読んで

## 記事を書く目的
情報をインプットしてアウトプットする練習のため、毎週本を読み理解したことや気になったことをまとめてみようと思い、投稿します。

:::note warn
以下記載する内容は個人の見解であり、内容が正しいかどうかは保証できないことをご理解ください。
:::


## 進め方 
私は新しい本を読む時、その本の目次を先に読み気になることを質問にまとめています。
以下では、その質問に回答する方針で進めたいと思います。


## 
##### Q.　 良い設計とは？
良い設計とは、ETC原則が守られている設計である。
ETC原則とは「Easier To Change」の略語で、つまり「変更がしやすい」という意味である。

ソフトウェア開発において変更がしやすい設計が良いと考えられている背景には、
ソフトウェアが常に変わりゆくものであり、開発者は常にソースコードを修正し続ける必要があるという考えがある。

つまり、開発者にとってソースコードに修正を加えやすい設計が、良い設計であると考えているということである。


さて次に、ETC原則を具体的に噛み砕いた原則をいくつか紹介したい。

**DRY原則**


DRY(Don’t Repeat Yourself)原則とは文字通り「繰り返しを避けよ」という原則である。
少し意訳すれば、「重複を排除せよ」となる。

なぜDRY原則がETC原則に通ずるのか、具体的にソースコードを修正する場面を考えてみる。

例えば、仕様の変更に伴いソースコードを修正する場面に遭遇したとする。

同じ修正内容を複数箇所で行わないといけないとなると、
修正することへのコストが増えまた、修正をし忘れるということのリスクにもつながってしまう。

つまりDRY原則とは、`同内容の修正は一つに集約しメンテナンスを行う際の容易性を上げよう`ということなのだ。


**直交しているシステム**

直交性とは、片方を変更しても他方に影響を与えない特徴のことである。
直交しているシステムとは、片方を変更しても他方に影響を与えない特徴を持つシステムということである。

例えば、直交していないシステムの場合にどのような弊害があるか考えてみる。

ある機能Aについての仕様変更があり、機能Aについてのソースコードを修正した。

その結果、仕様通り機能していた別の機能Bで不具合が出てきてしまった。

このような設計になっていると、機能Aだけの仕様変更のために機能Bが今までの仕様要求を満たしているかどうかを常に気にしながら実装しなくてはいけなくなってしまうだろう。

加えて、実際の開発の現場では機能が2個しかないシステムなど無く、その他数十~数百の全ての機能を気にしながら開発するのはとても開発効率が悪い。

つまり、直交しているシステムを作る原則とは、`ソースコードを修正する際に関心を一つにとどめれるような（別のことを気にしなくても良いような）設計`にしようということである。



また、表現を変えて、`凝集度の高いコンポーネントを設計するべき`であるとも主張している。

凝集度が高いとは、自己完結（独立）して、他のコンポーネントに依存していないという意味である。

コンポーネントが独立していることで（ほとんど直交していると近い考えであると理解しているが）、他の部分を気にせず変更することができるのだ。



## 感想
- 本書の中で、偶発的プログラミングをアンチパターンとして取り上げていた。`偶発的プログラミングとはなぜ動くか説明できないコードを実装`することである。私は偶発的なプログラミングをしがちだなので、耳がとても痛い話でした。。
- 直交性の話の中で、目の前のシステムが直交的かどうか判断するには、`「特定コンポーネントの要求が大きく変化した場合、どれだけ多くのモジュールに影響が及ぶか」という質問を投げかけると良い`と書いてあった。例えば、私（あなた）がフロントエンドの開発の責任者で顧客に、Webページからスマホのアプリケーションにしてくれと急遽言われたとする。その時、私（あなた）は、変更のしやすい設計にしているだろうか。例えば、ロジックとUIが分離されていてUI部分だけ差し替えれば良い設計になっているだろうか。データアクセスする処理を修正したら、ボタンの色が変わることはないか（そんなことはないと思うが。。笑）、など思考実験をしてみると良いのかなと思いました。


## 来週読む予定の本
- [良いコード/悪いコードで学ぶ設計入門](https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89-%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2/dp/4297127830/ref=sr_1_1?adgrpid=138203738080&gclid=Cj0KCQiA9YugBhCZARIsAACXxeLNldgtdaGZQG2pc55syZ3uHtFvpCoANYvaqgsIYk__cy5l5Mr0VloaAr0xEALw_wcB&hvadid=618732203267&hvdev=c&hvlocphy=1028853&hvnetw=g&hvqmt=e&hvrand=3784395806515851364&hvtargid=kwd-1717124964237&hydadcr=22147_13405101&jp-ad-ap=0&keywords=%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6&qid=1677932461&sr=8-1)


おしまい。
BingのAI検索エンジンがすごい！？どんなものか試してみた

BingのAI検索エンジンが搭載されたという噂を耳にしたので早速使ってみました！
WindowsだけでなくmacOSでも利用可能です。

## Bingとは？
MicrosoftEdgeに搭載されている検索エンジンです。
なので利用するためにはMicrosoftEdgeをダウンロードする必要があります。
もちろん、Macでも利用できます！

https://www.bing.com/new?form=MY028Z&OCID=MY028Z&scdexwlcs=1

## 実際の使用感
ダウンロードするためにBingを調べます。
Bingで調べてもMicrosoftEdgeのダウンロードを促すボタンが設置してあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/edd25b3c-b9b4-280d-a41a-dbede458b557.png)

と出たのでとりあえずダウンロードしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/951354dd-a9cc-fe43-3579-fbadf85e01d8.png)

ダウンロードが完了してブラウザを起動するとこんな感じです。
AI検索の導線がどこにあるのかわかりません…。
検索すればいいのか？と思ったので「マインクラフト」で検索してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/6db1f0d2-2f17-74bb-9b1b-52d4bd5b7547.png)

お…！「チャット」というそれらしいタブがあるので選択してみます。
チャットっぽいUIが開きました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/00079555-d65d-c601-5fec-6ae191d05e2a.png)

少し使ってみます。
![画面収録_2023-03-04_14_58_08_AdobeExpress (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/ee04137b-1d40-3a8e-210e-955b4ddb438a.gif)

入力や選択肢を選択することで会話が続きます。
質問への答えも違和感のない自然な言語で返ってくる印象でした！

## 【まとめ】MicrosoftEdgeに搭載されたAI検索エンジン
ChatGPTも試しに使ってみたのですが使いづらさもありました。

具体的には、
- エラーで検索できなくなる（フリーズする）
- 検索結果が返ってくるまでラグがある
などです。

:::note alert
ChatGPTの問題点として適当な回答が返ってくる、情報が古いことも言われていますので使い方によっては注意が必要です…。
:::

ChatGPTは無料で利用しているので仕方ない部分もありますが、BingのAI検索エンジンはスムーズに結果が返ってくる印象です。

:::note info
有料のChatGPTに勝るものはないかもしれませんが、無料で使いたい場合Bingを利用する方のも良いかもしれません！
:::


興味のある人はぜひ利用してみてください！
Juliaで文字列をスネークケースに変換する

```julia
function snakecase(str)
     str = replace(str, r"(?<a>[a-z])(?<b>[A-Z])" => s"\g<a>_\g<b>")
     str = replace(str, "-" => "_")
     str = replace(str, r"\s+" => "_")
     return lowercase(str)
end
    
snakecase("FOOBAR")  # => foobar
snakecase("FOO-BAR") # => foo_bar
snakecase("FooBAR")  # => foo_bar
snakecase("foo Bar") # => foo_bar
```

`replace` 関数で置換する際は、`(?<name>)` でキャプチャして、`\g<name>` で展開する。
Swiftで関数の引数に_が指定されている場合

関数の引数に_が指定されている場合、その引数はラベルなしで呼び出すことができます。つまり、関数を呼び出すときに、引数の名前を省略することができます。

例えば、次のような関数があるとします。

```swift

func sayHello(to name: String) {
    print("Hello, \(name)!")
}
```

この場合、関数sayHello(to:)を呼び出すためには、引数にラベルを付けて呼び出す必要があります。

```swift

sayHello(to: "John") // "Hello, John!"

```

しかし、引数に_が指定されている場合は、ラベルを省略して呼び出すことができます。

```swift

func sayHello(_ name: String) {
    print("Hello, \(name)!")
}

sayHello("John") // "Hello, John!"
```

上記の例では、関数sayHello(_:)を呼び出す際に、引数nameのラベルを省略しています。引数に_が指定されているため、引数名を省略して呼び出すことができます。
ABC292回答メモ

0.はじめに
　久々のスポンサー的なのがついていないABCでした。
　C問題の解法が分からず飛ばしてD問題に取り掛かったらすんなり解けました。
　ABDを回答した結果レートは±0でした。

1.A - CAPS LOCK
　言語の教科書に載っていそうな問題だなと思いつつ
　大文字に変換する関数をググって回答しAC

　https://atcoder.jp/contests/abc292/submissions/39407992

2.B - Yellow and Red Card
　イベント発生型の問題ではありますが、内容自体は簡単な問題。
　カードをもらった選手番号をキー、もらったカード状態を値にした辞書を作り
　イベント毎に辞書更新・参照をする形で実装しAC。

　https://atcoder.jp/contests/abc292/submissions/39413956

3.C - Four Variables
　コンテスト中は解法がわからず時間切れ。
　その後解説を見て、なるほどと思いつつ、
　解法が分かればプログラム的には簡単かとも思いますが
　なかなか難易度高いなと思いました。
　解法についてもN√N解法まではついていけましたが
　より高度な解法は理解できませんでした・・。

　【考え方】
　　・X+Y=NをみたすX(1～N-1)、Y(N-1～１)をループさせ
      それぞれのXとYについて
　　　Xを成り立たせるA*Bの組み合わせの数xと
　　　Yを成り立たせるC*Dの組み合わせの数yを求める
　　　それぞれのＸとＹの組み合わせの中でx*ｙがそのＸとＹの
　　　組み合わせを満たすＡＢＣＤの組み合わせ数となる。
　　・A*Bの組み合わせ数xの求め方
　　　例えば、X=12の時
　　　添え字jを１からカウントアップさせていきj*Bが成り立つ
　　　→X％j==0かどうかを判定し、成り立つ場合はxに1を足す
　　　X=12の時X％j==0が成り立つのは1,2,3,4,6,12
　　　組み合わせとしては、1-12、2-6、3-4となるため
　　　N<=J*J（N=12までの場合J=3)までをチェックし
　　　倍にすればxは求められる。
　　　Ｎ＝Ｊ*Ｊを満たすような場合は組み合わせが一つ減るので
　　　その点は考慮する。

　素直に実装した場合もACとなりましたが、その後ちょっとだけ工夫して
　Xの時のｘ、Yの時のｙを記憶しておけば
　X＜Yとなった場合の計算が不要となるため
　辞書にXの時のｘとYの時のｙを覚えさせておくようにして
　処理時間は半分になりました。

　https://atcoder.jp/contests/abc292/submissions/39454695

4.D - Unicyclic Components
　問題を読んで、ユニオンファインドを使って
　同じ根を持つ頂点数を求め
　辺の部分は、各辺毎に頂点u(vでもいいけど)が
　属する値を求め＝辺が属する根とし
　それぞれカウントして同じ根を持つ頂点数＝辺数を満たせば
　Yes、満たさなければNoとしたところAC頂けました。

　https://atcoder.jp/contests/abc292/submissions/39432516

　参考サイト：https://procon.fun/code/unionfind-cycle/

以上
SvelteでRxJSのSubjectをSvelte Storetとして使えるパッケージをリリース

はいさい！オースティンやいびーん！

この前、SvelteでRxJSを使う方法を紹介しました。

https://qiita.com/tronicboy/items/5324e8a108177c9728fb

そこで説明したように、RxJSのSubjectに`.set`もメソッドを追加する必要があります。

その`.set`を追加した`Subject`, `BehaviorSubject`, そして`ReplaySubject`を`SvelteSubject*`と名付けてnpmパッケージとしてリリースしておきました。

https://www.npmjs.com/package/@tronicboy/svelte-rxjs-subjects

RxJSとSvelte、一緒に使ってみてください！

これらのSvelteSubjectでユーザー入力をバインドできるので、とても楽しいです！
記事にコメント機能③

<h1>投稿画面を作成</h1>
画面の作成には、まずラウツを作成しその後、コントローラ

config/routes.rb

      resources :articles do
        resources :comments, only: [:new, :create]
      end
ラウツの設定はできているので、コントローラを設定していく

app/controllers/comments_controller.rb
を作る。
ファイル名は、複数形を使う。

    class CommentsController < ApplicationController
    end
コメントを保存したり、コメント作るための画面を表示するので、
こうしておく。
ファイルと同じコメンツコントローラにする。

ラウツを確認。
new_article_comment_path	

GET	

/articles/:article_id/comments/new(.:format)

	
comments#new

コメント記事を投稿するためのアクション

newをするときは、まず空の箱を作る。
new_article_comment_pathは、記事のidを取得できる。
今までは、idだけでとれたが、今回は、[:article_id]
なぜなら、今回ラウツを見るとarticle_idになっているのが、わかります。

コメントを取得してから、コメンツをビルドしている。
※build:建てる

app/controllers/comments_controller.rb

    def new
        article = Article.find(params[:article_id])
        @comment = article.comments.build
      end

app/views/comments
viewsにcommetsフォルダを作成。
CommentsControllerなので、commentsとする。

app/views/comments/new.html.haml
 ファイル作成後、

    = form_with(model: @comment, url: article_comments_path)
フォームで、コメント投稿するためのパス

それは、article_comments_pathのPOST
これは、article_idを指定しなければいけない！
(@comments.article)後ろにこれを追加。

    = form_with(model: @comment, url: article_comments_path(@comments.article), local: true) do |f|
f:formのf

    %div
        = f.label :content, '内容'
    %div
        = f.text_area :content
    = f.submit '保存', class: 'btn-primary'


text_areaは、railsで用意されているもの。

これは、定番の表現
わからなければ、ググれば良い！！

    .container
      %ul
        - @comment.errors.full_messages.each do |message|
          %li= message
エラーが、表示するようにする。

app/views/articles/show.html.haml

    .container
      = link_to new_article_comment_path(@article) do
        .btn-secondary
          コメントを追加
どこの記事に追加するかわかるように、＠articleを引数にする。

デザインの変更
app/assets/stylesheets/buttons.scss
    
    .btn-secondary {
      background-color: white;
      border: solid 1px $primary-color;
      width: 100%;
      text-align: center;
      color: $primary-color;
      padding: 16px 0;
      font-weight: bold;
    }
未経験30代がエンジニアになるまで

# はじめに
こんにちは。
まず簡単な自己紹介から、

年齢: 31歳
最終学歴: 高卒
資格: 何もありません
前職: 運送業
PC経験: 全くありません

という感じで、今年より本当の未経験から約半年で無事エンジニアとなれました。

そのロードマップを書いていきます。

# 動機について
前職が一日働いて、お風呂入って、食事して、寝ての繰り返しだったのですが、それ以外何もしてないんですよね。
それでも、今週もやり切ったとか思って毎日過ごしている時に思ったのですよね。
「これ60歳過ぎまで続けるのきついぞ」と、

色んな意味で肉体労働だったので・・・笑

そんなときに、youtubeでマナブさんの動画にあたり憧れや、実際に以前プログラミングに興味を持っていたこともあり、さらには手に職をつけるって部分に惹かれました。

という感じでした。


# 実際にやってみたこと
時系列として、
**学習1~2か月**
・Progateの言語コースを順番にやってみる(html, css, javascript, PHP, Ruby)
・youtubeでの解説を見ながらが実際に動かしてみる
・twitterで日々の学習用アカウントの作成
・Twitterを利用して誰かに聞ける環境を作る
・Twitter経由で、プログラミング学習コミュニティに参加

**学習3~4か月**
・コミュニティでオンライン勉強会など実施アウトプットの観点から自分も解説あり(Progateとyoutubeを活用)
・コミュニティで、1対1メンター式でコードレビューしてもらいながらアプリの作成

**学習4~6か月**
・Qiitaにて記事の作成(メモ、解決策の記録)
・エラーが起きてもなにが問題点か分かってくる(自己解決)
・ポートフォリオ作成(コミュニティメンバーにレビューしてもらう)

:::note info
勉強時間としては、大体一日夜の1時間～2時間くらいを目安
仕事が終わってからの時間を基本勉強時間として休みの日はあまりやらないようにしていました。
休みはしっかり休みたいし、リフレッシュしたいのでサボりです笑
:::

# やってみてよかったこと
### Twitterの運用
・転職希望者が多数利用している
・一人でやっている感がなくなる
・個人的にメッセージも来るので学習者同士で教えあえる
・実際にメッセージなどで企業からコンタクトがある

### コミュニティの運用
・多数の同じ目標を持った人がいるため、孤立しにくい
・講師として指導や解説などしてくれる人がいるのでわからなくてもすぐ聞ける
・共同開発経験ができる
・現役のエンジニアに色々聞ける、相談できる

# やってよくなかったこと
### Progate
・最初から完璧に理解しようと同じことを何度も復習する
・最初から色々な言語を触る(javascript,PHP,Ruby)など

:::note warn
注意
Progateが悪いわけではありません。
あくまで、勉強のやり方が悪いだけです。
:::

### Twitter
・色々な人達と話しができる分勧誘もある(中には二人掛かりでのスクール勧誘がありました)

# 転職について
私の場合、これまでに受けた社数は10社でした。
#### 受けた会社内訳として、
選考落ち・・・2社
書類選考・面談通過・・・4社
1次面接通貨・・・3社
合格・・・1社

#### 面接の内訳として、
Web面接・・・2社
訪問面接・・・2社

### 印象的だったこと
・年齢について(30代未経験について)
・最近はWeb面接が主流のため、来社での面接の方が好感を持てるとのこと
・Git,Githubを使ったことがあるかどうか(ほとんどの会社で聞かれました)
・技術的なことも聞かれますが、どっちかというとなぜこの会社に入りたいのか？なぜこの会社で無いとだめなのかをよく耳にします。
・日々の学習ログは残しておいたほうがいいです。未経験からという話だと技術より続けれる人かどうかを見られます。

# 使用した転職サイト使用感
### Green
・基本的に探して気になるや直接応募する形式
・企業側からも気になるが来るため話を聞きやすい。
・個々のコンタクトのため未経験だと返信率が低い傾向だと思いました。
#### 感想
求人情報の見やすさやコンタクトの取りやすさは魅力的でした。(zoomカジュアル面談が気軽)
ただ、経験者求めている傾向強い感じがしたので未経験での応募となると結構難しいかと思いました。

### doda
・エージェント、採用プロジェクト、、企業からのオファーと幅広く連絡が取れるためコンタクトが取りやすい。
・エージェント利用すると、言語指定やポートフォリオについてなど相談に乗ってくれる。
・希望している職種以外にもオファーがたくさん来てしまいほしい求人が埋もれやすい。
#### 感想
未経験で転職するのであれば結構なんでもやってくれるし、エージェント利用すれば現在の傾向も聞けるのでおすすめかなと思いました。

# 最後に
正直私は、最初副業ができればいいかな軽い気持ちで始めました。
ですが、コミュニティなどで色んな人達と交流を深める内にこの業界に入ってみたいと思い転職に至りました。

そういえば、正直転職もTwitter経由です笑
どこに縁が落ちているかわからないものです。

一人でやるには限界があります。
そして本気でエンジニアに転職したいのであれば
すでにエンジニアになっている方はたくさんいますので、
その人達に教えを乞うことが一番の近道だと思います。


少しでもこの記事が皆さんのためなることを祈っています。

以上
【AtCoder】ABC292 E F 解説【C++】

# E問題
$i→k,k→j$に辺があるなら$i→j$に辺があるようにするために追加する最小の辺の数を求める問題。

https://atcoder.jp/contests/abc292/tasks/abc292_e

## 解法
この問題は足りない辺を追加していく方針だと、(~~コンテスト中の自分のように~~)どうしても$O(N^3)$の解法に行きついてしまい、どつぼにはまる。
問題の性質を考えてみる。
- $i→k,k→j$に辺があるが、$i→j$に辺がない

というのはどういう状況だろうか。これは要するに、
- $i→j$に辺はないが、$i→j$に到達することはできる

のと同義である。そのため、こういった$(i,j)$の組を数える方針に辿り着く。各$i:1～n$に対して$j$を数えれば求める値になるのだろうか？答えは真である。
一見、辺を追加する順番に左右されたり、追加することで別の始点に対する値が変わってしまうように思われるが、実はそういったことはない。
結局やっていることは各$i$に対して$dist[j]=1$であるような$j$を探すことであり、別にどの順番で追加しようが、発見される$j$に変化はない。また、辺を追加することで、別の$i$から$j$への距離が変化するのは確かであるが、始点が異なる以上、その距離が(もともと辺が存在しない限り)$1$以下になることはありえない。

## コード
bfsの計算量は$O(N+M)$なので、$O(N(N+M))$。
```cpp
const int MX = 2001;
int connected[MX][MX];
int node_exist[MX][MX];
vector<int> e[MX];
int n, m;

void bfs(int s) { //O(N+M)
	int checked[MX];
	rep(i, n) checked[i] = 0;
	checked[s] = true;
	qi Q; Q.push(s);
	while (!Q.empty()) {
		int x = Q.front(); Q.pop();
		connected[s][x] = 1;
		for (int y : e[x]) {
			if (!checked[y]) {
				Q.push(y); checked[y] = 1;
			}
		}
	}
}

int main() {
	//(void)scanf("%d",& );
	//(void)scanf("%d%d",& ,& );
	cin >> n >> m;
	memset(connected, 0, sizeof(connected));
	rep(i, m) {
		int x, y; (void)scanf("%d%d", &x, &y);
		--x; --y; e[x].push_back(y); node_exist[x][y] = 1;
	}
	rep(i, n) bfs(i);

	int ans = 0;
	rep(i, n) {
		rep(j, n) {
			if (i != j && connected[i][j]) {
				if (!node_exist[i][j]) ++ans;
			}
		}
	}
	cout << ans << endl;

	return 0;
}
```

# F問題
長方形に内接する正三角形の最大の一辺の長さを求める問題

https://atcoder.jp/contests/abc292/tasks/abc292_f
## 解法
入力2辺を$A,B(A≦B)$とする。求める長さを$X$とすると、まず
```math
B\geqq \frac{2}{\sqrt{3}}A
```
ならば、
```math
X=\frac{2}{\sqrt{3}}A
```
になる。以下のような正三角形が求めるものとなっているためだ。![91F96A2D-1016-4C2D-A181-9E8F979BDECE.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665102/78da9d4d-8a10-10a7-c53a-36d79fa2cdf4.jpeg)
そのほかのケースの場合、求める正三角形は以下のようになる。
![IMG_0417.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665102/7be14698-3889-a1cd-6094-6ffcae1526b4.png)
条件を用いて成り立つ式は、
```math
A^2+C^2=B^2+D^2={(B-C)}^2+{(A-D)}^2
```
ここから$D$を消去して$C$に関する方程式を$A,B$を用いて表すと、
```math
(A^2+C^2)(C^2-4BC+4B^2-3A^2)=0
```
$A^2+C^2>0$であるので、実質的に
```math
C^2-4BC+4B^2-3A^2=0
```
解の公式を用いてこれを解くと、$C<B$より
```math
C=2B-\sqrt{3}A
```
これを求める辺の長さ
```math
X^2=A^2+C^2
```
に代入すれば答えが求まる。

## コード
想定解法は求める長さに対して二分探索(この場合二分法といった方が正しいのかな？)。なるほどと思いながらやはり高校数学の問題にしか見えない模様
```cpp
int main() {
	//(void)scanf("%d",& );
	//(void)scanf("%d%d",& ,& );
	int a, b;
	cin >> a >> b;
	double B = (double)max(a, b);
	double A = (double)min(a, b);
	double ans;
	if (sqrt(3) * B >= 2 * A) {
		ans = A * 2 / sqrt(3);
	}
	else {
		double C = 2 * B - sqrt(3) * A;
		ans = sqrt(A * A + C * C);
	}
	std::cout << std::fixed;
	cout << std::setprecision(10) << ans << endl;

	return 0;
}
```
エラーメッセージだけでは判断できない


The value of a parameter contains a character that is not allowed or the value exceeds the maximum allowed length. Remove the character from the parameter value or reduce the value length and resubmit. If the error still persists, report it to our Customer Support team. Provide the URL of the page you were requesting as well as any other related information.


このエラーメッセージの対応には色々とありそうです。共通で使われているメッセージかもしれない

# カスタム項目が作成できなくなりました

+ [カスタム項目が作成できなくなりました](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgJBg)

:::note
カスタム項目が作成できなくなった件について、Salesforceサポートより回答、対処してもらえました。

私の場合、「カスタム項目を作成する際に削除済み項目の領域が開放されておらず、領域に空きがない状況であるため」できなかったとのことでした。

確かに項目の空きがない状態でしたが、

項目をいくつか削除して、項目とリレーションの右上のボタン「削除済みの項目」から削除をして処理していたのですが、それだけではダメとのことでした。

「手動で物理削除処理をすることで領域の解放がなされる」とのことで、それはSalesforceサポートの方でやっていただけるとのことで対応してもらいました。

「※手動での物理削除処理にもお時間がかかる場合がございますので、その点についてはご容赦くださいますようお願い致します。」との注釈がありましたが、お願いしてから1時間ほどで完了し無事項目作成できるようになりました。
:::


# MessageDate <= DATETIMEVALUE(TODAY() - 30) 数式で出ている？

+ [Does anyone understand what this error means?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O8Q4FSAV)
Products, Quotes & Contracts


+ [Products, Quotes, & Contracts](https://trailhead.salesforce.com/content/learn/modules/sales_admin_products_quotes_contracts)

# GenWatt Gasoline 2000kwが表示されない

+ [Can't find the GenWatt Diesel product in the West Coast Manufacturing Price book](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JgKO2)

:::note
 I was fumbling around in the Price Book but sure enough, I had to set up the Products first, add them to the Standard Price Book and THEN I can add them to the Northwest Diesel Generator Sales Price Book.

価格表をいじっていましたが、確かに、最初に製品を設定し、それらを標準価格表に追加する必要があり、それからノースウェスト ディーゼル発電機の販売価格表に追加することができました。
:::

# 価格表の注意点

+ [価格表に商品を追加できません](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Ch4GuSAJ)

そのため、商品の関連リストに移動し、[価格表] セクションで [標準価格を追加] をクリックします。これにより、商品が標準価格表に追加されます。

標準価格表に追加したら、他の価格表に追加できます。カスタム価格表に追加する前に、まず標準価格表に追加する必要があります。

商品自体から行った方が簡単ですが、価格表に追加する場合は、まず標準の価格表に移動して商品を追加し、次に次の価格表に移動して商品を追加します。

最初に標準価格表に追加するしかないので、製品から行う方が簡単です
【Laravel】ファイルの変更が反映されない時のコマンド集

キャッシュをクリアすると反映される
```
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear
php artisan event:clear
php artisan clear-compiled
```

上記でも反映されなかった場合
```
composer dump-autoload
php artisan clear-compiled
php artisan optimize
php artisan config:cache
```
STM32G071でPWMを使ってSG90のセンターの1450usをだす。

目的
PWMのテスト


![o_cop391.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/be6cceeb-cf3e-f0c0-7b5a-62404a161a92.jpeg)



https://qiita.com/caa45040/items/17e50864f1052d00bedd


https://os.mbed.com/platforms/ST-Nucleo-G071RB/



```c++



//PWM_servo_test22_071_1

#include <Arduino.h>

//1000の割り算 だいたい正しい。
#define DIV1000(n) ((n+((n*25)>>10))>>10)

//data SG90
// 2400us 2.4ms
#define s_max  2400
// 500us 0.5ms
#define s_min  500
#define s_r    (2400-500)
#define s_c    (65536/20000)*1000
#define SN(n6)  (n6*((65536/20000)*1000))

#define DD PA10    // potentiometer connected to analog pin x


//初期化
void setup() {

  pinMode(DD, OUTPUT);   // sets the LED pin as output
  analogWriteFrequency(50);   //周波数
  analogWriteResolution(16);  //分解能

}//setup


//メインループ
void loop() {

  int ii; //ループカウンター

  //for (ii = 500; ii < 2400; ii=ii+100) {

  ii = 1450;
  analogWrite(DD, DIV1000(SN(ii))  );   // analogRead values go from 0
  // to 4095, pwmWrite values
  // from 0 to 65535, so scale rough
  delay(1000); //1000mS

  //}//for

}//loop




```
プロキシ環境でのPython環境構築まとめ

# はじめに
**以下の記事**で紹介した3種類のPython環境構築方法について、**プロキシ環境での実施手順**をまとめました。
基礎知識として、まずは以下の記事をご一読頂ければと思います。

https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64

実際に試し切れていない部分も一部あるため、不具合等ありましたら、コメントで適宜指摘・報告頂ければと思います

# 1. pyenv + venv
「1. pyenv + venv」をプロキシ環境で使用する場合、pyenvとpipのプロキシを設定する必要があります。
設定ファイル`pip.ini`で一括設定する事も可能ですが、仮想環境では混乱を招きやすいので、本記事ではコマンド毎に指定する方法を紹介します

### pyenvのプロキシ設定
[pyenvでインタプリタ切替](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64#pyenvでインタプリタ切替)で実行するコマンド

```
pyenv install バージョン名
```

を、

```
https_proxy=http://プロキシのアドレス:ポート pyenv install バージョン名
```

のように変えて実行することで、プロキシ環境でもpyenvのインタプリタ(Pythonのバージョン)をインストールする事ができます

### pip
[パッケージのインストール](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64#パッケージのインストール)で実行するコマンド

```
pip install パッケージ名
```

を、

```
pip install --proxy http://プロキシのアドレス:ポート パッケージ名
```

のように変えて実行することで、プロキシ環境でもpipでパッケージ (ライブラリ)をインストールする事ができます

# 2.pyenv + Poetry
「2. pyenv + Poetry」をプロキシ環境で使用する場合、pyenvとPoetryのプロキシを設定する必要があります。
本記事ではpyenvはコマンド毎に指定し、Poetryは設定ファイルでプロキシを指定する方法を紹介します

### pyenvのプロキシ設定

※[「1.pyenv + venv」の場合](https://qiita.com/c60evaporator/items/7a757134d028a7734118#pyenvのプロキシ設定)と同様です

[pyenvでインタプリタ切替](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64#pyenvでインタプリタ切替)で実行するコマンド

```
pyenv install バージョン名
```

を、

```
https_proxy=http://プロキシのアドレス:ポート pyenv install バージョン名
```

のように変えます

### Poetry
※こちらは常に上手くいくか自信がないので、うまく行かない方はコメント頂けるとありがたいです

プロジェクト内の[pyproject.toml](https://qiita.com/c60evaporator/items/b6a7394231d1e768ce64#プロジェクト用フォルダの作成-1)に以下の記述を追加します([参考](https://github.com/python-poetry/poetry/issues/3748))

```
[[tool.poetry.source]]
name = "proxy"
url = "http://プロキシのアドレス:ポート"
default = true
```
これでプロキシを指定した状態でPoetryのコマンドを実施できるはずです

# 3.Conda + conda-forge
「3. Conda + conda-forge」をプロキシ環境で使用する場合、Condaにプロキシを設定する必要があります。

### Condaのプロキシ設定
以下の場所にある`.condarc`を編集する必要があります

- Windowsの場合: `C:\Users\ユーザ名\.condarc`
- Macの場合: `~/miniforge3/.condarc` (Minicondaをインストールした場合`~/miniconda/.condarc`)
- Linuxの場合: `~/.condarc`

.condarcに以下内容を追記します

```.condarc
proxy_servers:
  http: http://プロキシのアドレス:ポート
  https: http://プロキシのアドレス:ポート
```

なお、pipでのインストールがうまくいかない場合は「1. pyenv + venv」と同様以下コマンドでインストールしてください

```console
pip install --proxy http://プロキシのアドレス:ポート パッケージ名
```
Windows10でBluetoothの機器が接続できないとき

# Bluetoothに接続できないとき (恐らくレアケース)

### 症状
症状としては、Bluetoothが使えているのに、新規の接続、ペアリングのみできない、という理解しがたい状況の場合。
「Bluetooth またはその他のデバイスを追加する」から、Bluetoothを選択すると瞬間的に「接続できませんでした」と表示される場合。
![bluetooth error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520911/2b8ea266-a079-22cb-87d3-c29ebb8bff8d.png)
Bluetoothのトラブルシューティングを行うと、「Bluetooth 無線の状態チェック」が「未解決」と出る場合。

### 原因
恐らく、サービスを弄った記憶があることだろう。
原因は「Network Connection Broker」が無効になっていることにある。
![NcbService.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520911/0d69db7c-4d03-adf8-8fc0-fc82efd8e76c.png)

このサービス、説明にはWindows ストア アプリが通知を受信できるように、としか書かれていないが、どうにも設定アプリもWindows ストア アプリ扱いで、且つ、Bluetoothのペアリングも担うらしい。
これが無効化されていることで、Bluetoothのペアリングは一切できなくなる。

### 解決策
![NcbService on.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520911/3323751d-1abe-512d-9239-411aa7e596f2.png)
スタートアップの種類を「自動」にするだけで良い。
ペアリングが発生した際に勝手に開始され、ペアリングができる。
手動にして開始をして、また無効にしても良いが、手間と同じ問題を踏む可能性を考えると、自動にしておくのが無難に思う。
格安SIM　マイソクスーパーライト（250円・音声通話＋32kbpsデータ）を試す

mineoさんのマイソクスーパーライトが、090番号が使えて月々250円とすごいプランだったので、
試してみます。
090番号付きのSIMをサブ扱いにして、デュアルSIM運用にしてみよう。さらにキャリアも分けて冗長化！
　・メイン eSIM　データのみ　　8ギガ 　　　　　　　 ドコモ回線　　IIJmioギガプラン
　・サブ　 SIM　 音声・データ　0ギガ（最大32kbps）　ソフバン回線　マイネオスーパーライト

# 進捗
　3/5 とりあえず申し込みまで、

# 前準備
　今使ってる090番号は変えたくないので、MNP予約番号を取得。

# マイネオ申し込み手順
・SIMのみ、SIMカード、5Gオプションあり
・Sプラン（ソフトバンク）
・デュアルタイプ（データ＋音声）
・マイソクスーパーライト（最大32kbps)
・広告フリー　申し込まない（マイソクでは申し込めない）
・mineo電話
・（お試し）　スマート留守電（留守電をテキストにしてメール通知）便利！　月々319円！
・MNP予約番号を入力「

# 費用
　初期費用　3740円
　月額　回線250円＋留守電319円
WindowsでVSCodeを用いたUbuntu開発環境をセットアップする

Windows内のVSCodeに"Remote Development"拡張をインストールし, WSL上でcodeコマンドを実行

# VS Code と WSL 拡張機能をインストールする
1. [VSCodeダウンロードページ](https://code.visualstudio.com/download)にアクセスし, Winsows用のVSCodeをダウンロードし, exeを実行してインストール
1. VSCode拡張の[Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)をインストール
1. WindowsのWSLを起動し以下のコマンドを実行
```
code 
```