OmniAICreator/Qiita-1.07M huggingface dataset:
GoでgRPCサーバーを立ててみる１（はじめに）

本日からGraphQLサーバーに繋ぐためのgRPCサーバーを立てていきます。
GoでgRPCサーバーを構築してみたいと考えている人に見てもらえたらいいなと思います！

# はじめに

## 今回やること

- Goで簡単なgRPCサーバーを立てる(

## 今回やらないこと

- Dockerの利用
- gRPC、GraphQLの概念説明

## 構成

gRPCを用いるarticleサービスの部分を実装していきます。

## アーキテクチャ

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/701f20c7-db73-9b2b-db18-af6fa87d75a2.png)

## ディレクトリ

- article ・・・ gRPCを用いたCRUDな記事投稿サービス
- graph ・・・ gqlgenを用いたGraphQLサービス

```
.
├── article (今回実装する部分)
│   ├── client
|   ├── pb
|   ├── repository
|   ├── server
|   ├── service
|   ├── article.proto
|   └── article.sql
|
├── graph
│   ├── generated
|   ├── model
|   ├── server
|   ├── resolver.go
|   ├── schema.graphqls
|   └── schema.resolvers.go
|
├── go.mod
├── go.sum
└── gqlgen.yml
```

自作アプリのバックエンドをRESTからgRPCに変えようと考えましたが、フロント側(TypeScript)とgRPCでやり取りするのが大変そうだと感じました。
そこで、BFF(Backend For Frontend)としてGraphQLサーバーを介入させればフロント側と容易にやり取りできるかもしれないと思い、この構成に至りました。

gRPCサーバー構築部分をBookにしようと思いました！

## サンプルコード

実装したものは以下の[GitHubリポジトリ](https://github.com/pinpointdev90/go-gRPC)で公開しています。

# 次章予告

次は、「gRPCのスキーマ定義」をご紹介したいと思います。

以上です。
ありがとうございました。
よろしくお願いいたします。
抽選ツール④

**抽選ツール**に結果待ちの間に演出メッセージの処理を並列に動かす非同期処理を実装しました。


```python3
###################################################
###   お題抽選ツール
####################################################

#ランダムモジュールを呼び出す
import random
import openpyxl
import subprocess
import asyncio
import time

#配列を定義する
array1 = []
array2 = []
#人数変数
N = 0
#エクセルファイルのファイル名変数
out_file = "prezen1.xlsx"
wb = openpyxl.load_workbook(out_file)
#書き込むワークシートを定義する
ws = wb['select']
#行数の定義
start_row = 3
# 待ち時間変数
sleep_time = 10

# 非同期処理で10秒待つ
async def sleep1():
  await asyncio.sleep(sleep_time)

# 非同期処理で10秒間演出する
async def message_out():
    for k in range(0,5):
      print("ﾄﾞﾗ" * 20)
      print("=" * 40)
      await asyncio.sleep(2)

async def main():

  task1 = asyncio.create_task(
        sleep1()
  )

  task2 = asyncio.create_task(
        message_out()
  )

  print(f"started at {time.strftime('%X')}")
  await task1
  await task2
  print(f"started at {time.strftime('%X')}")

#正の整数が入力されるまで繰り返す
while True:
  try:
    N = int(input("登録人数を指定してください\n"))
    if N <= 0:
      raise ValueError("error!")
    else:
      break
  except ValueError as e:
    print("文字列、小数、負の整数、0を入力しないでください")
    print("正の整数を入力してください")

#配列に名前を登録する
for i in range(0,N):
  name = input("名前を入力してください\n")
  array1.append(name)

#配列にお題を登録する
for j in range(0,N):
  title = input("プレゼンのお題を入力してください\n")
  array2.append(title)

#配列の要素をランダムに並べる
random_array1 = random.sample(list(set(array1)),N)
random_array2 = random.sample(list(set(array2)),N)

#ランダムに並べた名前を1行ずつエクセルファイルに出力する。
for k in range(0,N,1):
  man1 = random_array1[k]
  title1 = random_array2[k]
  try:
    with open(out_file,mode='a') as f:
      #エクセルファイルに追記モードで書き込む
      ws.cell(row=start_row,column=2).value = man1
      ws.cell(row=start_row,column=3).value = title1
      start_row += 1
  except:
    print("エクセルファイルが開いたままです。閉じてください")
    exit()

#エクセルファイルを保存する
wb.save(out_file)
asyncio.run(main())


#エクセルファイルを開く
subprocess.Popen(['start',r'prezen1.xlsx'],shell=True)
```
EKS Upgrade insightsを利用してクラスターアップデート時に影響あるAPI等を確認する

EKSを利用していると、必ずついて回るのがクラスターのバージョンアップデート対応です。作業・検証の負担が大きく、かつ更新頻度が高い為(Kubernetesバージョンがリリースされた時点から14ヶ月後に終了)、定期的に対応工数がかかります。 仮にリリース後即座に最新化しても、14ヶ月後には再びアップデート対応を行わなくてはなりません。

そんな中、2023年12月21日にUpgrade insightsという便利な機能がリリースされました。早速検証環境のクラスターで実際に確認してみます。

※2023年10月頃にEKSクラスターバージョンの延長サポート機能のプレビュー版がリリース、2024年1月頃に利用可能予定です。有償ですが、使う場合は追加で+12ヶ月サポートされます。

## Upgrade insightsとは

<b>EKSのバージョンごとで非推奨・削除予定となっているKubernetes APIをAWSのコンソール画面やAPIで確認できる機能</b>です。

利用するにあたり事前に設定等する必要はなく、EKSを利用中であれば簡単に確認が可能です。


以下は検証用環境のv1.25クラスター画面です
EKS画面の中央タブ・Upgrade Insightsの項目から確認できます

![スクリーンショット 2024-01-08 13.58.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/26ac1afe-c0bd-fc78-46a8-781d22595d4f.png)


公式ドキュメント：
https://aws.amazon.com/jp/blogs/containers/accelerate-the-testing-and-verification-of-amazon-eks-upgrades-with-upgrade-insights/

日本語 案内：
https://aws.amazon.com/jp/about-aws/whats-new/2023/12/amazon-eks-upgrade-insights/

### コンソールから確認する

先ほどの画面でErrorとなっている箇所を押下すると、対象のクラスターで利用されているAPIでv1.26では非推奨となるリソースを教えてもらえます。

![スクリーンショット 2024-01-08 14.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/f1ed6b07-99cc-8ecf-93b8-07d4fa366b10.png)


>Deprecated API usage detected within last 30 days and your cluster is on Kubernetes v1.25.

■Deprecation details

Usageに該当するAPI、Replaced withにAPIの修正例が記載されています

![スクリーンショット 2024-01-08 14.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/8cb9c091-403c-d665-8d6b-3aa7fe682cc0.png)

![スクリーンショット 2024-01-08 14.13.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/bd337e3e-9f79-3d3f-4471-721770e223db.png)


Errorとなっている箇所は、実際にEKS上で利用されている状態であることを示しています。/apis/autoscaling/v2beta2/horizontalpodautoscalersをクリックしてみますと、

![スクリーンショット 2024-01-08 14.17.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/9352d9c1-1154-96a0-3dc8-3817ff1d09da.png)

該当するリソース名、30日以内にリクエストされた数が確認できます。

■Recommended action

![スクリーンショット 2024-01-08 14.06.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/14fecaf1-8448-5500-d75a-d4d98798bec6.png)


こちらでは以下のようなEKS、Kubernetesのアップデートに関するドキュメントが案内されています。

https://docs.aws.amazon.com/eks/latest/userguide/update-cluster.html

https://kubernetes.io/docs/reference/using-api/deprecation-guide/#v1-26

v1.26では、以下のAPIが非推奨になるようです

>Flow control resources：flowcontrol.apiserver.k8s.io/v1beta1
HorizontalPodAutoscaler：autoscaling/v2beta2

■Resources

クラスター内で非推奨APIが実際に使われているリソースのネーム一覧が記載されています
(画像のNameにあるhorizontalpodautoscalersの右側に続くのはmetadata.name名となっています)

![スクリーンショット 2024-01-08 14.36.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985033/d88ae04a-114a-eed7-ceb4-bd42f5b0f00c.png)

## APIから確認

aws eks ****-insightコマンドから確認ができます

コマンドの詳細は以下リンクのAWS CLIより確認できます
https://docs.aws.amazon.com/eks/latest/userguide/cluster-insights.html

オプション等
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/eks/describe-insight.html

## アップグレード作業の時間短縮に活用したい

クラスターのバージョンごとに非推奨・削除予定となっているAPIを簡単に確認できるようになりました。上手く利用する事で、クラスターアップデート前にする調査対応の負担権限が期待できます。

現状、年1回程度はEKSアップデート対応が生じる状況ですので積極的に活用できればと思います。
Typescript Express 上で ES Module を使う

Node.js Express + Typescript へ ES Module を導入しようとした所、動かすのに随分手こずりました。正確にはある程度動かすのは簡単だったのですが型補完等を考慮すると推奨の方法だと warning は出るわでこだわった結果時間がかかりました（言い訳

Express + Typescript + ES Module で最終的に組んだ例を掲載します。

## 環境

* package.json の type に module は指定しない
* Express
* Typescript
* ES Module （今回は使おうとしていた [symbol-sdk@3](https://www.npmjs.com/package/symbol-sdk/v/3.1.0) を利用）

package.json ですが、 type: "module" を指定するのが正攻法だと思いますが、既存のプロジェクトへの組み込みを想定してここでは指定せずの例で記載しています。

## 準備

```shell
npm init -y 
npm install express typescript symbol-sdk@3 @types/express
npx tsc --init
```

## コード

**tsconfig.json**

`module` は `NodeNext` でお願いします

```json 
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "NodeNext",
    "strict": true,
  }
}
```

**esmodule.ts**

少し工夫しています。 import("module-name") 形式で読み込む必要があるのですが、利用する度に毎回読み込むのは非現実的なので、読み込み用の関数をここでは定義しました。

```typescript
// @ts-ignore
let symbolSdk: typeof import("symbol-sdk").default;

export const loadSdk = async () => {
  if (!symbolSdk) {
    symbolSdk = (await import("symbol-sdk")).default;
  }
  return symbolSdk;
};
```

:::note warn
警告
`typeof import` に ts-ignore をつけていますが、これをつけないと何故かエラーになります... `await import("symbol-sdk")` の方はエラーにならないのに typeof だと出るのは何故に...？
:::

**index.ts**

esmodule.ts を利用する側の express の記述です。 ES Module は直接 import せずに先程定義しました loadSdk 関数側を読み込んでいます。

```typescript
import { loadSdk } from "./esmodule";
import express from "express";

const app = express();
const port = 3000;

app.get("/", async (_, res) => {
  const sdk = await loadSdk();
  res.send(new sdk.facade.SymbolFacade("mainnet").network.name);
});

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
```

これで準備が出来ました。ここで少し悩んだ部分があります。 ts-node で実行したいなと考えており、公式の手順だと次が推奨されています。

```shell 
npx ts-node-esm ./src/index.ts
```

まず、これは動きませんでした。
もう1パターンがこれ。これは動きました。

```shell 
node --loader ts-node/esm ./src/index.ts
```

しかし、このパターンは動くものの、 node.js 側でこの方法は非推奨であるとずっとログが出てしまうんですね。
ということで最終的に ts-node は諦め、オーソドックスな以下にしました。

```shell 
npx tsc 
node ./src/index.js
```

もし ts-node を利用しても問題ない方法をご存知の方がおりましたら是非コメント等で教えて欲しいのですが、取り急ぎこれで開発はしようと思うので、一旦まとめになりました。

## まとめ

ということで、上記で Express + Typescript + ES Module を実行させる方法になりました。 ライブラリが ES Module にしか対応していないケースはまだまだ稀ではありますが、同じように困った方がいれば是非参考になれば幸いです。
正規表現で見慣れているから . は安全と思うな。

## 正規表現の「.」を使ってtext.txtを検出。
t.tの間にあるから
```
$value = "text.txt";

perl的に$value =~ m/t.t/;
```
やな、ほら検出したって、それ「バグ」だし。
試しに、
```
$value = "txt";
```
やってみ。検出したって喜んで、俺は「txt」検出したいから、とか、ぬかすなよ。
それなぁ、$value = "tat";も検出するし、ぇっ、やないやろ。
「.」はなぁ、正規表現で、任意の「なんでもいい」一文字に一致する。や。もちろん「t.txt」には二回も一致するし。水も漏らさぬって、濡れすぎやわ。
俺初めから、答え知ってる。知ってるって、言わんでも、知らん人に言っているんや。
だって、正規表現の一ページ目に「.」使え、安全や、正規表現は「.」からや、「.」知らんと笑われるってなっていないか?
答えを言ってしまうと、
```
\.
```
違うの出てきた? ￥記号。読み方分からん?(バックスラッシュ) この記号の事をメタ文字と言います。ただし、メタ文字はグループの総称です。
「^ * . 」などの、メタ文字。おまの好きな「.」出てきたぞ。これ自体が特殊な役割をするんや。それらの親方が「\」と言うわけです。\は任務の一時解任の命令を出せる、メタ文字です。ただし、こいつは、環境によって日本では￥に化けて仕事をしたり、しています。
\の出せる環境では同じ意味での￥は出せません。(全角です)

話は、戻って「.txt」検出したかったんやな。$value = "text.txt";
```
$value =~ m/\.txt$/i;
```
普通は、
```
if($value =~ m/\.txt$/i){一致したら;}

=~ とか m/ とか $/ とか i とか
見慣れんもんいっぱいあるな。言わんと。

=~ はマッチング演算子。パターンマッチの時に使われる演算子。逆にし
たい時は否定子(!)を付けて !~ と表すこともある。この時は反対やなと。

m/　mは無くても良いが、知らん人にここはマッチングしますよって、知
らせて(s)とかもあるから　次の/　はmが付けば m|..|とかに置き換え
られる。/を別の意味で使いたい時に、便利だが、あまりしない。

$/　文字の最後になったら。文字が$で最後だから文字が無いから/が来る。

i　は修飾子いって、中身に何をさせるかです。iは大文字小文字の区別
はしない。便利なものです。Txt,TXTなどの混ぜ合わせもok.
他にもgとかいろいろある。
```

詳しくはいわないが、深く知りたい時はQiitaの正規表現入門か、コピロット(Copilotこぱいろっと)と呼ぶと喜ぶが。をマニュアル参照やわ、
```
「\.」をただ見慣れているからと言う理由だけで「.」にするなよ。
```
UUIDをセッションIDとして使わないでくれという話

# 結論
UUIDはセッションIDに使わない。というか使ってはいけない。

# 根拠
[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122#section-6)の6章、セキュリティに関する考慮事項から抜粋した。
## 最初の1段落のみ抜粋
> 6 .  Security Considerations
>
>   Do not assume that UUIDs are hard to guess; they should not be used
>   as security capabilities (identifiers whose mere possession grants
>   access), for example.  A predictable random number source will
>   exacerbate the situation.

## 日本語訳
> UUIDで利用される乱数生成器は安全であるとは限りません。
> 例えば、セキュリティ機能（アクセス許可用の識別子）として使用しないでください。
> 推測可能な乱数ソースが利用されていた場合アクセス許可用の識別子として機能しません。

# 元々想定されているユースケース
分散システムにおけるシステム間のバレてもいい一意のID発行をするために開発された。
元々通信の安全性を担保させる場面でのユースケースは考慮されていない。

# UUIDv4はだめなのか
生成方法をおさらいしましょう。[RFC 4122 4.4章](https://datatracker.ietf.org/doc/html/rfc4122#section-4.4)からの抜粋です。

>4.4.  Algorithms for Creating a UUID from Truly Random or
>      Pseudo-Random Numbers
>
>   The version 4 UUID is meant for generating UUIDs from truly-random or
>   pseudo-random numbers.
>
>   The algorithm is as follows:
>
>   o  Set the two most significant bits (bits 6 and 7) of the
>      clock_seq_hi_and_reserved to zero and one, respectively.
>
>   o  Set the four most significant bits (bits 12 through 15) of the
>      time_hi_and_version field to the 4-bit version number from
>      Section 4.1.3.
>
>   o  Set all the other bits to randomly (or pseudo-randomly) chosen
>      values.

## 日本語訳
> 4.4. 真の乱数または疑似乱数からUUIDを作成するためのアルゴリズム
> 
> バージョン4 UUIDは、真の乱数または疑似乱数からUUIDを生成するためのものです。
> アルゴリズムは次のとおりです。
> 
> o clock_seq_hi_and_reservedの上位2ビット(bit 6とbit 7)をそれぞれ0と1に設定します。
> o time_hi_and_versionフィールドの上位4ビット(ビット12～15)を、セクション4.1.3の4ビットのバージョン番号に設定します。
> o他のすべてのビットをランダム(または擬似ランダム)に選択した値に設定します。

- 6ビットが固定値である
- 擬似乱数でもよい（「安全な乱数であれ」とか、「真の乱数であれ」とは言っていない。）
    - 線形合同法でもUUIDの実装上はRFC違反とならない。

# セキュリティ機能としてのセッションIDを実装する前に考えるべきこと
- そもそも128bitという幅は、将来的に安全であるのか(5年～10年スパン）
    - 計算能力が上がった時、そもそもセッションIDとして耐えられるのか
    - そもそも6ビット固定だし、有効なビット幅は122bitなんだよな。
- 耐えられなかった時、耐性を上げるため生成される乱数自体を長くしたり、乱数生成方法を変えられるなど拡張性はあるのか

最低限この2点は考えて採用したほうが良いかもしれない。
そして、UUIDはこれらを自分でコントロールできない（長さも変えられなければ、乱数生成方法を担保することもできない。使ってるライブラリ次第。突然メンテナが発狂して線形合同法でﾖｼｯとか言ってしまうかもしれない）

# 結局のところ
分散システムで、サーバがセッションを一元管理しないならJWTが良さそう。
一元管理するなら元々セッション管理を行う前提で設計されているフレームワークの機能を使ったりするのが一番お手軽な気がした。
もちろんそういうフレームワークAPIの前提として、「セキュリティを担保する物」であるので、突然メンテナが発狂しても「何してくれてんだ直せ」ってクレームを付けることはできる。

繰り返しにはなるけれど、UUIDの前提はあくまで「分散システムにおいてダブらなければどんな振り方でも良い」なので超小規模な環境が前提のライブラリなら線形合同法でもまぁ良いかとしても文句は言えない。
セキュリティの用途が前提であれば用途に対して安全な生成法（乱数の質や長さ）で適切に生成されたIDでなければならない。
毎日VSCodeで開くプロジェクトをSpotlightに登録して爆速開封の儀


供養

## 内容

![スクリーンショット 2024-01-10 23.19.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/14a8556e-38e4-b82d-9a31-e5ac7c6d7f7a.png)

![ezgif-1-8078f54032.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/b38a9c2a-f852-a244-2a6a-93bf6d347152.gif)

で、VSCodeが開く

## ソースコード

fzfは普段から入っているので必要な方はインストールしてください。
インターラクティブに選択できる部分がそれです

```bash
$ brew install fzf
$ vim ~/Documents/bin/OpenQiita
$ chmod a+x ~/Documents/bin/OpenQiita
```

fzfある版

```bash
#!/usr/bin/env bash
cd ~/workspace/qiita
ls -1 | fzf | xargs code
```

ない版。
workspace/qiitaをvscodeで開く決め打ちになります。

```
#!/usr/bin/env bash
code ~/workspace/qiita
```

## code動かない方


![スクリーンショット 2024-01-10 23.25.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/cc7782f8-f214-70f6-447c-a367e7fc4c87.png)

以下のようなコマンドが/usr/local/bin/にインストールされるはずです。

```shell
$ which code
/usr/local/bin/code
$ code /usr/local/bin/code
```

```bash
#!/usr/bin/env bash
#
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.

# when run in remote terminal, use the remote cli
if [ -n "$VSCODE_IPC_HOOK_CLI" ]; then
	REMOTE_CLI="$(which -a 'code' | grep /remote-cli/)"
	if [ -n "$REMOTE_CLI" ]; then
		"$REMOTE_CLI" "$@"
		exit $?
	fi
fi

function app_realpath() {
	SOURCE=$1
	while [ -h "$SOURCE" ]; do
		DIR=$(dirname "$SOURCE")
		SOURCE=$(readlink "$SOURCE")
		[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE
	done
	SOURCE_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
	echo "${SOURCE_DIR%%${SOURCE_DIR#*.app}}"
}

APP_PATH="$(app_realpath "${BASH_SOURCE[0]}")"
if [ -z "$APP_PATH" ]; then
	echo "Unable to determine app path from symlink : ${BASH_SOURCE[0]}"
	exit 1
fi
CONTENTS="$APP_PATH/Contents"
ELECTRON="$CONTENTS/MacOS/Electron"
CLI="$CONTENTS/Resources/app/out/cli.js"
ELECTRON_RUN_AS_NODE=1 "$ELECTRON" "$CLI" --ms-enable-electron-run-as-node "$@"
exit $?

```

## 純正ターミナルを自動で閉じる

![スクリーンショット 2024-01-10 23.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112929/086fbd07-0547-e77c-64b5-81dc6805fc0e.png)

> シェルが正常に終了した場合は閉じる


## 参考

https://takuya-1st.hatenablog.jp/entry/2017/12/09/212723

https://blog.siwa32.com/mac_terminal_exit_to_close/
paizaラーニング解答: レベルアップ問題集の答え一覧[Ruby]

## paizaラーニングのレベルアップ問題集とは
プログラミングスキルを伸ばしたい方向けのコーディング問題集です。
私はコーディングテスト対策に利用しています。

https://paiza.jp/works/mondai

本記事はプログラミング言語Rubyでの回答集です。
「Dランク獲得ストーリー」からCランク、Bランクと順番に各問題集に取り組む想定で記載しています。
勉強中の方はぜひご活用ください！

## 最初の一歩
https://paiza.jp/pages/works/stories/drank/
<details><summary>自己紹介問題セットの答え（折りたたみ）</summary>
 
```ruby
puts "name: Kirishima"
puts "language: Ruby, English"
puts "hitokoto: がんばります!"
```

</details>

### 標準入力サンプル問題セット
https://qiita.com/fujimotoprogramming/items/a7188efa7ee1bbb9d252


</details>

## Dランク獲得
### Dランクレベルアップメニュー

https://qiita.com/fujimotoprogramming/items/85661f15820f7f210bd8
### Dランク・スキルチェック見本問題セット

https://qiita.com/fujimotoprogramming/items/94747e0c690e8a3f8791
## Cランク獲得
https://paiza.jp/pages/works/stories/crank_ruby
### 標準入力メニュー

https://qiita.com/fujimotoprogramming/items/10c1898c546e122071e4
### 標準出力メニュー

https://qiita.com/fujimotoprogramming/items/98bfbcc4a26e42073b4e
### 算術・代入演算メニュー

https://qiita.com/fujimotoprogramming/items/03f712e984daddc2f756
### データセット選択メニュー

https://qiita.com/fujimotoprogramming/items/fed8d3f27c5b39489c52
### 論理演算メニュー

https://qiita.com/fujimotoprogramming/items/9c4d382b47ad74436517
### 条件分岐メニュー

https://qiita.com/fujimotoprogramming/items/f4e1df09123c34e0916c
### ループメニュー1

https://qiita.com/fujimotoprogramming/items/86f2cc464db6a3e9f9d7
### ループメニュー2

https://qiita.com/fujimotoprogramming/items/a78923894e1e0625329b
### 配列メニュー

https://qiita.com/fujimotoprogramming/items/592e47a09e1517b4b7a8
### 二重ループメニュー

https://qiita.com/fujimotoprogramming/items/9cd054f0d0d56f26cd4e
### 線形探索メニュー

https://qiita.com/fujimotoprogramming/items/8d49fb4747d70404d4e7
### データセット選択メニュー

https://qiita.com/fujimotoprogramming/items/fed8d3f27c5b39489c52
### 文字列処理メニュー

https://qiita.com/fujimotoprogramming/items/cca62c3c5f6f880d59b9
### Cランクレベルアップメニュー

https://qiita.com/fujimotoprogramming/items/5c9e6323df931cffa8d8


## Bランク獲得
https://paiza.jp/pages/works/stories/brank
### 配列活用メニュー

https://qiita.com/fujimotoprogramming/items/89fa4f95fa0faa87d72c

### 素朴なソートメニュー
https://qiita.com/fujimotoprogramming/items/7da0426bb20816357a6c
### 効率的なソートメニュー
https://qiita.com/fujimotoprogramming/items/6a3aed1da1f7d07b011b
### ソートメニュー応用編
https://qiita.com/fujimotoprogramming/items/2c1b1c1a41860e422455
### スタック・キューメニュー
https://qiita.com/fujimotoprogramming/items/66644f01b2c380577b1e
### ハッシュメニュー
https://qiita.com/fujimotoprogramming/items/64a08d836263cb7d26d9
### 累積和メニュー
https://qiita.com/fujimotoprogramming/items/7365882ae386aa5a8596
### 
### 
### 
### 


...以降も各メニューの解答を追加予定です！
ユニットテストするならフレームワーク使おう (Python unittest)

## ※ 注意

これは「ユニットテストはこういうことを書くのがいいよ！」という話ではありません。「フル自作より、フレームワーク使った方が良いよ」という話です。

良いユニットテストのやり方については、別の解説を探してください。

## 背景

(恥ずかしながら、真面目にユニットテストをするようになったのは割と最近のお話。)

テストの習慣化を始めたそのときは、テストフレームワークという言葉は聞いたことあったが、まともに向き合っていなかった。

で、あるとき「いい加減フレームワークの一つくらい触れておこうか･･･」と思い、とりあえず Python 標準のユニットテストフレームワーク `unittest` を使ってみた。

すると、これまで書いていたテストコードより、明らかに書くコード量が減ったではありませんか。なぜ今まで向き合わなかったのか･･･。

というわけで、その感動そのままに、本記事執筆に至りました。

## ユニットテストとは (軽く)

単体テストとも。

単体とは、例えば自作関数 1つとか、プログラムが機能するレベルとして最低規模と考えればヨシ。

テストとは、試験、つまりそのプログラムが想定 (設計・仕様) 通りに動くかどうかチェックすること。

要するに、プログラムの小規模パーツ単位でのチェック。より詳しいことは解説がたくさんあるのでカット。

## ユニットテストコード例

足し算と引き算のテストをするとします。ここで、引き算のテストには、あえて誤りを入れています。

```test_code_original.py
def expect_equal(expected, actual):
  if expected == actual:
    print("--- OK")
  else:
    print("--- NG")
    print(f"Expected: {expected}")
    print(f"Actual  : {actual}")


def test_add():
  print("-- test_add")
  expected = 3
  actual = 1 + 2
  expect_equal(expected, actual)

def test_sub():
  print("-- test_sub")
  expected = 2
  actual = 5 - 2 # 何か不具合があったとする
  expect_equal(expected, actual)


if __name__ == "__main__":
  test_add()
  test_sub()
```

```sh
python3 test_code_original.py
```

```txt
-- test_add
--- OK
-- test_sub
--- NG
Expected: 2
Actual  : 3
```

## `unittest` 使用で書き直すと

全く同じテストを、今度は `unittest` 使用で書いてみます。

```test_code_unittest.py
import unittest

class test_add_sub(unittest.TestCase):
  def test_add(self):
    expected = 3
    actual = 1 + 2
    self.assertEqual(expected, actual)

  def test_sub(self):
    expected = 2
    actual = 5 - 2  # 何か不具合があったとする
    self.assertEqual(expected, actual)


if __name__ == "__main__":
  unittest.main()
```

```sh
python3 test_code_unittest.py
```

```txt
.F
======================================================================
FAIL: test_sub (__main__.test_add_sub)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/<path>/test_code.py", line 12, in test_sub
    self.assertEqual(expected, actual)
AssertionError: 2 != 3

----------------------------------------------------------------------
Ran 2 tests in 0.000s

FAILED (failures=1)
```

`-v` オプションを付けると、実行中テスト名を詳しく出してくれます。

```sh
python3 test_code_unittest.py -v
```

```txt
test_add (__main__.test_add_sub) ... ok
test_sub (__main__.test_add_sub) ... FAIL

======================================================================
<以降同じ>
```

## テストフレームワークのここが良い

上 2つのコードとテスト結果出力を比較すると、`unittest` で以下の恩恵が得られると言えそうです。

* 実行中テスト名を自分で出力しなくてよい
* テスト結果を自分で出力しなくてよい
* テスト関数の呼び出しを書かなくてよい
  * `unittest.main()` だけで OK
  * テスト関数の定義を書く・消すだけ
* 失敗したテストを詳細に出力してくれる
  * テスト名、結果値の違い、該当の行番号

:::note
加えて `unittest` は Python 標準なので、追加の準備が不要という利点もあります。
:::

ここでは Python の `unittest` を例にしましたが、cpputest など他のフレームワークも、上のような特徴を持っていることでしょう。

## まとめ

ユニットテストフレームワークを導入すると、面倒なコードを書くことなく、テストをサクッと実装できて良い。

「結果出力書くの面倒でテスト書く気起きん」というような人が居たら、早急にフレームワーク導入を勧めましょう。

あと、テストはやるべきというのは言わずもがな。
Next.jsで()付きのディレクトリの扱い

## バージョン

```php
    "next": "13.5.6",
    "react": "^18",
    "react-dom": "^18",
```

## 概要

Next.jsでルーティングを行う時にディレクトリ内にpage.tsxを作成するとルーティングが可能になる。例えば、下記のようにディレクトリ内に作成すると`[http://localhost:3000/](http://localhost:3000/contact)pages`となる。

```php
pages
  →page.tsx
```

## 課題

仮にpagesディレクトリにtaskディクトリとcontactディレクトリを作成して、それぞれの配下にpage.tsxを作成する。それぞれのルーティングは`http://localhost:3000/pages/task`と`http://localhost:3000/pages/contact`になる。このパス中のpagesの記述をなくしたい。

## 解決策

pagesディレクトリを(pages)に書き換えることで、それぞれのルーティングは`http://localhost:3000/task`と`http://localhost:3000/contact`となる。
【Unity】PlayerSettingsが開かないときに確認すること

# はじめに
`ToolBar > Editor > PlayerSettings...`のWindowが開かない事象が発生しました。なかなか原因を特定できなかったため、解消方法を記録します。


# 確認方法
* Unity再起動
* OS(Windows,Mac等)再起動
* BuildTargetOSの変更
* `ToolBar > Window > Layouts > Resets > Resets All Layouts` を実行する
* キャッシュファイル類の削除
* 外部ディスプレイケーブルを挿抜する（ディスプレイ解像度設定を変更する。Windowsのみ？）

# 最後に
最後の項目以外は検索すると比較的すぐに見つかる情報なんですが、私の場合は最後の項目のケーブル挿抜でWindowを開くことができました。
ラップトップ＋外部モニター環境ではこの事象が発生する可能性があるみたいです。
（単にITリテラシーの問題だったかも。。。）
paizaラーニング解答: 線形探索メニュー[Ruby]

# 線形探索メニュー
https://paiza.jp/works/mondai/sequence_search_problems/problem_index?language_uid=ruby

線形探索についての詳しい解説は下記の講座で説明されています。

https://paiza.jp/works/algorithm-java/new-primer/algorithm-java-new-primer-2
## STEP: 1 指定された値の個数
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
puts a.count(k)
```

## STEP: 2 指定された値の位置 1
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
if a.include?(k)
    puts a.index(k) + 1
else
    puts 0
end
```

## STEP: 3 指定された値の位置 2
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
ans = 0
(n - 1).downto(0) do |i|
    if a[i] == k
        ans = i + 1
        break
    end
end
puts ans
```

## FINAL問題 【指定された値の探索】指定された値の位置 3
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
(0...n).each do |i|
    if a[i] == k
        puts i + 1
    end
end
```

## STEP: 1 2変数の最大最小
```ruby
a = gets.split.map(&:to_i)
puts "#{a.max} #{a.min}"
```

## STEP: 2 10変数の最大最小
```ruby
a = gets.split.map(&:to_i)
puts "#{a.max} #{a.min}"
```

## FINAL問題 【最大最小】n 変数の最大最小
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
puts "#{a.max} #{a.min}"
```
## STEP: 1 偶数の探索
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
(0...n).each do |i|
    if a[i].even?
        puts i + 1
        break
    end
end
```

## STEP: 2 奇数の探索
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
(n - 1).downto(0) do |i|
    if a[i].odd?
        puts i + 1
        break
    end
end
```

## STEP: 3 条件付き最小値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
ans = 1000
a.each do |i|
    if k <= i
        ans = [i, ans].min
    end
end
puts ans
```

## STEP: 4 条件付き最大値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
ans = -1000
a.each do |i|
    if k >= i
        ans = [i, ans].max
    end
end
puts ans
```

## STEP: 5 点と点の距離
```ruby
n = gets.to_i
a = n.times.map { gets.split.map(&:to_i) }
k = gets.to_i
xn, yn = a[-1]
count = 0
n.times do |i|
    x, y = a[i][0], a[i][1]
    if (x - xn).abs + (y - yn).abs <= k
        count += 1
    end
end
puts count
```
問題文だとわかりにくいですが、点nとは入力される値の中の最後のxとyのことです。
## STEP: 6 長方形に含まれる点
```ruby
n = gets.to_i
a = n.times.map { gets.split.map(&:to_i) }
xs, xt = gets.split.map(&:to_i)
ys, yt = gets.split.map(&:to_i)

count = 0
n.times do |i|
    x, y = a[i][0], a[i][1]
    if xs <= x && x <= xt && ys <= y && y <= yt
        count += 1
    end
end
puts count
```
## STEP: 7 成績優秀者の列挙 1
```ruby
n = gets.to_i
a = n.times.map { gets.chomp.split }
k = gets.to_i
n.times do |i|
    s, t = a[i][0], a[i][1].to_i
    if k <= t
        puts s
    end
end
```

## FINAL問題 【特殊な探索】 成績優秀者の列挙 2
```ruby
n = gets.to_i
a = n.times.map { gets.chomp.split }
k, l = gets.split.map(&:to_i)
n.times do |i|
    s, t = a[i][0], a[i][1].to_i
    if k <= t && t <= l
        puts s
    end
end
```

## STEP: 1 2番目に大きな値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
a.sort!
puts a[n - 2]
```

## FINAL問題 【第 k 要素の探索】k番目に大きな値
```ruby
n = gets.to_i
a = gets.split.map(&:to_i)
k = gets.to_i
puts a.sort[-k]
```
Google Earthに線を描画＆アニメーションするMATLABコード🌍

Google Earth Toolboxというもので遊ぼうと思います．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/12050f26-5e0b-d1bb-7861-d98437b80e75.png)
これは，Google Earth上で表示する物を表すフォーマット，"KML"や"KMZ"のファイルを作成するライブラリです．このライブラリでKMLやKMZファイルを作成し，Google Earthに読み込ませます．

## 線の描画 : `ge_plot3`
成田空港の滑走路から螺旋を生やしたいと思います．
```matlab
naritax = 140.38;
naritay = 35.76;

N = 100;
t_s = linspace(0,2*2*pi,N);
r_s = linspace(0,1e-2,N);
X = naritax + r_s .* cos(t_s);
Y = naritay + r_s .* sin(t_s);
Z = linspace(0,1e3,N);

kmlStr = ge_plot3(X,Y,Z, ...
    'lineColor','ffffff00', ...
    'lineWidth',5);

ge_output('a.kml', kmlStr); % KMLファイルへの出力
```
`ge_output`は得られたKMLテキストをKMLやKMZファイルに保存する関数です．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/47e116d3-f043-3d87-606c-90cf7ca65be8.png)

で，ここで問題なのですが，よく見ると線がガタガタになっています．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/8d119c1e-2365-a013-79ac-2e7b2e264bfc.png)
これは，Z座標の基準が地面になっているからです．Z座標の基準は，KMLの属性である「標高モード」として色々と定義されています．

https://developers.google.com/kml/documentation/altitudemode?hl=ja

このドキュメントによると，Z座標の基準を海面にしたい場合は，`absolute`にすればよいそうです．

`ge_plot3`では，以下のようにして出力される標高モードを変更できます．
```matlab
kmlStr = ge_plot3(X,Y,Z, ...
    'lineColor','ffffff00', ...
    'lineWidth',5, ...
    'altitudeMode','absolute'...
    );
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/5f737bba-af3d-1090-88e1-0349357fbcd7.png)
ガタガタが無くなった！

## アニメーション機能
先ほどのプロット関数`ge_plot3`などには，`timeSpanStart`，`timeSpanEnd`属性というものがあります．これは，そのKMLオブジェクトが現れる時刻を設定するもので，`timeSpanStart`〜`timeSpanEnd`の間に現れるようになります．

これを使えば，アニメーションを作ることができます．
例えば，以下の例のように，時間経過とともに伸びる線を作りたい場合，

1. 1つの線を数個の線に分ける．
1. 各線のKMLオブジェクトを生成する．その際，`timeSpanStart`と`timeSpanEnd`を前のKMLオブジェクトと比べて少しずらす．

というふうにします．

```matlab
% 線のデータを作る
naritax = 140.38;
naritay = 35.76;
N = 100;
t_s = linspace(0,2*2*pi,N);
r_s = linspace(0,1e-2,N);
X = naritax + r_s .* cos(t_s);
Y = naritay + r_s .* sin(t_s);
Z = linspace(0,1e3,N);

% 時刻データの準備
S = 'yyyy-MM-dd''T''HH:mm:ss''Z';
tBegin = datetime(2024,1,10);
tBegin.TimeZone = 'Asia/Tokyo';
tBegin.Format = S;
dday = 1/3600/24;

kmlStr = [];
for n=1:N-1
    tStart = tBegin+(n*dday);
    tEnd = tStart+dday;
    kmlStr = [kmlStr ge_plot3(X(n:n+1),Y(n:n+1),Z(n:n+1), ...
        'lineColor','ffffff00', ...
        'lineWidth',10, ...
        'altitudeMode','absolute', ...
        'timeSpanStart',char(tStart),...
        'timeSpanStop',char(tEnd)...
        ) ];
end

ge_output('a.kml', kmlStr);
```

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116310/a9df85a2-6dd5-92d5-1671-9f891da1501c.gif)

自分の研究で使おうかな！
Gitコマンドに別名を設定する

Gitコマンドを毎回入力するのがめんどくさい．
コマンドに別名(エイリアス)を設定しておくことで，入力を少しだけ楽にすることができる．
少しだけだけど．．．

```bash
$ # エイリアスの設定は，git config --global alias.<別名> <Gitコマンド>

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status
$ git config --global alias.unstage 'reset HEAD --'    # ステージを解除
$ git config --global alias.last 'log -1 HEAD'    # 直前のコミットを確認

# 外部コマンドを実行するときは，$ git config --global alias.visual '!<外部コマンド>'
$ git config --global alias.visual '!gitk'
```

##### 参考
https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-Git-%E3%82%A8%E3%82%A4%E3%83%AA%E3%82%A2%E3%82%B9
システムコールとは

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)


# システムコールとは
`システムコールとは、OSが提供する機能を呼び出すための仕組み`のことです。
アプリは通常、OSの基本機能に直接アクセスすることはできません。その代わり、システムコールを使用することで、アプリからOSの基本機能を呼び出せるようにしています。

# システムコールが必要な理由
なぜわざわざシステムコールを介して、アクセスするような仕組みにしているのでしょうか？
例えば、もしもシステムコールを使用せず、アプリが直接OSにアクセスした場合、アプリがリソースを間違った方法で利用するかもしれません。このような自体を防ぐために、アプリから直接OSにアクセスできないようにしています。
また、OSの上では複数のプログラムが動作しています。あるプログラムの動作が他のプログラムの動作に影響与えないようにするためにも、システムコールは重要な役割を担っています。


# システムコールの種類
一般的なシステムコールについて紹介します。
open、read、write、close、wait、execve、fork、killなどの機能があり、ファイルシステム・ネットワーク・メモリ・プロセス・スレッド・セキュリティなどに対する操作をシステムコールで行うことができます。
※ただし、OSによってサポートされるシステムコールは異なります。


# 終わりに
システムコールは、コンピュータシステムにおいて欠かせない存在です。アプリとOSの間で安全かつ効率的なコミュニケーションを可能にし、システムの正確な動作と安定性を確保する鍵となります。

最後までお付き合いくださりありがとうございました。
Gmail × Python メールの自動送信プログラム

<h1>はじめに</h1>
クライアントからGmailに自動送信されるよう要件定義があったので、そのためのコードを残しておきます。

<h1>スクリプト</h1>

```python:title.py

import smtplib
from email.mime.text import MIMEText
from email.header import Header

def send_email(from_email, to_email, subject, message, smtp_password):
    msg = MIMEText(message, 'plain', 'utf-8')
    msg['From'] = Header(from_email, 'utf-8')
    msg['To'] = Header(to_email, 'utf-8')
    msg['Subject'] = Header(subject, 'utf-8')

    server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    server.login(from_email, smtp_password)
    server.sendmail(from_email, [to_email], msg.as_string())
    server.quit()

# 処理が成功した際にメールを送る機能
def success_send():
    # 送信するメールの情報を設定
    # 送信元
    from_email = '****@gmail.com'

    # メールを送る相手のアドレス
    to_email = '****@gmail.com'

    # 件名
    subject = 'テストメール'

    # 本文
    message = '今日も最高でした。'

    # アプリパスワードを設定
    # やり方 Googleのアカウント→セキュリティ→2段階認証→アプリパスワード
    smtp_password = '**** **** **** ****'

    # メール送信関数を呼び出す
    send_email(from_email, to_email, subject, message, smtp_password)


```
G検定を受けてみての感想と対策方法

# G検定(G2023#5)を受けてみた
試験を受けての感想と対策方法を記しておこうと思いました。読みづらいと思いますが、活用してもらえればと思っています。

## G検定とは
G検定(ジェネラリスト検定)とは **ディープラーニングの基礎知識を有し、適切な活用方針を決定して、事業活用する能力や知識を有しているかを検定する** 
  
要するに、 **AIの基礎知識及びディープラーニング知識**について問われる試験です。

この試験は一般社団法人　日本ディープラーニング協会(JDLA)が実施している民間資格。
https://www.jdla.org/certificate/general/
## 受験きっかけ
私は大学の授業を通してAIについて学んでおり、授業内でG検定について触れることがあり、じゃあついでに資格を取ってみようという軽い気持ちで受けてみました。
  
決心したのは試験まで約2週間前というのもあって、必死に傾向と対策をしました...
  
## 勉強方法
結論からすると、**AIの基礎知識を身に着けたうえで、ディープラーニングの手法をイメージ(具現化)できる**ようになれば受かると思います。

私は、参考書や様々な記事から自分の教科書＝**カンペ**を作りました。

この試験は選択問題ですが120分で約200問を解くので、単純計算で **1問につき36秒で解かなければいけない** 試験でした。  
また、問題文も長くひっかけ問題も多いため、悩んでいる時間はありませんでした。  

使った参考本は２冊になります。  

<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3535173/a6bf7b31-0e95-a2e6-2f4e-8e4fafa1c7ba.png">

**白本**：深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 第2版
https://www.amazon.co.jp/dp/4798165948?tag=ukatta-22&linkCode=ogi&th=1&psc=1  

**黒本**:徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 (徹底攻略シリーズ)
https://www.amazon.co.jp/dp/4295011630?tag=ukatta-22&linkCode=ogi&th=1&psc=1  

どちらも白本・黒本と呼ばれる有名な参考本になります。

白本では、**G検定の概要知識理解、基礎知識の確認** に使います。  
黒本は、白本と並行して章が終わるごとに問題をといて、**知識の定着** を狙います。


## 白本の活用方法
３段階に分けて活用していきます。
1. 全体通読  
   どんな知識が必要か理解するのを目標にする
2. 章ごとの知識理解  
   出てくる単語の意味が分かるようにする
3. 分からない問題の時の確認  
   分からない単語が問題に出てきたときに確認をする


## 黒本の活用方法
問題集になるので、白本の2段階目に入ったら使っていきます。問題を使っていくと、全然理解できていないことに気づきます。最初は答えを見て、慣れることが大切だと思います。  
**問題を見る→解く→答えを見る→解説で理解する**  
この流れが大切になってくると思います。

## カンペを作る
この資格試験では、いかに早く問題を解けるかが鍵になってきます。よって、自分が分かりやすい**自分の教科書=カンペ**を作るべきだと思います。カンペを作ることで、単語の意味を調べるようになるので、より深い基礎知識の定着につながると考えます。
カンペを作るときは、公式から出ているシラバスを見てわからない単語は徹底的に調べた方が絶対いいです。
↓私が作ったカンペの一部になります。(イラスト部分は著作権等に絡みそうなので載せません)
<img width="500" src="https://qiita-image-store.s3.amazonaws.com/0/3535173/d6b858e6-c589-262f-ba9e-6fcb216dd72b.png">

## 模擬試験を受けてみる
G検定には過去問が存在せず実力を試す場がないので、インターネットにある模擬試験などを使わせてもらい、実力を測ります。私の場合、StudyAIの模擬試験で実力試しをしました。

https://study-ai.com/generalist/
![スクリーンショット 2024-01-10 215823.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3535173/0cdf7328-4713-09f0-8d60-a01fadd7cc35.png)

ここで点数が取れなければ、試験に落ちるといってもいいと思います。8割以上とれていなければ、白本を使って知識の再確認をしましょう。

## 試験を受験する
あとはやってきた自分の実力を信じて試験を受けるだけです！  
分からない問題はマークを付けてあと回しにして、時間を有効活用することが合格に繋がります。

## 受験結果の確認
受験後２週間後にメールで合否連絡が来ました。  
メールには点数の記載はありませんが、シラバス分野別得点率が記載されていました。  
私は1発合格しましたが、法律・倫理・社会問題の分野が低かったです...

## まとめ
資格難易度としては簡単な部類のG検定になりますが、基礎知識が定着することでプログラミングをするときに理解がしやすくなると感じました。
資格取得を目的とした受験であればここまでやる必要はないかもしれません…
AIのことについて興味のある学生は一度受験をしてみることで、現代のAI技術について学べるのでオススメしたいです。
MusicBrainz APIと使ってアーティストの人気の曲名を返してもらう

こんにちは、**ウエハラ　シンペイ**です。

今回MusicBrainz APIとLINE botを使って
アーティストの人気の曲を教えてくれると作っていこうと思います。

# MusicBrainz APIとは？
非営利団体であるMetaBrai
nzによって運営されいる、オープンな音楽データベースサービスだそうです。国内アーティストの情報を形成されていて、今回はこのAPIを試しに触ってみました。

![MBlogo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618353/f3a42471-cfea-7df9-a6ad-f5495870f77b.png)



# MusicBrainz APIは何ができる？
アーティスト、イベント、ジャンル、レーベル、作品など音楽に関係する情報が数多く検索可能でそれをXMLまたはJSON形式で返してくれるもののようです。

特に金額は発生せず、API キーもいらないけど、リクエストに返される数には制限があり最大25個とのこと(多分)

[MusicBrainz API](https://musicbrainz.org/doc/MusicBrainz_API "MusicBrainz API")


# LINEでアーティストを送ると曲名を返してもらう

<details><summary>実際のコード</summary>

```JavaScript:sample.js

const express = require('express');
const line = require('@line/bot-sdk');
const axios = require('axios'); // axiosを追加

const app = express();

const config = {
  channelSecret: process.env.CHANNEL_SECRET || 'XXXXXXXXXXXXXXX',
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || 'XXXXXXXXXXXXXXX',
};

const client = new line.Client(config);

app.post('/webhook', line.middleware(config), (req, res) => {
  Promise
    .all(req.body.events.map(handleEvent))
    .then((result) => res.json(result))
    .catch((err) => {
      console.error(err);
      res.status(500).end();
    });
});

async function handleEvent(event) {
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  const artistName = event.message.text;
  try {
    const response = await axios.get(`https://musicbrainz.org/ws/2/recording/?query=artist:${encodeURIComponent(artistName)}&fmt=json`);
    const recordings = response.data.recordings;
    if (recordings.length > 0) {
      const titles = recordings.map(recording => recording.title).join('\n');
      return client.replyMessage(event.replyToken, {
        type: 'text',
        text: `曲名リスト:\n${titles}`,
      });
    } else {
      return client.replyMessage(event.replyToken, {
        type: 'text',
        text: 'アーティスト名が一致しません',
      });
    }
  } catch (error) {
    console.error(error);
    return client.replyMessage(event.replyToken, {
      type: 'text',
      text: 'エラーが発生しました',
    });
  }
}

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Listening on port ${port}`);
});


```

</details>


### 曲名が無事帰ってきました！！

<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618353/afeea0e7-7acd-5051-c2b9-b1032a915e12.png">

ただ、いきなりインストが入っていたりと順番を人気順にしたいところでしたが、MusicBrainz APIに関するようなデータがないらしく、このあたりは他の方法があれば知りたいところでした。
Windows Update で KB5034441 がエラーになってしまうのを今すぐ何とかしたい方向けの手順

## 更新プログラム KB5034441 がエラーになる
2024年01月10日(日本時間) に公開された Windows 10 向けの更新プログラム「2024-01 x64 ベース システム用 Windows 10 Version 22H2 のセキュリティ更新プログラム (KB5034441)」について、「ダウンロード エラー - 0x80070643」などのエラーが発生してインストールに失敗するケースがあるようです。

![80070643.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177762/5b8404a9-fe14-ebaf-1936-e890628e5e6d.png)

現在、世界中でこのエラーについての報告があがっているようですので、今後 Microsoft 側で何らかの対処なり案内がなされるのではないでしょうか。それまでこちらのエラーは無視していればよいかと思います。

ただ、今すぐ何としてでもこのエラーを消し去りたい！という事情がある方もいるかもしれませんので、エラー解消のための手順を書いておきます。

## エラーの原因は回復パーティションのサイズ不足

* KB5034441: Windows 10 バージョン 21H2 および 22H2 用 Windows 回復環境の更新プログラム: 2024 年 1 月 9 日
https://support.microsoft.com/ja-jp/topic/62c04204-aaa5-4fee-a02a-2fdea17075a8

こちらの Microsoft 公式ナレッジによると、エラーが発生した場合は回復パーティションのサイズが不足しているため、手動でパーティションサイズを拡張するようにとの案内があります。

> 一部のコンピューターには、この更新プログラムを完了させるのに十分な大きさの回復パーティションがない可能性があります。 このため、WinRE の更新が失敗する可能性があります。 その場合、次のエラー メッセージが表示されます:
> 
> Windows 回復環境サービスが失敗しました。
> (CBS_E_INSUFFICIENT_DISK_SPACE)

具体的な手順は[こちらのページ](https://support.microsoft.com/ja-jp/topic/400faa27-9343-461c-ada9-24c8229763bf)にきちんと書いてあるのですが、少々ややこしいのでコマンドでのパーティション操作に慣れている方でないと戸惑うかと思います。

## エラー解消手順

上記のパーティションサイズ拡張の手順をスクリプト化してコピペで実行できるようにしました。

**管理者権限**で PowerShell を開いて次のコマンドを順に実行してください。
全行選択してコピペでOKです。

> 重要なデータは必ずバックアップを取ったうえで実行してください。
> 実行した結果について一切責任は負いません。

```powershell
$syspart = (Get-Partition -DriveLetter $env:SystemDrive[0])
$recpart = (Get-Partition).Where({$_.Type -eq 'Recovery' -or $_.MbrType -eq 0x27})[0]
$IsGpt = ($recpart | Get-Disk).PartitionStyle -eq 'GPT'
$dpscript = Join-Path $env:TEMP '\diskpart.txt'
$dparam = @("sel disk $($syspart.DiskNumber)")
$dparam += "sel part $($syspart.PartitionNumber)"
$dparam += "shrink desired=250 minimum=250"
$dparam += "sel part $($recpart.PartitionNumber)"
$dparam += "delete part override"
if($IsGpt){$dparam += "create part primary id=de94bba4-06d1-4d40-a16a-bfd50179d6ac"}
if($IsGpt){$dparam += "gpt attributes=0x8000000000000001"}
if(-not $IsGpt){$dparam += "create part primary id=27"}
$dparam += "format quick fs=ntfs"
if(-not $IsGpt){$dparam += "set id=27"}
$dparam | Out-File $dpscript -Force -Encoding ascii
if($stop = (-not $recpart -or $recpart.DriveLetter -or $syspart.DiskId -ne $recpart.DiskId -or $recpart.PartitionNumber - $syspart.PartitionNumber -ne 1)){throw 'This system is not supported.'}
reagentc /disable
if(-not $stop){diskpart /s $dpscript}
del $dpscript
reagentc /enable

```

### KB5034441 を再度インストール

無事にコマンドが成功したら再度 Windows Update を実行してKB5034441が正常にインストールされることを確認してください。
AIがアシストする開発環境 〜gpt-engineerの紹介〜

# はじめに
最新のテクノロジーは、私たちの生活と仕事のやり方を劇的に変えています。
特に、人工知能（AI）の進化は、プログラミングの分野に革命をもたらしています。
今回は、GitHubの「gpt-engineer」をご紹介します。

![DALL·E 2024-01-10 21.26.37 - A visually appealing eye-catching image for a blog post about the 'gpt-engineer' project. The image should represent the concept of AI assisting in so.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/c2fbf467-bcd0-71e3-a6b7-ffd17a3f13ad.png)
# gpt-engineerとは
「gpt-engineer」は、GitHub上で公開されているオープンソースプロジェクトです。
このプロジェクトはAIを利用して、ユーザーが何を作りたいかを指定すると、AIが質問をして明確化し、その後構築を手伝うシステムに焦点を当てています。
7.9kのForkと48.3kのStarを獲得しています(2024年1月10日現在)。

https://github.com/gpt-engineer-org/gpt-engineer

# 具体的な機能と利点
具体的には、「gpt-engineer」はプログラミング言語の理解に基づき、より複雑なコーディングタスクの解決をサポートします。
例えば、特定の機能の実装方法についてAIに質問すると、関連するコード例やベストプラクティスを提示してくれます。
また、既存のコードを分析し、改善点やバグを指摘することも可能です。

# おわりに
AIと人間の協力関係は、開発の世界において新たな地平を開いています。
「gpt-engineer」は、その最前線に立つプロジェクトであり、私たちが開発に対するアプローチを根本的に見直すきっかけを提供してくれるでしょう。
このプロジェクトがもたらす未来に、私たちは大きな期待を寄せています。
【初心者向け】現役プログラマーが伝授！プログラミング独学のロードマップ

この記事では効率のいいプログラミング独学法や、初心者さんがぶつかりやすい壁とその乗り越え方など、プログラミング初心者さんに必要な情報をすべてご紹介します。

https://www.mimu-programming.com/programming-roadmap/
基本情報　よく出る単語

### ２の補数
ある自然数を２進数で表現した値のビット列の全びっとを反転し、１を加算した値

### 論理積　AND
論理演算の一つで、２つの論理値が両方１なら１、それ以外なら０を結果とする

### 論理和　OR
論理演算の一つで、２つの論理値が両方０なら０、それ以外なら１を結果とする

###　排他的論理和　　XOR 
論理演算の一つで、入力した２つの論理値のうち片方のみが１である時のみ１、両方１や両方０の場合は０となる

### 半加算器
１桁の２進数同士を加算する論理和（加算器）の一つで、下位の桁から桁上がりを考慮しない加算回路のこと。

### オートマトン　状態機械
コンピュータの動作を抽象化したモデルの一つで、入力に対し内部の状態を変化させて処理を行い毛化を出力するといった、仮想的な機械の概念を指す。

### 逆ポーランド表記法
演算子を、非演算子（演算対象）の後ろにおく表記法

### ポインタ
変数や配列要素の格納位置（アドレス）を格納する特殊な変数

### リスト
データとポインタを１つの要素としてもち、ポインタで要素かんを連結したデータ構造のこと

### キュー　待ち行列
コンピュたのデータ構造の一つで、最初に格納されたデータが最初に取り出される（先入先出し（FIFO））構造をもつ

### スタック
コンピュータのデータ構造の１つで、最後に格納されたデータを最初に取り出す（後入れ先だし（LIFO））構造をもつ

### 2分探索木
全ての節において小さい値のノードが左部分木に、大きい値のノードが右部分機に配置される木

### オブジェクト指向
クラスや継承という概念を利用してソフトウェアを部品化したり再利用することで、ソフトウェア開発の生産性向上を図る手法。

### クイックソート
適当な基準値を選び、それより小さな値のグループとおいな値のグループにデータを分割する。
同様にして、グループの中で基準値を選び、それぞれのグループを分割する。この操作を繰り返していく方法。

### 2分探索
探索範囲を半分に絞り込む操作を繰り返し、目的のデータを探索する方法。

### ハッシュ法
探索地に紐づいた固有の値（キー値）から、探索値が格納されている位置を計算する方法

### D/A変換器
ディジタル信号とアナログ信号とを変換するための回路

### 間接アドレス指定方式
レジスタが示す番地に格納された値を、参照データの格納アドレスとする指定方式。

### MIPS
CPUの処理速度を表す単位で、１００万命令/秒を意味する
Pythonでsshして，コマンドの出力結果をリストに入れる

pythonでサーバーにsshして,入力したLinuxコマンドの出力結果をリストに格納する方法を説明します．pexpectを使用します．


Pythonでsshをする
---------------------------------------
まず，pyファイルを作りpexpectをインポートします．
```
from pexpect import pxssh
```

次にsshしたいサーバの情報を入力します
```
# ログイン情報を設定しSSHサーバーにログイン
ssh = pxssh.pxssh()
ssh.login(server="接続したいSSHサーバーのIP",  username="SSHサーバー側のユーザー名", password="接続したいSSHサーバーのパスワード")

この間に処理を書く

#ログアウト
ssh.logout()
```
pyフォルダを実行するには，pyフォルダがあるサーバのターミナルで

```
python3 実行したいpyファイル
```

これでssh接続ができます．

コマンドを実行してリストに格納する
---------------------------------------
下記のコードでできます

```
ssh.sendline('実行したいコマンド')
ssh.expect(r"\[.*\]\$ ",timeout=60)
komando=ssh.after.decode(encoding='utf-8')
↑またはssh.before.decode(encoding='utf-8')
list=(re.findall('切り取りたい文字列',komando))
```
---------------------------------------

1行ずつ説明します．
- ssh.sendlineは実行したいコマンドを入れてください（la -al,catなど）
- ssh.expectは特定の文字列（上記では`\[.*\]\$` ）が来るまで待機します．上記はターミナルの`test@testvm:~$`の`$`です．`$`が来たら次の処理に進みます．文字列はワイルドカードで指定します．
    timeoutは待機する時間です．デフォルトでは5秒になります．この時間を過ぎると処理が勝手に終了してしまうので，時間のかかる処理の場合は長めに設定しときましょう．
- ssh.after.decode(encoding='utf-8')は出力したコマンドと結果を出力します．afterとbeforeがあり，afterはssh.expectの前の出力が入り，beforeはあとの出力が入ります．例えば，下記のようになります．

```
ssh.sendline('ls /volume1/jasmine2-backup/backup')
ssh.expect(r"\[.*\]\$ ")
after=ssh.after.decode(encoding='utf-8')
before=ssh.before.decode(encoding='utf-8')
print("after:"+after)
print("before:"+before)
```
```
#結果
after:[0m2023-12-19-17-08  2023-12-21-17-08  2024-01-09-17-08
2023-12-20-17-08  2023-12-22-17-08
[PEXPECT]$ 

before:ls /volume1/jasmine2-backup/backup
```
確かに結果は出ましたが，これでは使いずらいです．
そこでre.findallで必要な文字列だけとってリストに入れます．
上記のフォルダだけ取りたい場合はワイルドカードで指定します．
```
after=ssh.after.decode(encoding='utf-8')
re=(re.findall(r'20\d*-\d*-\d*-\d*-\d*',after)
print(re)
```
```
#結果
['2023-12-19-17-08', '2023-12-21-17-08', '2024-01-09-17-08', '2023-12-20-17-08', '2023-12-22-17-08']
```

このようにpythonでsshして，コマンドの出力結果をリストに入れることができます．

-----------------------
subprocessでやる方法もあったのですが，上手くいかなかったので別の方法でやりました．同じような状況の人の役に立てればいいなと思います．

-----------------------
参考にさせていただいたサイト
https://zenn.dev/mtmatma/articles/19f4d455776723
直感 Deep Learning  書籍の1.3.2のコードで遭遇したエラー

出版から時間が立っていることとネットワーク環境のためいくつかのエラーが発生した。解決策を備忘録として残しておく。

前提条件
---
- HTTP通信監視下のProxy環境
- Windows10 64bit
- Python3.10.13
- tensoflow 2.15.0（書籍のコード中のkerasはtensorflow.kerasに置換した）

エラー その①
---
```
ImportError: cannot import name 'np_utils' from 'tensorflow.keras.utils'
```
### 対策：書き方がバージョンに合っていなかったのでコードを変更した。
```diff_python
- from tensorflow.keras.utils import np_utils
+ from tensorflow.keras.utils import to_categorical
```
https://stackoverflow.com/questions/45149341/importerror-cannot-import-name-np-utils

エラー その②
---
```
ERROR [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
Hostname mismatch, certificate is not valid for XXXXX.
```
下記コードを実行するとがエラーが発生しmnistデータのダウンロードができなかった。
```
(X_train, y_train), (X_test, y_test) = mnist.load_data()
```
### 対策：下記コードを先頭に追加した。
```diff_python
+ import ssl
+ ssl._create_default_https_context = ssl._create_unverified_context
```
https://end0tknr.hateblo.jp/entry/20210312/1615498434

エラー その③
---
```
FailedPreconditionError: XXXXX is not a directory
```
下記コードを実行するとエラーが発生しモデルの訓練ができなかった。
```
model.fit(X_train, Y_train,
batch_size=BATCH_SIZE, epochs=NB_EPOCH,
callbacks=callbacks,
verbose=VERBOSE, validation_split=VALIDATION_SPLIT)
```
#### 対策：カレントディレクトリのパスに日本語が含まれていたことが原因だったので、日本語のないパスに変更した。

https://stackoverflow.com/questions/76898131/failedpreconditionerror-runs-is-not-a-directory
Next.js で wasm が含まれるライブラリを使う場合は `NODE_OPTIONS=--experimental-wasm-modules` が必要

Next.js で wasm ベースのライブラリを使いたくなった。
というか自前で Rust のコードを wasm にして[ライブラリを作った](https://github.com/Mizumaki/wasma)ので、それを使いたくなった。

だが一筋縄ではいかなかったので、その備忘録

## wasm のコードを asset として配信する場合はそんな問題ない

自分で asset として wasm ファイルを置いておき、それを自前で読み込むとかの場合には特に罠はない。webpack の設定をよしなにしてやれば良いだけである。（SSR とかで Node が絡んでくると後述のように厄介になるので、dynamic import なりで解決する必要はある）

こちらの記事がわかりやすかった。
https://zenn.dev/razokulover/articles/fb64150be7a667

## wasm が含まれるライブラリを普通に import して使いたい場合

この場合、巷に溢れている情報だけだと上手くいかなかった。

### まずは必要な Webpack の設定

```next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.wasm$/,
      type: 'webassembly/async',
    });
    config.experiments = {
      asyncWebAssembly: true,
      layers: true,
    };
    return config;
  },
};

module.exports = nextConfig;
```

古い記事だと色々他にも設定入れていたりするが、これが現時点（`next@14.0.4`）での最小限の config であった。

ただ、これだけだと `Unknown file extension ".wasm"` エラーが出てきてしまう...

### `Unknown file extension ".wasm"` エラーの解決方法

webpack の指定もちゃんとしてるし、なんで `Unknown file extension` となってしまうのか...

```
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".wasm" for ...
```

と思っていたが、webpack 以前の問題で Node.js がそもそも `.wasm` を読み込んでくれていなかった。

`NODE_OPTIONS=--experimental-wasm-modules` を `next dev` の前に入れてあげると普通に読み込んでくれるようになった。結構これに辿り着くまでに時間かけてしまったので、誰かがこの記事で時間を節約できることを祈って :pray: 

## 余談：production build で `Error: ENOENT: no such file or directory` が発生する場合

本筋から逸れるが、Production Build だと上記の webpack config では動かなかった...:cry: 

調べると、一番手軽な解決のための hack としては

```js
if (isServer) {
  config.output.webassemblyModuleFilename = './../static/wasm/[hash].wasm';
} else {
  config.output.webassemblyModuleFilename = 'static/wasm/[hash].wasm';
}
```

のようなものがよく見られたが、`next: 14.0.4` だと全然上手く動かず苦労した...

結果的には

```next.config.js
function patchWasmModuleImport(config, isServer) {
  config.plugins.push(
    new (class {
      apply(compiler) {
        compiler.hooks.afterEmit.tapPromise('SymlinkWebpackPlugin', async compiler => {
          if (isServer) {
            const from = path.join(compiler.options.output.path, '../static');
            const to = path.join(compiler.options.output.path, 'static');

            try {
              await fs.access(from);
              return;
            } catch (error) {
              if (error.code === 'ENOENT') {
                // No link exists
              } else {
                throw error;
              }
            }

            await fs.symlink(to, from, 'junction');
            console.log(`created symlink ${from} -> ${to}`);
          }
        });
      }
    })()
  );
}
```

このような symlink を貼る script を用意して NextConfig の webpack に噛ませたら動いた。

https://github.com/vercel/next.js/issues/25852#issuecomment-1057059000

まだまだ wasm　周りは未解決の罠が多い...
モノリシック（monolithic）とは?? 

### ITにおける意味
ソフトウェア設計の際、部分的に分割をせず、全て同一のモジュールとして作り上げることをモノリシックな設計と言います。

### 雑学
モノリシックの対義語はマイクロです。﻿
モノリシックアーキテクチャーになっています。っという使い方をする。
階層型ストレージとは ?? の備忘録

### 階層型ストレージとは？超簡単にいうと、、

よく利用されるデータは高性能なストレージで利用。(例えばSSD)
利用頻度が低いデータは低性能かつ低コストなストレージ(例えばHDD)に移動させることによってコスト効率よく運用するストレージのこと。

#### 階層型ストレージ詳細説明
階層型ストレージでは、利用頻度やアクセスパターンに基づいてデータを異なる階層のストレージに配置することで、コストとパフォーマンスを最適化します。頻繁にアクセスされるデータは高性能なかつ高コストなストレージに配置し、アクセス頻度が低いデータは低性能かつ低コストなストレージに移動させることで、リソースを効果的に利用できます。

#### AWS Systems Manager のパラメーターストア

パスワードやAMIの設定データ管理と機密管理のための安全な階層型ストレージを提供しています。
paizaラーニング解答: Dランク・スキルチェック見本問題セット[Ruby]

# Dランク・スキルチェック見本問題セット
https://paiza.jp/works/mondai/d_rank_skillcheck_sample/problem_index?language_uid=ruby
## 掛け算
```ruby
a = gets.to_i
b = gets.to_i
puts a * b
```

## 足し算
```ruby
a, b = gets.split.map(&:to_i)
puts a + b
```

## 一番小さい値
```ruby
n = []
5.times do
    n << gets.split.map(&:to_i)
end
puts n.min
```
配列nを初期化して、<<で配列に追加しています。
minメソッドで最小値を取得できます。
## 文字の一致
```ruby
a = gets.chomp
b = gets.chomp
if a == b
    puts "OK"
else
    puts "NG"
end
```