OmniAICreator/Qiita-1.07M huggingface dataset:
可読性とその改善メリットについて理解する

# この記事で分かること
- 可読性の定義
- 可読性を上げるメリット

# 目次
1. 背景
3. 可読性とは
3. 可読性を上げるメリット
4. 可読性が下がってもいい場合
5. 最後に
6. 参考

# 1. 背景
今まで業務で変数の命名、設計ともに知識があやふやなまま実装していました。
それによる弊害として以下がありました。
- 仕様変更、機能追加対応によるデグレ、修正漏れ等が起こりやすくなった
- 新規参集者がデグレを恐れてコーディングが億劫になる、それによって実装スピードが低下する
- コード自体の実装が良くないのでテストコードが書きづらい、それによってさらにデグレが起こりやすくなる

そこで最近「良いコード／悪いコードで学ぶ設計入門」という本を軽く1周しました。
２周目である今回はそこで触れられる内容を深掘りして理解を深め、業務に落とし込みたいと思った為です。

# 2. 可読性とは
コードの意図や関係する処理の流れの読解のしやすさです
（良いコード／悪いコードで学ぶ設計入門から引用）

当たり前かもしれませんが抽象的なものを扱う際は脳に負荷がかかります。
>Our brains need to do more work when dealing with abstractions.

[Psychology of Code Readability](https://medium.com/@egonelbre/psychology-of-code-readability-d23b1ff1258a)

以下は極端ですが変数を使った例です。
```js:可読性が低い
const a = 0.1;
```

```js:可読性が高い
const CONSUMPTION_TAX = 0.1;
```

aという抽象的な変数名の為、周辺のソースを見て何の為にこの変数が宣言されたのかを理解しないといけません。

# 3. 可読性を上げるメリット
個人に収まらずチームにとって長期的なメリットをもたらします。

- 既存コードを読む時間が減り、他の時間に使える
- バグの原因を特定する時間の短縮
- 必要以上に前後を追って読む必要がない
- コードレビューがしやすい
- 機能追加、修正時に今後起こるリスクの把握ができるようになる
- 以下が不要になリます
    - コメント
    - 仕様書に詳細なロジックを書くこと
    - 新規参集者にコードの説明
        - ちなみに自分の書いたコードは半年経てば忘れてしまって、他人が書いたコードみたいに思えてしまいます（リーダブルコードから引用）
- 開発スピードの向上
- コードの再利用が容易
- アルゴリズムを見直しやすくなりパフォーマンス向上に繋がる
- リファクタリングがしやすくなりさらにより良い設計、実装ができる
- フレームワークの移行、言語の書き換え等がしやすい
- githubcopilot等、コード自動生成補助ツールの精度が上がる
- コードの重複実装を防ぎ、最低限必要なコードしか実装しなくて済む
- コードを書くのが楽しくなる
- エンジニアのスキル向上をさらに活性化させる

# 4. 可読性が下がってもいい場合
- プログラムコードを読んで解析されたくない
- 人間にとっての読みやすさよりサイズ縮小が最優先

buildツールでよく見るminifyがその例です。

https://vitejs.dev/config/build-options#build-minify

# 5. 最後に
- 可読性について改めて考え直すきっかけになりました。
- これから命名、設計等深掘りして記事でアウトプットしていきます！
- この記事が可読性を意識した実装をするきっかけになれば幸いです！

最後に以下、Donald Knuth’sさんの文を引用します。
>Let us change our traditional attitude to the construction of programs: Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do

## プログラムの構築に対する従来の態度を改めよう： 私たちの主な仕事は、コンピューターに何をすべきかを指示することだと考えるのではなく、コンピューターに何をさせたいかを人間に説明することに集中しよう。

# 6. 参考
- [プログラムの可読性は何故大事か？](https://www.capa.co.jp/archives/7383)
- [【プログラミング】コードの可読性について](https://deliv.tech/2022/03/03/%E3%80%90%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%91%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E5%8F%AF%E8%AA%AD%E6%80%A7%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)
- 良いコード／悪いコードで学ぶ設計入門―保守しやすい 成長し続けるコードの書き方（技術評論社）
- リーダブルコード―より良いコードを書くためのシンプルで実践的なテクニック（O'Reilly Japan）
- [可読性を高める2つの大きな方向性 - 脳内メモリに優しいコードを書く -](https://zenn.dev/n_harada/articles/readability-guideline)
- [プログラミングでコードを綺麗に書く隠れたメリット！綺麗に書こうとする意識がメリットを呼ぶ！](https://alivetodayblog.com/code-writecleanly-merit/)
- [可読性](https://dic.nicovideo.jp/a/%E5%8F%AF%E8%AA%AD%E6%80%A7)
- [質の良いソースコードは何をもたらすのか](https://climbing.on-sight.biz/webtech/2431/)
- [読みやすいコードがもたらすメリット](https://www.codegrid.net/articles/2019-readable-code-hint-1/)
- [A Process for Readable Code](https://jaidevd.com/posts/code-readability-process/)
- [Why your code is so hard to understand](https://medium.com/on-coding/why-your-code-is-so-hard-to-understand-83057c115a2b)
- [Psychology of Code Readability](https://medium.com/@egonelbre/psychology-of-code-readability-d23b1ff1258a)
【AWS】Codebuildのエラー「 YAML_FILE_ERROR Message: YAML file does not exist」の原因

# エラー内容
AWS Codebuildを利用してビルドを行ったら以下のエラーになりました。

```
[Container] 2023/10/19 02:18:10 Waiting for agent ping
[Container] 2023/10/19 02:18:11 Waiting for DOWNLOAD_SOURCE
[Container] 2023/10/19 02:18:12 Phase is DOWNLOAD_SOURCE
[Container] 2023/10/19 02:18:12 CODEBUILD_SRC_DIR=/codebuild/output/src1489528821/src
[Container] 2023/10/19 02:18:12 Phase complete: DOWNLOAD_SOURCE State: FAILED
[Container] 2023/10/19 02:18:12 Phase context status code: YAML_FILE_ERROR Message: YAML file does not exist
```


# 原因と解決方法
エラーメッセージは、`DOWNLOAD_SOURCE`フェーズで`YAML`ファイルが見つからない、と言っています。
ビルドプロジェクトのソースコードをダウンロードする際に、指定された`YAMLファイル`が存在しないためエラーになったのです。

CodeBuildで設定していた`YAML`ファイルはデフォルトのまま`buildspec.yaml`でした。
`buildspec.yamlファイル`とは、CodeBuildでビルドプロジェクトを実行する際に使用されるビルドスクリプトの設定ファイルのこと。

今回は、このファイルが存在しない状態でビルドしていたため、エラーが発生しました。
（作るのを忘れていました...）

設定箇所は、具体的には以下になります。

```
CodeBuild -> ビルドプロジェクト -> 編集 -> Buildspec
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/2991b989-31ff-c1c9-fc6c-adf0aa0fdc04.png)

親切に説明も記載されています。

> CodeBuild のデフォルトでは、buildspec.yml という名前のファイルがソースコードルートディレクトリで検索されます。buildspec ファイルに別の名前または場所を使用している場合は、ここにソースルートからのパス (buildspec-two.yml や configuration/buildspec.yml など) を入力します。

デフォルトから編集していないので、ソースリポジトリのプロジェクトルート直下にpushしてあげると解決します。

ちなみに、`buildspec.yaml`は以下のような形式で作成します。

```yaml
version: 0.2
phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
  build:
    commands:
      - echo Build started on `date`
      - echo Logging in to Docker Hub...
      - docker --version
      - docker login -u $USER_DOCKER -p $DOCKER_KEY
      - echo Building the Docker image...
      - docker build -t $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$REPOSITORY:latest .
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$REPOSITORY:latest
      - echo Writing image definitions file...
      - printf '{"name:"XXXXX","imageURI":"%s"}' $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$REPOSITORY:latest > imageDetail.json
      - cat imageDetail.json
artifacts:
  files:
      - imageDetail.json
  discard-paths: yes
  ```

`$AWS_DEFAULT_REGION`や`$AWS_ACCOUNT_ID`は環境変数で、AWS Codepipelineのビルドステージで設定することができます。ビルドが開始される前にビルド環境に読み込まれるものなので、AWSの各種リソースにアクセスするための認証情報、Dockerレジストリにログインする際に必要な情報などを設定します。`buildspec.yaml`に直接書いても良いですが、セキュリティ上の理由から実際の値は書かずに環境変数としてAWS側(他にもSecret ManagerやParameter Store等)で持たせることが多いと思います。
3 行 3 列の整数の入力 Python3編

問題をいくつか飛ばしてこんな問題。
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__matrix_data_step1

> 3 行 3 列の行列が与えられます。上から i 番目、左から j 番目の整数は a_{i,j} です。
> 3 行 3 列の行列をそのまま出力してください。

まあ何も考えんとやれば。。。
```py
print(input())
print(input())
print(input())
```
となるけどそんなわけもない。
二次元配列を入れる方法で考えていく

```py
arr = []
for i in range(3):
    value = list(map(int,input().split(" ")))
    arr.append(value)

for i in range(3):
    print(*arr[i])
```
見慣れない方法だけど、
print() でリストを出力するときに、先頭に * をつけることで、リストの要素を半角スペースで区切った文字列を出力することが可能、らしいです。

これは[別のところ](https://qiita.com/Atsulabo/items/30771f66ff2b86ea98c4)でコメントで教えていただいたところにあって
これはなんだろう？と思って調べたやつでした。
ありがとうございます！
TypeScript の .d.ts で string? や T? と書いてもエラーにならないと思ったら skipLibCheck: true になっていた件について

# TL;DR (結論を3行で)

- TypeScript では型 `T?` は許容されていない (2023年10月現在)
- JSDoc では `T?` と書ける
- `.d.ts` ファイルでは `T?` は許容されていないが、`skipLibCheck: true` にすると許容される

# なんか書いてみたら通ってしまった

TypeScript で `.d.ts` ファイルには型定義を書くことができ、たとえば以下のようになります。


```typescript:正しい型定義.d.ts
declare interface Hoge {
  myNum?: number;
  myStr?: string;
}
```

しかし、ある日うっかり以下のようなコードを書いてしまいました。

```typescript:誤った型定義.d.ts
declare interface Hoge {
  myNum: number?;
  myStr: string?;
}
```

後日このコードは誤りであることが分かったものの、vscode でも tsc でもエラーは出ていませんでした。なぜなのでしょうか？

# skipLibCheck を false にするとエラーが出る

`tsconfig.json` に `skipLibCheck: false` を設定するとエラーが出てきて、それが原因だったことが分かりました。

> ### skipLibCheckの挙動
> true を設定することで *.d.ts ファイルに対する型チェックをスキップすることができます。

https://t-yng.jp/post/skiplibcheck

```diff_json:tsconfig.json
 {
   "compilerOptions": {
-    "skipLibCheck": true,
+    "skipLibCheck": false,
     ...
   }
 }
```

```typescript
src/sample.d.ts:2:10 - error TS8020: JSDoc types can only be used inside documentation comments.

2   myNum: number?;
           ~~~~~~~

src/sample.d.ts:3:10 - error TS8020: JSDoc types can only be used inside documentation comments.

3   myStr: string?;
           ~~~~~~~
```

これは JSDoc で使われる型定義の書き方で、TypeScript ではこのように書くことはできないそうです。

# JSDoc では T? と書ける（らしい）

エラーメッセージによると JSDoc というライブラリでは Nullable types を `T?` のように書くことができるそうですが、JSDoc のリファレンスには `?T` のように ? を前置する書き方しか記載されておらず、`T?` というように ? を後置する書き方についての公式的な記載は見つけられませんでした。

https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html

> Nullable types only have meaning if strictNullChecks is on:
>
> ```typescript
> /**
>  * @type {?number}
>  * With strictNullChecks: true  -- number | null
>  * With strictNullChecks: false -- number
>  */
> var nullable;
> ```

が、どうやら書けるようです。

https://zenn.dev/qnighy/articles/56917d9bf9077b#jsdoc%E5%86%85%E3%81%AE%E5%9E%8B%E3%81%AE%E6%A7%8B%E6%96%87

> - ?T, T?
>   - 前置と後置に意味的な違いはない。
>   - strictNullChecksが無効の場合は ? は無視され、中身 T がそのまま使われる。

# vscode では一応 `T | null` に解釈される

TypeScript で `T?` が `T | null` または `T | undefined` または `T | null | undefined` のいずれに解釈されるべきなのかという話については色々な意見がありますが、試してみたところ、一応 vscode 上では `T | null` と解釈されるようです。(`any` にはならない)

```typescript
(property) Hoge.myNum: number | null
```

![2023-10-31_02h59_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78152/de8bac2d-1375-2a82-1e9f-83f4e2ab8098.png)

（参考：一方で optional property は `T | undefined` と解釈されます。）

https://typescriptbook.jp/reference/values-types-variables/object/optional-property
JavaScriptにおける浅い比較（Shallow Comparison）と深い比較（Deep Comparison）

JavaScriptでオブジェクトや配列の同等性を正しく扱うためには、浅い比較と深い比較の違いを理解することが重要です。特に、複雑なデータ構造を扱う場合や、Reactのようなライブラリでの状態管理、コンポーネントの再レンダリングの最適化において、この知識は不可欠です。

## **浅い比較（Shallow Comparison）とは何か？**

浅い比較は、二つのオブジェクトや配列をそれらの実際の内容ではなく、参照に基づいて比較するプロセスを指します。

### **浅い比較の特徴：**

- **参照ベース**：オブジェクトや配列の参照が同じかどうかをチェックします。
- **表面的なレベル**：オブジェクトの属性や配列の要素は考慮しません。
- **効率性**：メモリアドレスだけを比較するため、より速く、リソースをあまり消費しません。

### **例：**

JavaScriptの浅い比較は**`===`** 演算子を使用します。

```jsx
const objectA = { key: 'value' };
const objectB = { key: 'value' };
const objectC = objectA;

console.log(objectA === objectB); // 異なる参照なので、falseを出力
console.log(objectA === objectC); // 同じ参照なので、trueを出力
```

## **深い比較（Deep Comparison）とは何か？**

深い比較は単なる参照確認をせずに、オブジェクトや配列に格納されたデータを徹底的に比較します。

### **深い比較の特徴：**

- **値ベース**：オブジェクトや配列の実際のデータと構造を比較します。
- **深さ**：ネストされた全てのオブジェクトや配列の値まで目を向けます。
- **リソース集約型**：全ての要素の詳細な比較が必要なため、より複雑で遅くなります。

### **例：**

JavaScriptには深い比較機能を持つ組み込み関数はありません。そのため、自分で実装するか、Lodashのようなライブラリを使用します。

**LodashのisEqual**

```jsx
const _ = require('lodash');

const object1 = { key: 'value', inner: { number: 1 } };
const object2 = { key: 'value', inner: { number: 1 } };

console.log(_.isEqual(object1, object2)); // true
```

## **浅い比較と深い比較の選択**

アプリケーションの特定の要件に応じて、浅い比較と深い比較のどちらを使用するかを選択します。

- **浅い比較**：二つの変数がメモリ上の同じオブジェクトや配列を指しているかどうかを確認する場合に使用します。
- **深い比較**：二つの異なるオブジェクトや配列の全てのデータを比較する必要がある場合に使用します。

## **結論**

JavaScriptで浅い比較と深い比較を理解することは、データ比較を効果的に扱うために不可欠です。浅い比較はメモリ上の参照同等性を確認するために使われ、効率的です。一方で、深い比較はオブジェクトや配列の実際の内容を詳細に検証するために使用されますが、より複雑で計算コストがかかります。どちらの方法を選ぶかは、アプリケーションのパフォーマンス要件とデータの構造に基づいて慎重に判断する必要があります。
CODから結晶構造ファイル一式をダウンロード（ログ）

# 目標設定
COD（Crystallography Open Database）からcifファイル一式をローカルドライブ（外付けSSD）にダウンロードする．

[1] Crystallography Open Database
https://www.crystallography.net/cod/index.php


## 流れ
1. [2]から圧縮ファイルをローカルにダウンロードする．（今回はSSD上にダウンロードした．）
2. 1. の圧縮ファイルを解凍する．


[2] Obtaining COD
https://wiki.crystallography.net/howtoobtaincod/



## 実行の詳細ログ
#### 圧縮ファイルをダウンロード
```terminal
pwd
```
/mnt/ssd_elecom_black_c2c_480G


```terminal
ls -CF
```
'$RECYCLE.BIN'/  'System Volume Information'/


```terminal
wget http://www.crystallography.net/archives/cod-cifs-mysql.txz
```
--2023-11-01 16:59:16--  http://www.crystallography.net/archives/cod-cifs-mysql.txz
Resolving www.crystallography.net (www.crystallography.net)... 158.129.170.82, 198.97.190.53, 193.0.14.129, ...
Connecting to www.crystallography.net (www.crystallography.net)|158.129.170.82|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 16199786560 (15G)
Saving to: ‘cod-cifs-mysql.txz’

cod-cifs-mysql.txz            100%[=================================================>]  15.09G  7.39MB/s    in 35m 5s

utime(cod-cifs-mysql.txz): Operation not permitted
2023-11-01 17:34:22 (7.34 MB/s) - ‘cod-cifs-mysql.txz’ saved [16199786560/16199786560]



```terminal
ls -CF
```
'$RECYCLE.BIN'/  'System Volume Information'/   cod-cifs-mysql.txz*


#### 圧縮ファイルを解凍
```terminal
sudo time tar Jxvf cod-cifs-mysql.txz
```
（略）
1606.69user 876.08system 4:56:49elapsed 13%CPU (0avgtext+0avgdata 9972maxresident)k
0inputs+0outputs (1major+796minor)pagefaults 0swaps


```terminal
ls -CF
```
'$RECYCLE.BIN'/  'System Volume Information'/   cif/   cod-cifs-mysql.txz*   mysql/


#### 解凍後のディレクトリのサイズを確認
（ -s：指定したディレクトリの総容量だけを確認，-h：サイズを適切な単位で表示 ）

```terminal
du -s -h mysql/
```
515M    mysql/


```terminal
du -s -h cif/
```
92G     cif/
Prophetを使用した株価予測

このコードは、特定の株式の過去の価格データを取得し、そのデータに基づいて将来の株価を予測するためのPythonスクリプトです。主に次のステップで構成されています：

1. **必要なライブラリのインポート**:
    - `datetime`と`pandas`はデータ操作に使われます。
    - `Prophet`は時系列予測に使われるFacebookのライブラリです。
    - `plotly.graph_objs`はインタラクティブなグラフ作成に使用されます。
    - `pandas_datareader`は金融データの取得に使用されるライブラリです。

2. **`pandas_datareader`のインポートチェック**:
    - `pandas_datareader`がインストールされていない場合、エラーメッセージを表示してスクリプトを終了します。

3. **株価データ取得関数（`get_stock_data`）**:
    - この関数は指定された銘柄コード（`meigara_cd`）、開始日（`from_date`）、終了日（`to_date`）に基づいて株価データを取得します。
    - `pandas_datareader`を使用して、Stooqデータソースからデータを取得します。

4. **データ取得の実行**:
    - スクリプトは特定の銘柄コード（ここでは"9104"）と期間（2020年1月1日から今日まで）についてデータを取得します。

5. **データが正常に取得できた場合の処理**:
    - 取得した株価データをProphetが読み取れる形式に変換します。
    - Prophetモデルを作成し、株価データでモデルを学習（フィット）させます。
    - 未来の365日間の予測を行います。

6. **予測結果の可視化**:
    - `plotly`を使用して予測結果をグラフ化します。これには予測値、予測の上限と下限、実際の株価が含まれます。
    - このグラフはHTMLファイルとして保存され、ブラウザで開くことができます。

7. **エラーハンドリング**:
    - データ取得に失敗した場合、エラーメッセージが表示されます。

このスクリプトは、株価予測に関心のあるユーザーや開発者にとって有用です。ただし、株価予測は非常に複雑で、多くの不確実性を含むため、実際の投資判断には慎重に使用する必要があります。

銘柄や開始日等は適時修正してください。
また銘柄によってはAdj Close (調整後終値)にしたほうが良いかと思われます。



``` python
import datetime
import pandas as pd
from prophet import Prophet
import plotly.graph_objs as go

# pandas_datareaderのインポートを試みる
try:
    from pandas_datareader import data as pdr
except ImportError:
    raise ImportError("pandas_datareaderがインストールされていません。")

# 株価データ取得関数
def get_stock_data(meigara_cd, from_date, to_date):
    try:
        df = pdr.DataReader(name=meigara_cd + ".JP", data_source='stooq', start=from_date, end=to_date)
        return df
    except Exception as e:
        print(f"データ取得中にエラーが発生しました: {e}")
        return None

# データ取得
meigara_cd = "9104"  # 銘柄コード
from_date = "2020-01-01"  # 開始日
to_date = str(datetime.date.today())  # 終了日

data = get_stock_data(meigara_cd, from_date, to_date)

# データが正常に取得できた場合のみ処理を続ける
if data is not None and not data.empty:
    # Prophet用インプットデータ
    df = pd.DataFrame({"ds": data.index, "y": data["Close"]}).reset_index(drop=True)

    # インスタンス化と学習
    proph = Prophet()
    proph.fit(df)

    # 予測用のフレーム
    future = proph.make_future_dataframe(periods=365)

    # 時系列を予測
    forecast = proph.predict(future)

    # Plotlyグラフの作成
    fig = go.Figure([
        go.Scatter(x=forecast['ds'], y=forecast['yhat'], name='予測値'),
        go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill=None, mode='lines', line={'color': 'lightgrey'}, showlegend=False),
        go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill='tonexty', mode='lines', line={'color': 'lightgrey'}, showlegend=False),
        go.Scatter(x=df['ds'], y=df['y'], name='実際の値', mode='markers')
    ])

    # グラフをHTMLファイルとして保存し、ブラウザで開く
    fig.write_html("stock_forecast.html")
    print("グラフは 'stock_forecast.html' に保存されました。")
else:
    print("データ取得に失敗しました。")

```
整数の組からの選択 Python3編

いくつか問題を飛ばして今回はこれ
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__pair_data_step3


> 1 行目に整数 N が与えられます。
> 2 行目以降に、N 組の整数 a_i と b_i が N 行で与えられます。(1 ≦ i ≦ N)
> 8 組目の a_i と b_i を出力してください。


わたしはというと、とりあえず文字列のまま配列に入れて７番目のを出力という方法。
でも可読性は悪いなと感じている。
これはN組というのは次元を暗示しているので普通なら配列に入れてやらないといけないと思う。

 ```py
 N = int(input())
arr = []
for i in range(1,N+1):
   arr.append(input())
   
print(arr[7])
 ```
なので再度考える

```py
N = int(input())
a = []
b = []
for i in range(N):
    a_value, b_value = map(int, input().split())
    a.append(a_value)
    b.append(b_value)

print(a[7], b[7])

```
 あれ？　あれれれれ？
 ８組目。。。。
あっそっか、
０から数えても１から数えても、結局配列には0から入れていくわけで、
結局７になるんだ、なるほど。
Swiftのデリゲートとは?

# デリゲートとは?
デリゲートは、一つのクラスが他のクラスに特定のタスクを委任するための設計パターンです。これは、クラス間の通信を可能にし、特にiOSでは頻繁に使用されます。

具体的には、デリゲートはプロトコルを使用して定義されます。デリゲートの役割を果たすクラスは、このプロトコルに準拠し、必要なメソッドを実装します。一方、デリゲートを設定するクラスは、デリゲートのメソッドを呼び出すことで、デリゲートの役割を果たすクラスにタスクを委任します。

このように、デリゲートはクラス間の疎結合を実現し、コードの再利用性と柔軟性を向上させます。
疎結合とは、クラス間の依存性を最小限に抑える設計原則の一つです。これにより、一部の変更が他の部分に影響を与えにくくなり、コードの再利用性と保守性が向上します。

デリゲートは、この疎結合を実現する一つの手段です。具体的には、デリゲートを使用するクラスは、デリゲートの役割を果たすクラスの具体的な実装に依存せず、プロトコルに定義されたメソッドのみを呼び出します。これにより、デリゲートの役割を果たすクラスの内部実装が変更されても、デリゲートを使用するクラスには影響が出ません。

## デリゲートの使用例

```swift
// デリゲートの定義
protocol SampleDelegate {
    func didSomething()
}

// デリゲートを使用するクラス
class SampleClass {
    var delegate: SampleDelegate?

    func doSomething() {
        // 何かの処理
        delegate?.didSomething()
    }
}
```

以下に、デリゲートを使用して疎結合を実現する例を示します。

```swift
// デリゲートの定義
protocol PrinterDelegate {
    func printDocument()
}

// デリゲートを使用するクラス
class Document {
    var delegate: PrinterDelegate?

    func print() {
        delegate?.printDocument()
    }
}

// デリゲートを実装するクラス
class Printer: PrinterDelegate {
    func printDocument() {
        print("ドキュメントを印刷しました")
    }
}

let document = Document()
let printer = Printer()

// デリゲートの設定
document.delegate = printer

// メソッドの実行
document.print()  // "ドキュメントを印刷しました"が出力される
```

## 最後に
### 疎結合
疎結合とは、各クラスやモジュールが互いに独立していて、一部が変更されても他の部分に影響を与えにくい設計のことを指します。デリゲートは、この疎結合を実現する一つの手段です。具体的には、デリゲートを使用することで、一部の処理を別のクラスやモジュールに委譲することができ、その結果、クラスやモジュール間の依存関係を減らすことができます。

## モジュール
モジュールとは、関連するコードをまとめたものを指します。モジュールは、関数、クラス、変数などを含むことができます。モジュールは、コードの再利用性を高め、コードの管理を容易にするために使用されます。また、モジュールは、名前空間を提供し、コードの衝突を防ぐ役割も果たします。


ソフトウェアの開発では、難しい専門用語が多くてコンピュータの知識がいるな〜と思いました。
ThinkPad X250をWindows11にしてみた

ジャンク品を買って直して使っている私のThinkPad X250。
Core i5-5300U(第5世代)でまぁ古くもないが新しくもないノートPCです。
SSDはSanDiskの240GBにクローンして換装。メモリは8GB。最低限で開発試作するような使い方をしています。
Python3.12とArduino IDE、VSCodeで十分IoT開発は可能だけど、正直メモリはもうちっとほしい。
サイズ、キーボードともに使い勝手が良いのでもうしばらく使いたい、という動機でWindows11化へ。

:::note warn
作業の最初に下記コマンドでプロダクトキーはメモっておいてください。
できれば回復ディスクUSBもつくっておくべき。
```
wmic path SoftwareLicensingService get OA3xOriginalProductKey
```
:::

さて、本題のWindows11化。結論から言うとちゃんとできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283529/7fc90f0b-4823-4d24-67d9-3a11b06e02c6.png)


皆さんご存じの通りX250はばっさり切り捨てられた世代ではあるのですが、公式情報としても入れられることになっているらしい。

:::note alert
最初にいっておくと、結構めんどくさいぞ！これ！
よくわからん人は絶対やらないほうがよい。私は一切の責任は負えません。
GPT変換のところはミスると起動しなくなります。自己責任でお願いします。
:::

調べてみると、Windows11の要求スペックに対してNGだったのは以下。

:::note info
①Core第8世代以降のCPU ⇒ 第5世代
②TPM2.0 ⇒ TPM1.2
③BIOS ⇒ UEFI
:::

①は、レジストリに一つ加えると回避できる。

:::note info
・コマンドプロンプトから「regedit」でレジストリエディタ起動。
・「HKEY_LOCAL_MACHINE¥SYSTEM¥Setup¥MoSetup」を新規作成。
・「AllowUpgradesWithUnsupportedTPMOrCPU」DWORD（32ビット）キーを新規作成。値は1にする。
:::

②と③はBIOSの「Security Chip」と「Secure Boot」の項目を変更するとできるのだが、UEFIが曲者だった。まず、BIOSをUEFIにするとWindowsが起動しない。
「UEFIの場合、ブートに使用するドライブはGPT形式でなければならない」
という制約があり、今使っているのがMBRだったのだ。

https://tobiinu.com/2021/10/21/x240-windows11/
↑のサイトに非常に丁寧に書かれていたので、ここを参考にMBR⇒GPT変換する。

変換前に下記コマンドでチェックすると
```
mbr2gpt /validate /disk:0 /allowFULLOS
```

「Cannot find OS partition(s) for disk 0」
というエラーが発生。
https://www.diskpart.com/gpt-mbr/mbr2gpt-cannot-find-os-partition-7201.html
上記サイトで解決したのだが、記述がわかりづらい。
コマンドプロンプト（管理者権限で起動する）に打ち込む文言は以下のとおり。OSのドライブレターはCドライブのままでよいので変更不要。

```
diskpart
select disk 0
list partition
select partition 1
assign drive letter=B
exit
```

上記でBドライブにブート領域が割り当てられて見えるようになるので、bcdeditコマンドで全パラメータを表示する。
```
bcdedit /store B:\boot\bcd /enum all
```
「device = ramdisk=[unknown]」となっている箇所のidentifierをコピーする。
({}もつける)
以下のコマンドでパラメータを削除する。
```
bcdedit /store B:\boot\bcd /delete {XXXXXXXXX-XXXX-XXXX-XXXXXXXXXX}
```

再度、下記コマンドでチェックしてエラーが発生しなければ検証はOK。
```
mbr2gpt /validate /disk:0 /allowFULLOS
```

いよいよ本番の変換を実行。
```
mbr2gpt /convert /disk:0 /allowFULLOS
```

変換が正常終了したら、再起動してF1連打してBIOS設定にはいる。
TMPとUEFIを切り替える。

:::note info 
・TMP2.0にするには「Security Chip」を「Intel PTT」に変更。
・「Secure Boot」を「Enable」に変更。
　「UEFI/Legacy Boot」設定が「UEFI Only」に自動的に変更される。
:::

Saveして起動。Windows10が起動すればOK。

:::note alert
起動しなかったら・・・まずはBIOSを戻す。
戻してダメならおそらく回復ディスクからの復旧が必要です。。。
個別案件なので自己調査願います。ご愁傷さまです。
:::

ここからはよくわからんはまったポイントの事前回避。環境によって異なりますが、私ははまった。

:::note info 
・Office365が入っていたらアンインストールしておいた方がよい。
　(データは残るのでアプリだけ)

・システムファイルチェッカーを実行しておく。(下記サイトの方法 4のみ)
https://answers.microsoft.com/ja-jp/windows/forum/all/windows-10/bc6415a3-678a-4032-8970-3ba14a2b7940

・自動更新を無効にする

・ディスククリーンアップでシステムデータのバージョンアップデータを削除しておく
:::

・「インストールに必要な作業を確認」が5h以上たっても終わらない
・更新が46%で止まる
などの症状が出た場合、これらを試す価値はある。

で、ようやくインストール。isoファイルをダウンロードしマウントしてsetup.exeをたたく。
https://www.microsoft.com/ja-jp/software-download/windows11

2時間くらい放置して完了。
下準備が大変でした。。。
【図解】Git でのブランチマージ戦略まとめ

Gitでのブランチのマージ戦略にはいくつかの主要な方法があります。それぞれの方法には特定の使用シナリオと利点があります。ここでは、最も一般的なマージ戦略をいくつか紹介し、それぞれを図解します。

### **1. Fast-Forward Merge**

**使用シナリオ:** ブランチがベースブランチから分岐して以降、ベースブランチに変更がない場合。

**使い方:** **`git merge <branch>`**

**図解:**

```mathematica
A---B---C  master
         \
          D---E  feature

After Fast-Forward Merge:

A---B---C---D---E  master
```

### **2. 3-Way Merge (No Fast-Forward)**

**使用シナリオ:** ベースブランチとマージするブランチの両方でコミットが行われている場合。

**使い方:** **`git merge --no-ff <branch>`**

**図解:**

```mathematica
A---B---C  master
         \
          D---E  feature

After 3-Way Merge:

A---B---C-------F  master
         \     /
          D---E  feature
```

ここで、Fは新しいマージコミットです。

### **3. Squash Merge**

**使用シナリオ:** マージするブランチのコミット履歴を単一のコミットにまとめたい場合。

**使い方:** **`git merge --squash <branch>`**

**図解:**

```mathematica
A---B---C  master
         \
          D---E  feature

After Squash Merge:

A---B---C---F  master
```

ここで、FはDとEの変更を含む新しい単一コミットです。

### **4. Rebase**

**使用シナリオ:** ブランチのベースを最新のコミットに移動したい場合。これにより、リニアなプロジェクト履歴が保たれます。

**使い方:** **`git rebase master`** (featureブランチ上で実行)

**図解:**

```mathematica
A---B---C  master
         \
          D---E  feature

After Rebase:

             D'---E'  feature
            /
A---B---C  master

```

リベース後、featureブランチはmasterブランチの最新コミットから分岐しています。

これらのマージ戦略は、プロジェクトの要件やチームのワークフローに応じて選択されます。Fast-Forwardと3-Way Mergeは最も一般的に使用される戦略ですが、Squash MergeやRebaseも特定の状況で非常に有用です。
クラスの継承と上書き、プロトコル

### 継承とは?
クラスは他のクラスから継承することができます。これは、一つのクラスが他のクラスの特性を引き継ぐことを意味します。継承するクラスをサブクラス、継承されるクラスをスーパークラスと呼びます。サブクラスはスーパークラスの特性を引き継ぎつつ、新たな特性を追加したり、既存の特性を上書きしたりすることができます。

使い方
```swift
class サブクラス : スーパークラス {
    サブクラスで追加・変更するプロパティ
    サブクラスで追加・変更するメソッド
}
```

```swift
class Vehicle {
    var speed: Int = 0
    func accelerate() {
        speed += 10
    }
}

class Car: Vehicle {
    var gear: Int = 1
    func changeGear(to newGear: Int) {
        gear = newGear
    }
}

let car = Car()
car.accelerate()
car.changeGear(to: 3)
print(car.speed)  // "10"が出力される
print(car.gear)   // "3"が出力される
```

### 継承したクラスを上書きする
`override`(上書き)を使用すると、継承したクラスのメソッドを上書きすることができます。車というクラスのメソッドを継承したトヨタというクラスが上書きして、メソッドの処理を書き換えることができます。

```swift
// 継承されるスーパークラス
class Car {
    // プロパティ
    let name : String = "車"
    
    func start() -> () {
        print("これは\(name)です。")
    }
}

// 継承するサブクラス
class Toyota : Car {
    let price : Int = 3000000
    
    // メソッドを上書きして処理を書き換える。
    override func start() {
        super.start()
        print("これは¥\(price)のToyota製の\(name)です")
    }
}
let toyota = Toyota()
toyota.start()
// log
// これは車です。
// これは¥3000000のToyota製の車です
```

### プロトコルを使った継承
Swift のプロトコルは、型のインターフェースを定義するものです。具体的な処理内容は書かず、クラスや構造体が実装するプロパティとメソッドを定義します。﻿

- プロトコルのメリットは次のとおりです。﻿
- 実装を後から変更できる
- 複数のプロトコルを適用できる
- 柔軟性が高い
- 抽象化できる

```swift
// 抽象クラスのように使える
protocol Car {
    func start()
    func stop()
}

// クラスで継承する場合
class Toyota : Car {
    
    func start() {
        print("ランクルのエンジンをかける!")
    }
    
    func stop() {
        print("ランクルのエンジンを停止する")
    }
}

// クラスをインスタンス化する
let toyota = Toyota()
toyota.start()
toyota.stop()

// 構造体で継承することもできる
struct Nissan : Car {
    
    func start() {
        print("エクストレイルのエンジンをかける!")
    }
    
    func stop() {
        print("エクストレイルのエンジンを停止する")
    }
}

// 構造体をインスタンス化する
let nissan = Nissan()
nissan.start()
nissan.stop()
```

## 最後に
Swiftの勉強を１年以上前にやってたのですが、その頃は今以上に継承とかインターフェースについて理解してませんでした。
CやJavaをやっている人だと、インターフェースやクラスの継承を使ったことがあるので、オブジェクト指向を理解しているから、キャッチアップが早いのでしょうね。
私は、Dartを使って設計の勉強をしてからやっと理解できました💦

SwiftやKotlinだと、継承するときに `:` を使うので、`extendes`に慣れていると違和感を感じます💦
しかし、コードを短く書けるので可読性は高いのかなと思いました。
SSH公開鍵認証をざっくりと

GitHubは現在、SSH公開鍵認証にて認証を行っている。
クライアントで秘密鍵と公開鍵を作成して、GitHubに公開鍵を登録するという流れで設定することができる。

設定方法はググれば山程出てくるが、このSSH公開鍵認証がどのような流れで認証しているのかが気になったため、簡単な流れを残しておく。

## 【気になりポイント】
* GitHub側ではなく、クライアント側が秘密鍵を持っているのはなんでだっけ？
    * よくある公開鍵暗号方式の説明としては、自身で秘密鍵と公開鍵を作成してファイルを暗号化し、公開鍵と暗号化ファイルを相手に渡してファイルを復元してもらうというもの。
* GitHubに公開鍵を渡してどんなことをしているのだろう？

## 【認証の流れ】
Git側が確認したいのは、相手がGitに接続許可のあるユーザーであるということ。
そのため、Git側で秘密鍵と公開鍵を作成して公開鍵を渡してしまうと、作成して公開鍵を持っているユーザーが誰でもアクセス可能となってしまう。

* ユーザー側で秘密鍵と公開鍵を作成する。
* GitHubに公開鍵を登録する。
* 認証時、まずGitHubは接続してきたユーザー名に紐づく公開鍵があるか確認する。
* ユーザー名に紐づく公開鍵がある場合、その公開鍵を使用してランダムな文字列を暗号化する。
* 暗号化したメッセージをユーザーに送信する。
* ユーザーは受信した暗号化メッセージと秘密鍵を使用して文字列を生成する。
（これがいわゆるデジタル署名）
* 生成した文字列（デジタル署名）をGitHubに返す。
* GitHubはユーザーから受信したデジタル署名と公開鍵を使用してメッセージを生成する。
* 生成したメッセージが暗号化前のメッセージと同じであれば、ユーザーが秘密鍵を持った登録されたユーザーであることを認証する。

## 【セキュリティの利点】
* 秘密鍵の保持
    * 秘密鍵はクライアント側でのみ保持され、ネットワーク越しに送信されることはない。
これにより、秘密鍵の漏洩リスクが低減される。
* 公開鍵暗号方式
    * SSHは公開鍵暗号方式を使用しているため、公開鍵を持っていても秘密鍵を知ることはできない。
つまり公開鍵が漏洩してもセキュリティ上のリスクは低くなる。

このように、SSH公開鍵認証は、安全にサーバーへのアクセスを制御するための効果的な手段となっている。
【Android】アプリ内からGoogle Playのアプリ詳細へ飛ばす方法【Kotlin】

# はじめに
以前、[アプリ内から他アプリのSNSシェアをする](https://qiita.com/Tsubasa12/items/cec04e137ed613d53ccb)　といった記事を書いたのですが、それと似たような内容になります。
短めですが、自分のメモ用と思っていただければと思います。

# 実装

    val uri = Uri.parse("market://details?id=パッケージ名")
    val intent = Intent(Intent.ACTION_VIEW, uri)
    startActivity(intent)


以上になります。 

アプリのレビューを書いてもらう際などに直接アプリページへ飛ばせるので、役立ちそうです。
2 行目で与えられる N 個の文字列の入力 Python3編

次はこれ（例のごとく何題か飛ばしてます（実際はクリアしてますがQiitaで飛ばしているという意味）
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__string_number_step2

1 行目に整数 N,2 行目に、N 個の文字列 s_1, ... , s_N が半角スペース区切りで入力
⇒s_1, ... , s_N を改行区切りで出力　という問題

まあこれも簡単なのですがNを使えていません

```py
N = int(input())
arr = input().split()
for i in arr:
    print(i)

```

まあ使わなくてもいい場合があるのは知ってますがとりあえず使った場合を考えます
とはいってもそんなに差はない。
ポイントはN+1にならないこと（今まではN＋１になってたので）
なぜN+1になるのかなぜNでよいのかというのを理解しておきたいところです


```py
N = int(input())
arr = input().split()
for i in range(N):
    print(arr[i])
```
AWS Global Accelerator のイメージ図

## AWS Global Accelerator のイメージ図
![スクリーンショット 2023-11-19 21.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/c3609dd8-44d3-5670-c2c4-4513b284dd5c.png)

雑な絵ですが、
Public Internet は必ずしも最短経路を通るわけではなく、
複数の事業者のネットワークを経由しながら目的のリージョンまで辿り着く。
AWS Global Accelerator を使えば、近くのエッジロケーションからAWSのネットワーク内の短い経路で目的のリージョンまで辿り着く。
こんなイメージ。

近くのリージョンでは効果が薄いが、
地理的に遠くのリージョンにアクセスする際には効果が大きくなる。
グローバルに展開するサービスに利用される。

### Global Accelerator vs Public Internet
Global Accelerator と インターネット経由のアクセス速度の比較。
各リージョンから両経路でファイルをダウンロードした時の時間を比較し、効果を実感できる。
![スクリーンショット 2023-11-19 21.16.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586577/b5471cdf-9696-e5ad-b3ab-6d428cacc3e2.png)


https://speedtest.globalaccelerator.aws/#/

### 参考

https://tech.nri-net.com/entry/global_accelerator_cloudfront
Selenium Chrome Driver 現在のダウンロードフォルダ指定方法

## Selenium Chrome Driverのダウンロードフォルダの指定が効かない
2023年に入ってからSeleniumでダウンロードフォルダを指定しても有効にならなくなった。
download.default_directoryは、ヘッドレスモードでは使えるようだが、そうでない場合には反映されないようになったようだ。

## 対策
chrome driverのインスタンス作成後に１回だけPage.setDownloadBehaviorを設定すればいいらしい。
ただし、setDownloadBehaviorはDeprecatedになっている。
~~~python:t.py
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService

download_dir = "c:\\test\\" #ダウンロードフォルダ

chrome_service = ChromeService(executable_path= 'C:\\chromedriver\\chromedriver.exe')
driver = webdriver.Chrome(service=chrome_service)

driver.get('http://google.com')
#ここから
params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
driver.execute("send_command", params)
#ここまで
#この後ダウンロードする
~~~

起動時のオプションでadd_argument("--headless=new")にするといいとかいう記載もあったが、ヘッドレスでないときはどうすればいいのかは不明。
正式な対処法が分かるまでは、Page.setDownloadBehaviorを使うしかなさそうである。
Dockerで作るReact環境

Reactの勉強のついでにDockerで環境構築もしたので共有

## 実行環境
Docker Desktop 24.0.2
MacOS 14.1.1
React 18.2.0

## 必要なファイルを作成
今回必要になるのは、Dockerfile, .dockerignore, docker-compose.ymlの３つ。
touchコマンドでファイル名を波括弧でくくると、複数ファイルが同時に作れるのは知らなかった。。。

```zsh
touch {Dockerfile,.dockerignore,docker-compose.yml}
```


#### Dockerfile
まずはDockerFileを作成します。これが無いとどうにもならん。
今回はステージ1と2に分けてマルチステージビルドしています。
不必要なファイルを排除して、イメージサイズを軽量化するためです。

```Dockerfile
# Stage1
# dockerhubを参照して、最新のnodeのイメージを使用。ステージ2ではbuilderという名前で使用する。
FROM node:21-alpine AS builder
# 後続のコマンドが実行されるディレクトリをコンテナ内の/appに設定
WORKDIR /app
# ローカルのpackage.jsonとpackage-lock.jsonをコンテナの作業ディレクトリにコピー
COPY package.json package-lock.json ./
# Node.jsのOpenSSL関連の問題を回避するための環境変数を設定。
# 詳細→https://builtin.com/software-engineering-perspectives/err-ossl-evp-unsupported
ENV NODE_OPTIONS=--openssl-legacy-provider
# package.jsonに定義された依存関係をインストール
RUN npm install
# 全てのソースコードをコンテナ内にコピー
COPY . ./
# アプリケーションのビルド
RUN npm run build

# Stage2
FROM nginx:alpine
# ステージ1でビルドしたソースをNginxのディレクトリにコピー
COPY --from=builder /app/build /usr/share/nginx/html
# listenするポートを設定
EXPOSE 80
# Nginx起動
CMD ["nginx", "-g", "daemon off;"]
```

#### .dockerignore
不要なファイルがdockerイメージに含まれないよう、以下のディレクトリとファイルを指定する。

```
node_modules
build
.git
.env
```

## Dockerイメージのビルド
ターミナルで以下のコマンドを実行して、イメージをビルドする。

```zsh
docker build -t test-react-app .
```

## Dockerコンテナの実行
以下のコマンドを実行してコンテナを実行する。
今回は、ローカルの8080ポートをコンテナの80ポートにマッピングしています。
```zsh
docker run -p 8080:80 test-react-app
```

## いざ確認！
localhost:8080にアクセスすれば、アプリの稼働確認ができるはず。
私のはこんな感じ。(openweathermapというAPIを使って天気予報アプリを作っている途中)
![スクリーンショット 0005-11-19 21.42.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/d2962e0b-4d93-fbb1-cf65-f53401e98f95.png)
CursorやWindsurfを日本語化する方法【忘備録】


今話題のエディタ「**Cursor**」や「**Windsurf**」のメニューバーを日本語化する方法メモ。

下記の手順で日本語できない場合は、まずVSCode拡張機能の「**Japanese Language Pack for Visual Studio Code**」を入れておく必要があるっぽいです。

---

- メニューバーから「**View**」→「**Command Palette**(Ctrl+Shift+P)」を選ぶ。

![cursor_japanese_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/b7ace8c0-f243-4355-627f-11ba7103c345.png)

- 立ち上がったコマンドパレットから「**Configure Display Language**」を選択する。
![cursor_japanese_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/957e6a83-5313-4e12-b2a9-aef09d05fabc.png)

- 「**日本語(ja)**」を選択する。
![cursor_japanese_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/d798ed89-c218-1fd6-73c6-b51159d1609c.png)

- 「日本語に切り替えるためにCursorを再起動するか？」みたいなウインドウが出てくるので、「**Restart**」をクリックする。
![cursor_japanese_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486558/26ed7274-26f7-ff60-9246-bab5469f7bf8.png)

---

### 2025年3月追記：
「**Windsurf**」も同じ流れで日本語化できるはずです。

※上記の手順で日本語できない場合は、まずVSCode拡張機能の「**Japanese Language Pack for Visual Studio Code**」を入れておく必要があるっぽいです。
AI ログの取得補助

ChatGPT や Bard などでは個別のチャットのログ全体を Markdown で取得することができないようです。ChatGPT では全ログをエクスポートすることはできますが、個別ログの取得に使うのは非効率です。

スクレイピング的なことをすると問題になるかもしれないため、ログのコピーは手動で行って、スクリプトでクリップボードを監視することでペーストせずに自動的に記録してみました。

この方法は基本的に手動のためあまり省力化にはなっていませんが、汎用性があるので Bing AI や Claude などでも使えます。

# 追記 2025/5/6

pyperclip で API が変更になったため、スクリプトを修正しました。

https://qiita.com/7shi/items/9e49ff81ceb1196f73a4

記事を書いた当初はログ全体を取得するのに使っていましたが、長いログから選択的に必要な部分だけ抽出するために使うようになりました。

ログ全体を取得するのであれば Obsidian Web Clipper を推奨します。（by @karaage0703 さん）

https://zenn.dev/karaage0703/articles/52c3e016653003

# 準備

Python を使用します。pip などで [pyperclip](https://github.com/asweigart/pyperclip/tree/master) をインストールしてください。

# コード

```python:copy_log.py
import sys, os, re, io, time, pyperclip

if len(sys.argv) != 2:
    print(f"Usage: python {sys.argv[0]} file")
    sys.exit(1)

def waitForNewPaste(timeout=0):
    current = pyperclip.paste()
    start = time.monotonic()
    while True:
        time.sleep(0.1)
        text = pyperclip.paste()
        if text != current:
            return text
        if timeout > 0 and time.monotonic() - start > timeout:
            raise pyperclip.PyperclipTimeoutException(
                f"waitForPaste() timed out after {timeout} seconds.")

def waitForNewPasteLines():
    ret = waitForNewPaste().replace("\r\n", "\n").split("\n")
    while ret and not ret[-1]:
        ret.pop()
    return ret

file = sys.argv[1]
num = 1
while True:
    print("prompt?")
    p = waitForNewPasteLines()
    print("response?")
    r = waitForNewPasteLines()
    with io.StringIO() as sio:
        if os.path.exists(file):
            print(file=sio)
        print("##", num, file=sio)
        num += 1
        print(file=sio)
        for line in p:
            print("    " + line, file=sio)
        print(file=sio)
        code = False
        for line in r:
            if line.startswith("```"):
                code = not code
            if not code and (m := re.match(r"#+(.*)", line)):
                print("**", m.group(1).strip(), "**" ,sep="", file=sio)
            else:
                print(line, file=sio)
        with open(file, "ab") as f:
            f.write(sio.getvalue().encode("utf_8"))
```

# 使用方法

```sh
python copy_log.py log.md
```

プロンプトを手動で選択してコピーします。返答はクリップボードアイコンでコピーします。これを繰り返します。

プロンプトと返答をセットとして、随時ログファイルに追記していきます。終了時は [Ctrl]+[C] でスクリプトを強制終了させれば、そこまでのログは残ります。

GitHub に置くことも考慮して、ログは改行コードを LF に変換しています。

:::note info
WSL で使用するときは、Windows 側に Python をインストールしておいて、`python.exe` で呼び出した方が安定します。
:::

# 関連記事

Bard では公開リンクに期限があります。

https://qiita.com/7shi/items/3de830afa69add8a705c

ログを期間制限なしで公開したいときは、今回のスクリプトで Markdown 化して GitHub に置くような運用を行っています。

ChatGPT では共有リンクに明確な期限は示されませんが、Markdown 化しておくと何かと便利なため、同様に処理しています。
ncnnでColorizationを動かしてみる

## 概要
ncnnで、モノクロ画像からの色推定を行う、Colorizationを動かしてみます。
Colorizationは白黒の画像を入力として、カラー化して出力する機械学習モデルです。一般的に、草は緑で、空は青く、てんとう虫は赤くなります。機械学習モデルは、これらのsemantic（意味）をベースにカラー化を行います。

![Screenshot from 2023-11-19 21-18-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/16976a08-6078-43a4-287d-3206c1871f1a.png)

## 環境構築
構築手順に入る前に、まずPCに以下のバージョンのUbuntuをインストールした環境で、構築しました。

[M5UnitV2のクロスコンパイル環境を構築する手順](https://qiita.com/nnn112358/pbulic/9e15450265b689300216)

```
Ubuntu 22.04.3 LTS(x64)
OpenCV ver 0.4.4
ncnn ver 231027
```

## ncnn-colorization-siggraph17のダウンロード

GitHubからncnn-colorization-siggraph17のコードをダウンロードします。

```
$ git clone https://github.com/magicse/ncnn-colorization-siggraph17
$ cd ncnn-colorization-siggraph17
```

学習モデルをダウンロードし、modelsフォルダに解凍します。

```
$ wget https://github.com/magicse/ncnn-colorization-siggraph17/releases/download/v1.0.0/models.zip
$ unzip models.zip

$ ls models
siggraph17_color_sim.bin  siggraph17_color_sim.param
```

## CMakeLists.txt ファイルの作成

cmakeでコンパイルするために、CMakeLists.txtを編集します。

```
gedit CMakeLists.txt
```

```CMakeLists.txt
SET(CMAKE_BUILD_TYPE "Release")

SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")

if(TARGET_COMPILER STREQUAL "arm")
    message(STATUS "TARGET_COMPILE STREQUAL arm")
    SET(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
    SET(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
    SET(NCNN_INSTALL_DIR /opt/external/ncnn/install/arm/)
    SET(ZBAR_INSTALL_DIR /opt/external/zbar-0.10/build/arm)
    SET(OpenCV_DIR /opt/external/opencv/build/arm)
else()
    message(STATUS "TARGET_COMPILE STREQUAL X64")
    SET(NCNN_INSTALL_DIR /opt/external/ncnn/install/x64/)
    SET(ZBAR_INSTALL_DIR /opt/external/zbar-0.10/build/x64/)
    SET(OpenCV_DIR /opt/external/opencv/build/x64) 
endif()


PROJECT(color_gan)
cmake_minimum_required(VERSION 3.5)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)

if(OpenCV_FOUND)
 message(OPENCV_VERSION)
 message(STATUS "OpenCV_LIBS: ${OpenCV_LIBS}")
 message(STATUS "OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}")
endif(OpenCV_FOUND)

find_package(OpenCV REQUIRED)

link_directories(${OpenCV_LIBRARY_DIRS})

include_directories(${OpenCV_INCLUDE_DIRS} )
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${NCNN_INSTALL_DIR}/include/ncnn)

add_executable(color_gan main.cpp colornet.cpp)
target_link_libraries(color_gan ${OpenCV_LIBRARIES})
target_link_libraries(color_gan ${NCNN_INSTALL_DIR}/lib/libncnn.a -fopenmp)
```


## ビルド
Ubuntu用のプログラムをコンパイルして実行します。

```shell
$ cmake .
$ make
$ ./bin/color_gan -i test1.jpg 
```
## プログラムの格納先
このプログラムは以下に格納しています。

https://github.com/nnn112358/ncnn-colorization-siggraph17


## 参考資料
この記事を作成するにあたり、以下のウェブサイトを参考にしました。

[richzhang/colorization](https://github.com/richzhang/colorization)

[Colorful Image Colorization](https://richzhang.github.io/colorization/)
2 行目で与えられる N 個の整数の入力 (large)

次はこれ（途中何題か簡単だったので飛ばしてます）
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_number_step4

これも一応簡単な部類に入るんだけど、
内容としてはこんな感じ。

```py
N = int(input())
arr = input().split()

for i in arr:
    print(int(i))
```

で、ここで`map()`というものを使えるようにしようということで
前半をmap()とlist()を使って書いてみます

```py
# map()を使わない書き方
arr = input().split()
for i in arr:
    print(int(i))

# map()を使う書き方（※split()はsplit(" ")でもOK)
arr = list(map(int, input().split()))

#一応、下でもOK（list()がない）だった
arr = map(int,input().split())

#こうすると次のループがeasyに
for i in arr:
    print(i)

```
まだまだ書き慣れてないですが
とりあえず以上で
三度の飯よりターミナル操作が好きな人類におすすめ、inshellisense

# みなさん、bashが好きですか?
## 好きですよね
僕なんかパソコンを立ち上げたら意味もなくターミナルを立ち上げてはとりあえず`whoami`で自分が誰かを聞いています。

今回はみんなが大好きなbashがIDEのように使える様になるinshellisenseを紹介したいと思います。

inshellisenseはGitHubの[microsoft/inshellisense](https://github.com/microsoft/inshellisense)でインストール方法を調べることができます。
# ダウンロード方法/環境設定
ダウンロードにはバージョンが16.x以上のnodeが必要です。個人的にはnodeenvで管理するのがおすすめです。
参考記事->[nodenvでNode.jsのバージョンを切り替える](https://zenn.dev/donchan922/articles/b08a66cf3cbbc5)

node.jsの環境が構築できたら以下のコマンドをターミナルで実行してください‼️
```bash
npm install -g @microsoft/inshellisense
```
これでターミナルを再起動するとinshellisenseが使える様になります。bashの場合はターミナルを立ち上げて以下のコマンドを打ちましょう
```bash
inshellisense --shell bash
```
そうすると...
![スクリーンショット 2023-11-19 20.55.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311006/41c74311-6856-4f87-2527-a44459aac3b9.png)
ターミナルコマンドにIDEのように予測と簡単なコマンドの説明がでるようになりました！
でもこのままではinshellisenseの立ち上げに毎回上のコマンドを打つ必要があり、不便です。
そこで、
```bash
inshellisense bind
```
と打つと, Ctrl+aでターミナルをinshellisenseモードに切り替えることができるようになります。

もしくは、お気に入りのエディターで.bashrc, .zshrcなどを開いて以下の行を追加しましょう。
```bash
alias bashide="inshellisense --shell bash"
```
こうすることでターミナルを再起動したのちにbashideを打つとinshellisenseモードに変わります。
ターミナルを起動したら最初からinshellisenseモードになっていて欲しい人は.bashrc, .zshrcなどを開いて`inshellisense --shell bash`を追加しましょう。
.bashrcや.zshrcはターミナルログイン時に実行されるため、これを書いておくことで最初からinshellisenseのままターミナルが使えます。

# 対応しているコマンド
ざっと思いついたコマンドで、対応しているコマンドを調べてみました
- cat
- cd(予測結果にはやや不満, -と~のみ)
- chmod
- code
- command
- echo
- git
- grep
- less
- ls
- man
- nc
- pwd
- rm
- where
- which
- xargs

# 予測結果が出なかったもの
- lshw
- play
- printenv
- rec
- sox

考えてみれば当たり前ですが、デフォルトのshellにあるコマンドは対応済みなものが多く, brewやaptでダウンロードしたものは対応していないものが多いです。

# 唯一の不満点
![スクリーンショット 2023-11-19 21.18.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3311006/b9cff15e-bb57-9ce3-7d64-07c26192058c.png)
実行中はこんなふうにカレントディレクトリが見えなくなってしまうのでやや使いづらいかなと思います。
今後の発展に期待ですね。
セキュリティーグループのアウトバウンドルールでVPCエンドポイント宛の通信を許可する方法


# はじめに
<!-- 発端や概要を記載 -->
セキュリティーグループのアウトバウンドは設定しないことが多いですが、
セキュリティー要件が厳しいシステムだと細かく制御を求められることがあります。

そんなとき、
「VPCエンドポイント宛の通信ってどうやって指定するんだ？？」、
「そもそもVPCエンドポイントにIPアドレスあったっけ？？」なんてお悩みがわきませんか？？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/eb97e851-eaf5-aacf-76ab-c76db630201e.png)

本記事はそんなお悩みをもった方に向けたものです。

また以降の図ではクライアント側はEC2としていますが、ECSやLambda(VPC内)などセキュリティーグループをアタッチできるリソースは同様の設定方法となります。

<!-- 各チャプター -->
<a id="#Chapter1"></a>

# 1.インターフェース型VPCエンドポイントの場合

## ・VPCエンドポイントのIPアドレスを指定する
まずは素直にIPアドレスを指定する方法です。
インターフェース型のVPCエンドポイントは作成時に指定したサブネット内にてENIが作成されVPCエンドポイントに割り当てられるので、ENIのプライベートIPアドレスを指定することができます。
またこのENIはVPCエンドポイントを削除しない限りは消えないため、IPアドレスが変化することもありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/a0169101-c645-08d9-d6d4-7b3fcac12e66.png)

またVPCエンドポイントを複数作成する場合は、`VPCエンドポイント用のサブネットを用意してサブネットのIP CIDRごと許可する`、といったアプローチも考えられます。
こうすることで設定値の煩雑さを多少軽減できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/3edaaa8b-57f9-7f71-8626-4809d8824a4a.png)

## ・VPCエンドポイントのセキュリティーグループを指定する
次に`VPCエンドポイントに割り当てたセキュリティーグループのID`を指定する方法です。
個別にIPアドレスを設定する必要もなく、
他のVPCエンドポイントとセキュリティーグループを共有することもできるので、
IPアドレス指定に対する熱いこだわりがなければ、この方法がおすすめです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/981c7e72-7473-a534-2b4d-29275f01eff4.png)


<a id="#Chapter2"></a>

# 2.ゲートウェイ型VPCエンドポイントの場合

## ・マネージドプレフィックスリストを指定する
ゲートウェイ型VPCエンドポイントはENIは存在せず、宛先がグローバルIPアドレスとなります。
例として、S3で利用されているIP CIDRのリストは以下ドキュメントに記載があります。
* [AWS IP アドレスの範囲-公式ドキュメント](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/aws-ip-ranges.html#aws-ip-download)

愚直に上記でIP CIDRを調べて設定してもいいですが、
AWS側が予め各IP CIDRを設定したマネージドプレフィックスリストを用意してくれているので、ありがたく使いましょう。
* [マネージドプレフィックス-公式ドキュメント](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/working-with-aws-managed-prefix-lists.html)

セキュリティーグループの送信先としてS3のマネージドプレフィックスリストのIDを指定すれば、一括でS3で利用されているIP CIDRを許可できます。
余談ですがマネージドプレフィックスリストはリージョンごとに固定であり、今現在東京リージョンのIDは`pl-61a54008`です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/c04c372e-31ff-9807-9aee-fc65e02a360d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/1d482a1f-3eaa-f413-7954-0bb131f81d44.png)


<a id="#Chapter3"></a>

## 3-最後に
以上、セキュリティーグループのアウトバウンドルールでVPCエンドポイントを指定する方法でした。

また本記事では記載しませんでしたが、
`VPCエンドポイント側のセキュリティーグループのインバウンドルールで、接続元のIPアドレスを設定する`ということもできます。
正直、個人的にはそこまで細かく制御する意味は薄いと思いますが、
セキュリティー要件の厳しい案件に出会った際は設定を検討してみてください。
【9ヶ月ぶりのセール開催】Adobeのセールきた！公式でもアマゾンでも12/4までセール中！

# Adobeのブラックフライデーセール開催 2023年11月17日から12月4日まで
Adobeの2023年ブラックフライデーセールは11月17日から12月4日までの17日間開催されます。Adobe公式サイトでのセール価格は、いずれもサブスクリプションの新規申込のみが対象となります。また、セール対象は1年間の価格で、翌年からは通常の価格での請求となります。
![スクリーンショット 2023-11-19 21.03.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/9cad3099-795d-bd6d-d99e-fdffe22f6bb1.png)

https://www.adobe.com/jp/?sdid=49F59KY6&clickref=1011lxXDI58z&mv=affiliate&mv2=pz&as_camptype=&as_channel=affiliate&as_source=partnerize&as_campaign=altstack

## Adobe公式サイト ブラックフライデーセール対象製品 
### Creative Cloudコンプリートプラン（個人向け）
* 年間プラン（月々払い）
6,248円 → 3,960円/月（38%OFF）
* 年間プラン（一括払い）
74,976円 → 47,520円（34%OFF）

https://www.adobe.com/jp/creativecloud/plans.html?promoid=R3B5NZKF&mv=other&clickref=1101lxXg8oEj&mv=affiliate&mv2=pz&as_camptype=&as_channel=affiliate&as_source=partnerize&as_campaign=altstack

### Adobe各種ソフトウェア 単体プラン（個人向け）
* 個人向け 
2,728円 → 1,848円/月 (税込)32%OFF
* 個人向け 
28,776円 → 22,176円/年 （税込）22%OFF​

* 個人向けのソフトウェア単体プランも以下の8製品が対象
    * PhotoShop
    * Premiere Pro
    * Illustrator
    * After Effects
    * InDesign
    * Animate
    * Dreamweaver
    * Audition

https://www.adobe.com/jp/creativecloud/plans.html?promoid=R3B5NZKF&mv=other&clickref=1011lxXDIyuQ&mv=affiliate&mv2=pz&as_camptype=&as_channel=affiliate&as_source=partnerize&as_campaign=altstack

### 他のプラン
個人以外に法人向けや学生・教員向けのプランもセール中なので、公式のサイトをチェックしてみてください！！

# Amazonや他のECサイトでもセール価格に！
Amazonや、ベクターPCショップ、ヨドバシ,comなどでもCCコンプリートプランのライセンスパックや、Illustratorライセンスパックなどのセールが開催しています。なおこれらは、新規入会以外＝既存の利用ユーザーも購入でき、サブスクリプション期間に延長＝追加という形で適用できます。

今回は一番話題になっているAmazonのセールについて説明します！

## AmazonのAdobe製品 ブラックフライデー対象製品
Amazonで、Adobe CC コンプリートプランがのセールが開催しています！
最近のセールは10%オフで、35％オフというこの値引き率になるのは実に9ヵ月ぶり！
この機会をお見逃しないように！！！
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/4614a02a-cf56-0701-e5ec-e40e29357e96.png">
<img width="500" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/61a199dd-4520-bebf-e70d-26321a6f7551.png">
この論理ファイルはどの物理ファイルに紐づいているのか？の調べ方

## はじめに

前回はある物理ファイルに対して、どのような論理ファイルが紐づいているのか調べる方法についてご紹介しました。

今回この記事では、ある論理ファイルが、どの物理ファイルに紐づいているのか調べる方法についてご紹介します。


## 調べ方

1. `STRPDM`
2. 「2. オブジェクトの処理」を実行
3. 対象の論理ファイルを指定
4. オプション「5= 表示」を対象の論理ファイルに対して実行する

上記の手順を実行すると、（画像１）のような結果が表示されます。

「基となるファイル／ライブラリー」に記述されているファイルが、紐づいてる物理ファイルです。

（画像１）
![searchLfPf_01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/c1dff974-5738-d113-57d7-aef99dedd7f0.jpeg)

ご参考になれば幸いです。最後までお読み頂きありがとうございます。

## 関連した投稿

[この物理ファイルはどの論理ファイルが紐づいているのか？の調べ方](https://qiita.com/tamaday/items/13f766383cb56dcf05d9)
R で独立二標本の平均値の差の検定を行い，ChatGPT がサマライズ

R で独立二標本の平均値の差の検定を，いわゆる Welch の方法によって行ない，その結果を ChatGPT にサマライズさせてみた。

## Q1.
### Anonymous

R により，独立二標本の平均値の差の検定を行います。等分散性は仮定しないので，いわゆる Welch の方法で両側検定を行います。
データは，以下のようになっています。
x = c(2, 3, 1, 4, 6, 5, 4, 4)
y = c(3, 2, 3, 5, 6, 7, 8, 6, 4, 5, 3)
検定を行う R スクリプトを提示してください。

### ChatGPT

Welchの方法を用いて、Rで独立した二つの標本の平均値の差の検定を行うために、t.test 関数を使用します。以下がRスクリプトです。

```R
# データの準備
x = c(2, 3, 1, 4, 6, 5, 4, 4)
y = c(3, 2, 3, 5, 6, 7, 8, 6, 4, 5, 3)

# Welchの方法で独立二標本t検定を実行
result <- t.test(x, y, alternative = "two.sided", var.equal = FALSE)

# 検定結果の表示
print(result)
```

このスクリプトでは、t.test 関数を用いて、x と y の二つの標本の平均値の差の検定を行っています。alternative = "two.sided" は両側検定を指定し、var.equal = FALSE は等分散性を仮定しないことを示しています。

実際の検定結果は result に保存され、print(result) で結果を表示します。

### Anonymous
あなたが提示した R スクリプトの出力は以下のようになりました。これをもとにして，論文の一部を記述してください。

```R
> x = c(2, 3, 1, 4, 6, 5, 4, 4)
> y = c(3, 2, 3, 5, 6, 7, 8, 6, 4, 5, 3)
> result <- t.test(x, y, alternative = "two.sided", var.equal = FALSE)
> print(result)

	Welch Two Sample t-test

data:  x and y
t = -1.3692, df = 16.555, p-value = 0.1892
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -2.8042896  0.5997441
sample estimates:
mean of x mean of y 
 3.625000  4.727273 
```


### ChatGPT

検定結果から得られた情報を元に、論文の一部を記述してみましょう。以下は例です：

```
統計的検定結果:

Welchの方法による独立二標本t検定を用いて、変数XとYの平均値の差について調査を行った。検定の結果、t(16.555) = -1.3692, p = 0.1892 であり、両側検定において統計的に有意な差があるかどうかを確認した。

検定結果の解釈:

検定の結果、p = 0.1892 であり、有意水準 0.05 で帰無仮説を棄却する十分な証拠が得られなかった。したがって、我々のデータからは変数XとYの平均値に統計的に有意な差があるとは言えない。

95%信頼区間を考慮すると、真の平均値の差は約 -2.8043 から 0.5997 の範囲にあり得る。これにより、変数XとYの平均値に関する差異の範囲を推定することができる。

結論:

我々の検定結果からは、変数XとYの平均値に統計的に有意な差があるとはいえない。ただし、結果はサンプルに基づいており、より大規模なデータセットや追加の調査が必要であることを考慮する必要がある。
```

## Q2.
### Anonymous
別の分析結果が以下のようになりました。これをもとにして，論文の一部を記述してください。

```R
	Welch Two Sample t-test

data:  x and y
t = -6.3378, df = 16.555, p-value = 8.408e-06
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -6.804290 -3.400256
sample estimates:
mean of x mean of y 
 3.625000  8.727273 
```

### ChatGPT

```
統計的検定結果:

Welchの方法による独立二標本t検定を実施し、変数XとYの平均値の差について結果を得た。検定の結果、t(16.555) = -6.3378, p = 8.408e-06 であり、両側検定において極めて高い統計的有意水準で帰無仮説を棄却する結果が得られた。

検定結果の解釈:

p = 8.408e-06 という極めて小さな値が示唆するところによれば、変数XとYの平均値には統計的に有意な差が存在する。これは、サンプル平均値の差が、母集団において差がないと仮定することが難しいほど強い統計的な証拠を提供している。

95%信頼区間も考慮すると、真の平均値の差は約 -6.8043 から -3.4003 の範囲にある可能性が高い。これにより、変数XとYの平均値の差異の範囲をより具体的に把握できる。

結論:

検定結果から、変数XとYの平均値には統計的に有意な差があり、これは母集団全体においても存在する可能性が高い。この結果は我々の初期の仮説を支持し、変数XとYの間に存在する差異についての洞察を提供している。
```
5 行の整数の入力

次のステップにはいって数題は簡単だったので飛ばしてここから
https://paiza.jp/works/mondai/stdin_primer/stdin_primer__integer_row_step3

整数 a_1, a_2, a_3, a_4, a_5 が 5 行で与えられる
⇒ a_1, a_2, a_3, a_4, a_5 を 5 行で出力　という問題
これは前回ステップの問題集にあったやり方
(input()にintで変換しておくの忘れてたけど通ってた）

```py
arr =[0] * 5
for i in range(5):
    arr[i] = input()

for i in arr:
    print(i)

```

他にもphpにあったような配列の追加方法
どっちがいいかというと、下の方かな？
あらかじめ数が決まっているのはあんまりなくて
不定の場合が多いので
さっき間違えてたけど、appendをapendと書かないように注意
pは２文字必要

```py
arr =[]
for i in range(5):
    value = int(input())
    arr.append(value)

for i in arr:
    print(i)
```