OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】Lambda

# Lambdaとは
AWSが提供しているサーバーレスを実現するためのサービス。様々なプログラミング言語をサポートしている。必要な時に必要な分だけアプリケーションを実行できる。

:::note info
**サーバレス**
ソースコードさえあればアプリケーションの実行が可能で，サーバーの準備をする必要がない
:::

## Lambda関数
Lambdaで実行するアプリケーションのソースコードと，ソースコードの開発言語に対応したランタイムの2つを合わせてLambda関数という。

**エイリアス**はLambda関数の別名。エイリアスは最大2つのバージョンを指し示すことが可能。

# ランタイム
アプリケーションの実行に必要なライブラリやパッケージのこと。Lambdaには**カスタムランタイム**という機能があり，デフォルトのランタイムでサポートされていないバージョンのランタイムを作成・実行できる。

## デプロイパッケージ
Lambda関数をビルドして作成したパッケージのこと。

## トリガー
Lambda関数を呼び出すリソースや設定。呼び出し方には以下の2通りがある。
| 呼び出し方 | 説明 |
| ---- | ---- |
| 同期呼び出し | Lambda関数からのレスポンスの返却を待つ |
| 非同期呼び出し | リクエストの受付結果を受け取る |

## イベント
Lambda関数の呼び出し元から連携されるJSON形式のドキュメントのこと。

## 同時実行数
ある時点における実行中のLabmda関数の数。リクエスト:コンテナ=1:1。
東京リージョンでの最大値(**上限値(クォータ)**)は1000。

## Layers
複数のLambda関数が共通で利用するライブラリやカスタムランタイム，依存関係をZIPファイルで切り出して共有する機能。Layersを利用したLambdaの拡張機能として**Extensions**がある。

# メリット
* サーバ構築が不要
運用コストなど削減

* オートスケーリング
必要な時だけコードを実行し，リクエストの回数に合わせて自動的にスケールする。これによりリクエストが増えても安定したパフォーマンスを維持できる。

* 他のAWSサービスと連携
AWSサービスの操作を自動化できる。

# 利用料金
関数とデータ転送量に対して従量課金が発生。**Provisioned Concurrency**を有効化した場合は，有効化してから無効化するまでの時間に対して従量課金が発生する。

# 参考
https://aws.amazon.com/jp/lambda/
https://www.youtube.com/watch?v=Z9OaZMOmjqo&list=PLPzcoMdqG5noLR7rAc552mvPADUmmdSt1&index=5
AWSの基本・仕組み・重要用語が全部わかる教科書
[UE5] 複数人開発でBPに関する便利そうなデバッグ

# 概要
svn使ってて便利だなって感じたデバッグ関係です。

# .uassetの変更差分を確認する
自分のローカルとの差分を確認するやり方です。

アセットを右クリックし、「Source Control」→「Diff Against Depot」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/63961a11-68e1-7ff8-952a-e9a47d196979.png)

表示されるウィンドウにて、黄色くなっている部分が変更されている場所です。
画像のように緑色で細かく確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/0b1ab028-16b6-6984-7429-c1b487c0bbe4.png)


# .uassetの変更履歴を確認する
これまでの更新履歴についてとどういった変更がされていたか確認するやり方です。

アセットを右クリックし、「Source Control」→「History」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/8bf7cbf8-02a3-8583-5dd8-bc448f0ed3e0.png)

これまでの変更履歴が確認できます。
※無いとは思うけど、念のため色々隠してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/e164fa02-09f5-0bbb-02b8-fd54b3aadcd3.png)

適当なリビジョンを右クリックし、「Diff Against Prevoius Revesion」で変更差分が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/bc1a43ce-425c-f51f-a782-0484ed3229d1.png)

差分の内容は先ほどと同じような見た目となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/64f1cf08-10b3-8c9c-bd54-d0cc045869ea.png)


# ノードの呼び出し履歴を見る
cpp/hだとブレイクポイントを張り、呼び出し履歴をすると思いますが、それと同じようなものです。

「Tools」→「Debug」→「Blueprint Debugger」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/8ee6b3cf-c9c7-410a-f680-c24d7f09a37a.png)

このウィンドウを表示させた状態にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/77006218-a541-6945-8a3b-afc2a8c0ee51.png)

適当なBP内でブレイクポイントを張っておきます。今回は、プレイヤーがプレイ中にスポーンさせるようなアクター内で行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/babdf9e1-3906-86aa-1c0c-fbd7b0975e5c.png)

「Call Stack」のタブ内で画像のような形で確認することができます。（ちょっと例としては分かりにくいかも・・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252485/7a6b356e-bc3a-ba16-21f6-8b0351adc3ff.png)
M1 Mac へ Nim v2.0 インストール （without choosenim）

# M1 Mac へ Nim v2.0 インストール （without choosenim）

記事にする必要もなくとても簡単ですが、公式も含めいろんな方法が乱立していたため
v2.0時点でのM1 MacへのNimのインストールをまとめます


```Shell
# homebrewをインストール（インストールされていれば不要）
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

HomebrewでNimをインストールします。

```Shell
# brewでNimをインストール
$ brew install nim
```
・これで最新のNim（現時点では2.0）がインストールされます。
・choosenimは必要ありません。
・nim用パッケージマネージャ nimble もこれでインストールされます。

## nimble へパスを通す

nimbleでインストールしたコマンド系をどこでも使えるようにするために、環境変数を設定します。

```Shell
# zshの場合
$ echo 'export $PATH="$HOME/.nimble/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
```
SwinIRで鬼トリミングした画像を魔解像する

SwinIRをやっている記事をいくつか見つけましたが、どうもすんなりいかなかったので確実にできる方法をメモしておきます。

今回はこちらの画像を使用します。

![ZZ8_0492.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/fd303cf9-3f7e-7636-1c8e-491a962b2bb8.jpeg)


400m先のキンクロハジロを500mmの望遠レンズで撮影し、フルサイズ8300×5500ピクセルの画像を800×530ピクセルまで鬼トリミングしたものです。

まずはgoogle Colaboratoryを立ち上げ、ノートブックを新規作成。SwinIRなどと名前を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/d3cc0a7b-0256-5315-f6e1-b4b66608cc37.png)

右上のアカウントのアイコンをクリック。
googleのアカウントを管理をクリック。
右上のgoogleアプリをクリックし、ドライブをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/f956a5c9-d831-9e0d-3c60-a8d20d3d3bb6.png)

マイドライブの画面になります。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ここでいったんノートブックに戻ります。
作業ディレクトリをマイドライブに移動します。
```python
from google.colab import drive
drive.mount('/content/drive')
%cd ./drive/MyDrive
```
timmをインストールします。
```python
!pip install -q timm
```
opencvをインストールします。
```python
!pip install -q opencv-python
```

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

SwinIRのpythonファイルは[こちら](https://github.com/JingyunLiang/SwinIR)からZIPファイルをダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/3ac8dbc8-21e9-85ca-8b67-983ce7620e4b.png)

ダウンロードしたら、すべて展開します。
SwinIR-mainというフォルダの中にさらにSwinIR-mainというフォルダがありますが、
この名前が長いのでSwinIRに変更しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/35d8abab-2faf-18aa-ca72-35cdda2d7515.png)

その中にpythonファイルなどが入っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/85ee1c9d-c879-742e-2dda-c3173594210d.png)

testsetsフォルダにはRealSRSet+5imagesというフォルダがあり、サンプル画像が保存されていますが、自分が解像させたい画像でない限りこれを使う必要はないでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/e42ce094-170f-9c5b-47c7-10c2fc368391.png)


testsetsフォルダ内にsampleという名前（なんでもよい）で新しいフォルダを作成します。
この中に今回解像させたい画像を入れます。

名前を変更したSwinIRフォルダをマイドライブにドラッグ＆ドロップでアップロードします。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ノートブックに戻り、作業ディレクトリをSwinIRフォルダに移動します。
```python
%cd ./SwinIR
```

以下のコードを実行します。

```python
!python main_test_swinir.py \
  --task real_sr \
  --model_path experiments/pretrained_models/003_realSR_BSRGAN_DFOWMFC_s64w8_SwinIR-L_x4_GAN.pth \
  --folder_lq testsets/sample \
  --scale 4 \
  --large_model
```

新たにresultsフォルダが作成され、その中のswinir_real_sr_x4_largeフォルダに作成された画像が保存されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/5500278c-e8f1-8b3c-06f9-931583ddbaf4.png)

フォルダ名をsample以外にしたい時は
--folder_lq testsets/sample \
のsampleを変更してください。

こんな感じになりました。

![ZZ8_0492_SwinIR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/05416939-098f-04f0-3808-ef53757135bc.png)


元の画像を拡大して見比べた結果がこちら！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635830/153128e2-f1ab-75dd-72ff-6ad94dc66f5e.png)

遠くの鳥を撮って証拠としてブラッシュアップしたい時に使えそうです。
DB設計

# 初めに
データベース(DB)の設計には大きく分けて「論理設計」と「物理設計」という二つの段階が存在する。
論理設計が「何を保存するか」に焦点を当てるのに対し、物理設計は「どのように保存するか」に焦点を当てる。

# 論理設計
データベースの構造を定義する段階。
どのようなデータを格納するか、データ間の関係はどうなるかなどを決定する。
主な目的は、データの整合性と効率的なアクセスを確保すること。
以下の要素が考慮される。

### データモデルの選定
例えば、リレーショナルモデルや非リレーショナルモデル(NoSQL)など。

### エンティティと属性の定義
データベースで管理する各種データ(エンティティ)と、それらの特性(属性)。

### 関係の定義
エンティティ間の関係を定義し、それらの結合方法を決定する。

### 正規化
データの重複を避け、効率的なデータ管理を実現するため行う。

# 物理設計
論理設計で定義された構造を実際のデータベースシステム上で実装する段階。
目的はデータベースの性能やストレージの効率を最適化すること。
以下の要素が考慮される。

### データの格納方法
データがどのようにディスク上に保存されるかを決定する。

### インデックスの設計
検索効率を高めるためのインデックスを設計する。

### パーティショニング戦略
大量のデータを効率的に管理するためにデータを分割する。

### セキュリティとバックアップ
データの安全性を確保し、災害時にデータを復旧できるようにする。
出先でも家のグローバルIPを取得できるようにする

# 出先でも家のグローバルIPを取得できるようにする

我が家はインターネッツの契約上、グローバルIPがちょくちょく変わる。
出先でお家のPCにリモートデスクトップやSSHしたい時に、グローバルIPが変わっていて詰むことが稀によくある。
なので、出先でも家のグローバルIPを取得できるようにする。

## 構成

- GAS
- RaspberryPI

## 仕組み

- 自分のネットワークのグローバルIPを取得し、GASにPOSTするシェルを作り、
常時起動したRaspberryPIのCronにそれを定期的に実行するように設定する。
- GAS側では、受け取ったグローバルIPが以前のIPと変わっていたらメール通知する。

## コード

こんな感じのスプレッドシートを用意
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213727/8cb82791-72ef-7be3-4298-8c2517bcc138.png)

GASのコード

``` gas
const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
const sheet = spreadSheet.getSheetByName("index");

function doGet(e) {
  const name = e.parameter['name'];
  if (!name || name == "") {
    return createResponse({
      status: "400",
      message: "name is require"
    });
  }

  const requestIP = e.parameter['ip'];
  if (!requestIP || requestIP == "") {
    return createResponse({
      status: "400",
      message: "ip is require"
    });
  }

  const userdata = getUserDataByName(name);

  if (userdata == null) {
    return createResponse({
      status: "404",
      message: '"' + name + '" is not found'
    });
  } 

  if (requestIP != userdata.ip) {
    updateIPByName(name, requestIP);

    const address = userdata.email;
    const subject = "IP変更が検知されました";
    const body = "変更後のIP: " + requestIP
    GmailApp.sendEmail(address, subject, body);

    result = {
      status: "201",
      ip: requestIP
    }
  } else {
    result = {
      status: "200",
      ip: requestIP
    }
  }

  return createResponse(result);
}

function createResponse(obj) {
  const output = ContentService.createTextOutput();
  output.setMimeType(ContentService.MimeType.JSON);
  output.setContent(JSON.stringify(obj));
  return output;
}

function getUserDataByName(name) {
  const data = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
  const values = data.getValues();
  const idx = values.findIndex(ary => ary[0] == name);
  if (idx == -1) {
    return null;
  }
  return {
    name: values[idx][0],
    ip: values[idx][1],
    prevIP: values[idx][2],
    email: values[idx][3],
  };
}

function updateIPByName(name, ip) {
  const data = sheet.getRange(2, 1, sheet.getLastRow() - 1, sheet.getLastColumn());
  const values = data.getValues();
  const idx = values.findIndex(ary => ary[0] == name);
  if (idx == -1) {
    return;
  }
  values[idx][2] = values[idx][1];
  values[idx][1] = ip;
  data.setValues(values);
}

```

RaspberryPIのシェルのコード

``` bash
response=$(curl -s httpbin.org/ip)
ip=$(echo "$response" | jq -r '.origin')
curl -L "https://{GASのURL}?name=renon&ip=$ip"
```

## 実際に届くメール

![image-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1213727/0bbc96f0-4864-6b7c-d4b7-6c5d498e905d.png)

## おわり

出先の開発が快適になった。
groovy以外のファイルのスクリプトをjenkins pipelineで使う方法

# どんな時の話？
1. jenkins pipelineでビルドスクリプトをSCMチェックアウトで取ってくる
1. 新たに、ビルド対象のrepositoryを取得
1. groovy以外のpy, bat, shファイルなどを動かしたい（こいつは、1番目のビルドスクリプトと同じrepositoryに存在）


という状況があったとします。
これの解決方法

# どうするか

答えとしては、明快です。
1番目のビルドスクリプトを配置しているrepository取得時に、pythonなどのファイルをローカルに作成します。

```groovy
stage ('SCM checkout') {
        checkout scm
 
        hogeUtility = load "hogehoge/utils/hogeUtility.groovy"

        // hoge.pyをローカルに作成
        hogepy = readFile(file:'hogehoge/utils/hoge.py') //✨これ
        writeFile(file:'hoge.py', text:hogepy) // ✨これ
    }
...
 
```
参考：

https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#writefile-write-file-to-workspace

これをすると、workspaceフォルダのroot直下にhoge.pyが作成されます。
これに合わせてpythonをコマンドで叩けばOKです。
パスをコピー元と一緒にしたい場合は、fileで指定すればよいです。

```groovy
sh 'python hoge.py'
```
とかですかね。

# まとめ
欠点としては、いちいちファイルを作ることです。
面倒ですね。
groovyの中に直接書いてもいいかもしれません。
本稿の目的は、すでにあるpythonファイルなどをそのまま動かしたい場合です。
「バンダイナムコスタジオ」様のワークショップに参加してきました【Go言語】

# はしがき

　2023年12月2日、バンダイナムコスタジオ様が開催された『**サーバーエンジニア編「Go 言語でゲームサーバーを作ろう！ゲームサーバー API プログラミング ワークショップ」**』に参加してきました。
 
　本記事では、参加レポートを記述します（ほとんど個人的な感想です）。今後、同社のインターンやワークショップに参加を検討されている方の参考なればと思います。

　ちなみに、リモートで1日の開催です。

* 参考

https://www.bandainamcostudios.com/recruit/graduate/news/12604

* プレイ画像
![インゲーム画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621804/b1f51763-c710-83ed-8886-94472d970a24.png)

# 全体的な感想

### 参加した理由

　日常的に書いている言語がGoであったため、「Go言語のワークショップ」という言葉に惹かれ、気づいたらエントリーしていました。また、SQLやコンテナといった技術も勉強したことがあり、このワークショップに参加すれば成長できそうと考えました。

### 当日の流れ

　当日は「Gather」というサービスを使用しました。Gatherは、RPGっぽいマップ上を移動して会話ができるツールです。マップ上には、全員が集まれる場所以外にも、一対一で話せる場所や4人程度で集まれる場所もたくさん用意されていました。

　ワークショップは10時から開始でしたが、トラブルで遅れて10時30分からとなりました（本当にお疲れ様です）。最初に会社説明があり、次にワークショップ内容の説明がありました。その後、休憩を挟みながらコードを書き、最後に質疑応答と懇親会を行って終了しました。

　実習では3人から4人ごとに分かれ、Gatherのプライベートエリアに入って作業をしました。私のグループでは、学生間での会話も少しありましたが、基本的には黙々と作業する雰囲気でした。定期的に講師の方がプライベートエリアに入って進捗確認や質問の対応をしていたので、その場で質問しやすい雰囲気だったと思います。


### 内容

　今回は、ワークショップ用に簡素化された「ミスタードリラー」を使用して、WebAPIサーバーの実装を行いました。具体的には、ブラウザ上で動作するゲームからHTTPのリクエストを受け取り、処理を行った結果をレスポンスとしてブラウザに戻す、といったプログラムを書きました。そのため、JSONやHTTPレスポンスステータスコードについて知っていると、コードの理解が捗ると思います。
 
　機能としては、ゲームリザルトの記録、複数ユーザ間のランキング、アチーブメントを実装しました。（私は「アチーブメント」という言葉を初めて聞きましたが、「実績」みたいな機能でした。「10回プレイした」とか「スコアを5000以上達成した」などです）

* アチーブメントの画面
![アチーブメント画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621804/d269ba6c-a2d7-cdcf-5286-737518622c54.png)

### ワークショップの課題
　課題は「Step 1」から「Step 6」までの6つの課題に加え、全て終わってしまった人のために追加課題がたくさん用意されていました。私も含め、多くの人は追加課題まで進めないほどの量なので、早く進めるより、ゆっくりロジックを考える方が得るものが多いと思います。
 
　そもそも課題は学生向けにレールが敷かれているので、ぶっちゃけてしまうと、片付けるだけであれば考えることは多くありません。しかし、WebAPIの処理を中心に、周りのロジックがどのように動いているのかを考えてみると、かなり勉強になると思います。

　私の場合、最初の方はゆっくり考えながら実装を行なっていました。しかし、時間が経つにつれ、「Step 6」までは終わらせたいという気持ちが強くなり、かなり急いで「Step 6」の実装をしました。振り返ると、課題を終わらせることが目的になっても仕方がないので、あまり良い行動ではなかったなと反省してます。

### 参加するにあたって必要な知識

　まず、Go言語の基本的な書き方は知っている必要があると思います。Go言語の未経験者でも参加できるとは思いますが、事前に時間をかけて勉強をしておかないと、当日は結構辛そうな雰囲気があります。加えて、SQLがGo言語に次いで必要な知識かと思います。ただ、SQLが苦手な私でも問題なく取り組める程度の難易度感です。
 
　上記は主観的な意見ですので私のバックグラウンドを補足すると、Go言語は勉強を始めてから半年程度、SQLは一年前に初心者向けの書籍を一周した程度です。

# おわりに

　今回のワークショップには、Go言語についてレベルアップをしたいと考えて参加しました。しかし、Go言語について詳しくなれたというより、開発に関わるツールや周辺技術の知識がつきました。他にも、バンダイナムコスタジオ様自体についてやゲーム業界について、より深く知ることができました。
 
　すでに書かれたコードを読みながら実装を行う経験も貴重なものでしたので、今回のワークショップに参加できて幸運だったと思います。ワークショップで使用したWebAPIサーバーのソースコードはダウンロードして良いとのことだったので、時間がある時に眺めてみようと思います。
外部ツールからGoogleChartでメッセージ送信

# 議事概要
会社・個人でGooleChatを使っている人向け。外部ツール等からMessageを投げる方法。  

# 方法
Webhook取得後、URLに向けてPostでOK。

# スクリプト

**⇓Python**
```python
import json
import requests

webhook_url = 'https://chat.googleapis.com/v1/spaces/xxxxxxxxxxxx'

message = {
    'cards': [
        {
            'header': {
                'title': 'title',
                'subtitle': 'subtitle',
                # 'imageUrl': 'https://xxxxx.png',
                # 'imageStyle': 'IMAGE',
            },
            'sections': [
                {
                    'widgets': [
                        {
                            'keyValue': {
                                'topLabel': 'topLabel',
                                'content': 'Hello Wrold !',
                                'onClick': {
                                    'openLink': {
                                        'url': 'https://qiita.com/'
                                    }
                                },
                                'icon': 'DESCRIPTION',
                            }
                        }
                    ]
                }
            ],
        }
    ]
}

# message = {
#   'text': 'Hello World !'
# }
headers = {'Content-Type': 'application/json; charset=UTF-8'}
response = requests.post(webhook_url, headers=headers, json=message)
print(response.status_code)
```

**⇓PowerShell**
```powershell
# Webhook URL
$webhookUrl = 'https://chat.googleapis.com/v1/spaces/xxxxxxxxxxxx'

# Message
$jsonData = '{
    "cards": [
        {
            "header": {
                "title": "title",
                "subtitle": "subtitle"
            },
            "sections": [
                {
                    "widgets": [
                        {
                            "keyValue": {
                                "topLabel": "topLabel",
                                "content": "Hello Wrold !",
                                "onClick": {
                                    "openLink": {
                                        "url": "https://qiita.com/"
                                    }
                                },
                                "icon": "DESCRIPTION"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}'

# $jsonData = '{
#   "text": "Hello World"
# }'

# HTTP POSTリクエスト
Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $jsonData -ContentType 'application/json; charset=UTF-8'
```

# 参考
⇓公式が分かりやすい。  
<a href="https://developers.google.com/chat/concepts?hl=ja" target="_blank">https://developers.google.com/chat/concepts?hl=ja</a>

# 使い方
上のスクリプトはカード型のサンプルなので、クリックした際のURLや画像を設定すれば色々活用ができる。  
私自身はファイル監視のスクリプトと組み合わせて、ファイルがないorファイルの更新が一定期間されていない時にGoogleChatに通知するようなことをしていた。
[Re:VIEW] minted を使ったコードブロックで自動改行されない場合の解消方法

https://review-knowledge-ja.readthedocs.io/ja/latest/latex/minted.html

上記の記事を参考に、`review-ext.rb` を設定したところ、`listnum` などのコードブロックにおいて長い行がブロックをはみ出してしまう。この解消に少しハマったのでメモ。

## 原因

`minted` パッケージの `breaklines` オプションが効いていないことが原因。

## 対処

以下の2通りの方法で解消できる。

### 言語ごとに自動改行を有効化する方法

`review-custom.sty` ファイルに以下を追記する。

```diff_te_x
% for user-defined macro
\usepackage{minted}
\usemintedstyle{solarized-light}

+ \setminted[python]{breaklines=true}
```

他の `minted` のオプションも同様にここで指定できる。
これは上記のドキュメントにも記載があったが、`breaklines` オプションが自動改行を司っていることに気付くのにすこしかかった。

### 全てを対象に自動改行を有効化する方法

これは `review-ext.rb` を編集する方法。ドキュメントの通りに設定していれば、`common_minted_code()` の中に以下の記述がある。 

```ruby
      args = ''
      if lineno
        args = "linenos=true,firstnumber=#{lineno}"
      end
      puts %Q(\\begin{minted}[#{args}]{#{lang}})
```

これを以下のように書き換える。

```diff_ruby
-     args = ''
+     args = 'breaklines=true'
      if lineno
-        args = "linenos=true,firstnumber=#{lineno}"
+        args = "linenos=true,firstnumber=#{lineno},breaklines=true"
      end
      puts %Q(\\begin{minted}[#{args}]{#{lang}})
```

これで minted を使ったコードブロックでも自動改行が有効化される。

## 参考

https://www.ctan.org/pkg/minted
Nim v2.0 リリース！

# Nim v2.0 リリース！

こちらの公式記事を要約、日本語化しております。
[Nim v2.0 released](https://nim-lang.org/blog/2023/08/01/nim-v20-released.html)

## 何が大きく変わったのか
1. GCのARC/ORCアルゴリズム改良が完成！
2. タプル型の代入がより直感的かつネスト可能に
3. 型推論にトップダウン推論を対応
4. オーバーロード可能なEnum
5. オブジェクト宣言時にデフォルト値を設定可能に
6. 型不一致の際のエラーメッセージがわかりやすく

### 1. GCのARC/ORCアルゴリズム改良が完成！

　語弊を恐れずにわかりやすくすると、
　Rustのような厳格なメモリ管理が特別に意識せずGCで行えるようになりました。

　実はv1.4からARC/ORCについての対応は進んできていました。
　そちらが今回改良も含めて完成したということですね！

　NimはRustと比較されることが多いので、例として挙げさせていただきましたが
　Rustの所有権の概念と同じように、確保した変数メモリがスコープを抜けると
　解放されるようになっています。
　つまりコンパイル時にコンパイラからスコープを判定してデストラクタを入れています。
　
　ARC, ORCはどちらもGCのためRustの障壁となる学習コストをかけずに
　GCにお任せしつつ効率的なメモリ管理ができます。

　ORCの詳しいアドバンテージについては、素晴らしい記事があるのでこちらを...！
 
　[Nimのメモリ管理を理解する④ ― ORC - アルゴリズムによるアドバンテージ](https://zenn.dev/dumblepy/articles/efffa86d9177b1)

### 2. タプル型の代入がより直感的かつネスト可能に

```Nim
proc returnsNestedTuple(): (int, (int, int), int, int) = (4, (5, 7), 2, 3)

# Tuple型のネストが展開でも使用可能！
let (x, (_, y), _, z) = returnsNestedTuple()
```

お、Qiitaのコードスニペットもまだv2.0に対応していないので、エラーになってますね。

### 3. 型推論にトップダウン推論を対応

これまでは下記のような複雑な型チェックはコンパイルできませんでしたが、
v2.0からコンパイル可能になりました。

```Nim
let foo: seq[(float, byte, cstring)] = @[(1, 2, "abc")]
```

### 4. オーバーロード可能なEnum

具体的には外部ライブラリと同名のパラメータとの曖昧性回避などにに役立ちます。

```Nim
type
  E1 = enum
    value1, value2
  E2 = enum
    value1, value2 = 4

const
  Lookuptable = [
    #　曖昧性の回避
    E1.value1: "1",
    value2: "2"
  ]
```


### 5. オブジェクト宣言時にデフォルト値を設定可能に

こちらは他の言語だとお馴染みでしたが、今までは宣言時にデフォルト値を入れることができなかったため便利になりました。

```Nim
type
  Rational* = object
    num: int = 0
    den: int = 1

var r = Rational()
assert $r == "(num: 0, den: 1)"
```

### 6. 型不一致の際のエラーメッセージがわかりやすく

```Nim
proc foo(s: string) = discard
proc foo(x, y: int) = discard
proc foo(c: char) = discard

foo 4
```

上記コードを実行したときのエラー出力が下記のように表示されるようになります。

```Nim
temp3.nim(11, 1) Error: type mismatch
Expression: foo 4
  [1] 4: int literal(4)

Expected one of (first mismatch at [position]):
[1] proc foo(c: char)
[1] proc foo(s: string)
[2] proc foo(x, y: int)
```


標準ライブラリがnimbleに移動したので下記でインストールするように変更されました

```shell
# 例：
$ nimble install punycode

# パッケージ名の移動
std/punycode => punycode
std/asyncftpclient => asyncftpclient
std/smtp => smtp
std/db_common => db_connector/db_common
std/db_sqlite => db_connector/db_sqlite
std/db_mysql => db_connector/db_mysql
std/db_postgres => db_connector/db_postgres
std/db_odbc => db_connector/db_odbc
std/md5 => checksums/md5
std/sha1 => checksums/sha1
std/sums => sums
```
中学生がGitHub Educationの申請に大苦戦した話

最近話題のGitHub Copilotを使ってみたいと思いGitHub Educationの申請を行うことにしました。
## GitHub Educationとは
・**GitHub Copilotが無料で使える**
・GitHub PROが無料で使える
・GitHub Student Developer Packが使える
その他は

https://qiita.com/Kobayashi2019/items/5adb9bde57691a770419

中学生なので使えるのか迷ったが13歳以上と書かれていたため申請することにした。
## 申請方法
下記の記事を参考にした。

https://qiita.com/Kobayashi2019/items/5adb9bde57691a770419

https://qiita.com/shuki/items/1ad3e0a5cb8abce3cdbf

学校のメールは制限が多く、組織外からのメールは跳ね返される様になっていました。
そのため、生徒手帳の写真をアップデートする必要がありました。(ed.~,ac.~のアドレスなら結構スムーズにいくみたい。)
参考にした記事よりも審査が厳しくなっており、結局6回リクエストする羽目になりました。

:::note warn

記事は2023/10月末時点の情報です。
:::
1.GitHub Educationの[申請ページ](https://education.github.com/discount_requests/application)に行く
2.説明をよく読む![説明](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553326/7ac9be76-a6f8-734a-ea23-aeed460de9a4.jpeg)
3.フォームに記入する![フォーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553326/9efd694f-81f3-8760-ac1b-17f96e15e56d.jpeg)
"How do you plan to use GitHub?"のところは中学英語レベルの作文でも通りました。
たとえ、学校用メールアドレスが使えなくても登録してあるメールアドレスを必ず選択する必要があることに注意！
continueボタンを押すと位置情報共有の許可が求められるためOKを押します。
4.学校の所在地をマップから選択します。Bing maps?が埋め込まれていて検索すると素早く見つけられます。
5.生徒手帳 or 学生証の写真を撮影またはアップロードします。
私は、最初、生徒手帳の写真をPowerPointに貼り付け右側に英訳を記載しました。
しかし、アップロードした画像は信頼性がないと拒否されてしまいました。
![拒否](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553326/3ed51bc5-37c6-55cb-09e5-39304f631c6d.jpeg)
そこで、生徒手帳と英訳をクリップボードに挟み、Webカメラで撮影したところうまくいきました。
![成功](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553326/dd3d449b-ade8-fa0a-14d3-4b3d01c0c7e5.jpeg)
6.処理が完了するのを待つ
処理が完了して、適用されるまでには約4日かかるようです。
## 学割が適用されたら...
![学割](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553326/6078c8f4-f269-46f7-e858-d010224e7169.jpeg)
様々な恩恵を受けることができます。
・クレジットカードを登録しなくていいため、親に迷惑をかけない所が良いところです。
申請は簡単とは言えませんが英語の勉強がてら申請しないともったいないと思いました。
Cursor コードのカラーがVScodeと一致しなくてめっちゃ詰まった

## 概要

最近エディターのCursorを使い始めた。setting.jsonなどは設定を同期する拡張？を使ってVScodeから同期した。コードを開くと何故かコードに色があまりない。馴染みの色が出ずすごくコードが読みにくかった。友人に愚痴ったところ助けてくれたので懺悔を兼ねて簡単にまとめる。

## 原因

エディターのテーマがVScodeとCursorで違っていた。
VScodeがダークモダンだったのに対し、CursorはAnysphere Darkだった。

## 言い訳

まさか配色テーマがコードの色に関係していると思わなかった。勝手な思い込みで「PHPのコードの色なんだからなんか自分が入れてるPHPの拡張機能が勝手にコードに色つけてるんだろう」と思っていた。

## 配色テーマの変更方法

1. Cursorのウインドウをクリックしてアクティブにする。
1. 右上の帯の「Cursor」をクリックする。
1. 「基本設定」→「テーマ」→「配色テーマ」と進む。

    ![スクリーンショット 2023-12-05 21.56.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d919df14-1ec3-9cbe-31c7-33355fb756fe.png)

1. 表示のなかから配色テーマを設定する。（自分はダークモダンが見やすい。）

    ![Cursor_と_PostRegisterControllerTest_php_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8e19750f-a022-7cc0-0459-a3a66484b386.png)

## 謝辞

本件を教えてくださったお友達さんにこの場を借りて感謝させてください。本当にありがとうございます。
「いや〜Cursorはコードに色が出ないからちょっと見にくいんですよね〜」とかほざいてた自分をぶん殴りたいです。
pygameを使って、簡単なインベーダーゲームを作成&自己紹介

# 自己紹介
初めまして！
現在、プログラマーを目指して勉強中の大学生である「kazuma」と申します！
出身は静岡県で、現在は文系学部の大学に所属しています！
趣味：ゲームをすること。筋トレなどの一人で体を動かすこと。読書
最近興味のあること：プログラミングを勉強すること。漫画アプリで漫画を読むこと。マガポケで読める「私のアリカ」はオススメです！

まだまだプログラミング初心者ですが、これから学習をしていき、いずれ自身の制作物を開発したいと思っています！今後ともよろしくお願いいたします:bow:

## 投稿のきっかけ
最近、技育CAMP勉強会に参加し、そこで情報発信が大事なのかということを知りました。
なので初心者とはいえど、発信していきたいと思ったため、今回は自己紹介＆動画を参照しながら制作した「インベーダーゲーム」の紹介をしたいと思いました。今後はどうなるか未定ですが、何かしら投稿していきたいと思っています！


# 制作したゲームの主な内容
#### ソースコードや使用した画像ファイルなどは以下のGithubを参照してみてください
（本当にすみません:cry:ソースコードのpyファイルを記載するのに苦戦してしまい、今回はGithubのみとなりました...）
GithubのURL:https://github.com/Mio-3/InvadersGame_pygame.git

### 名前：InvadersGame_pygame
#### 内容：
Pythonのライブラリである「pygame」を使って、簡単なインベーダーゲームを開発

使用した言語：Python3

#### ゲームの流れ、ルール：

1.タイトル「Invader Game」の表示の下に、「Press Space key」とあるので、スペースキーを入力する

2.ゲーム開始、制限時間は30秒。プレイヤーは宇宙船を操作して、左右に動いて、迫り来るエイリアンを倒す！！

3.キーボードの左右の矢印キーを推して、宇宙船が移動。スペースキーを押すことで攻撃することができる！スコアはエイリアンを一体倒すごとに、1点追加される。できるだけ多く倒せ！！！

4.30秒後、ゲームが終了。最後の画面に、「Thank you for playing!」の表示と、最終スコアの表示があり、ゲーム終了。


参照した動画のYoutubeのURL:https://youtu.be/fAJ_BjLd3Ro?si=X8zrxiWPnneC9fiX

#### 動画の内容以外に、自身で実装したもの：
ChatGPTなどを用いて、実装しました。

・エイリアンの数を複数体現れるようにしたこと

・制限時間や背景画像の追加

・ゲーム終了時に最終スコア、「Thank you for playing!」の表示の実装

# 終わりに
一通り制作して思ったこととしては、とても大変だった...！！
でも楽しい！！！！！！

この思いが浮かびました。
まだまだ多くの機能の追加などができると思うので、次に制作する時は、他の機能も実装できるようにすることが、今後の課題です。

長くなりましたが、今回の初投稿は以上とさせていただきます。

ここまで見ていただいた人には、本当に感謝します！！！
JointJS解説　～Link編～

今回はJointJSの描画要素であるLinkについて解説します。

## Linkとは

Linkは図形と図形をつなぐ線です。つなぐ対象の図形の位置から自動的に計算された座標で描画されます。

## Linkの使い方

Linkに対して`source`と`target`を設定します。`source`と`target`にはつなぐ対象の図形をそれぞれ設定します。

### コード例

```js
// つなぐ対象の四角形の生成（設定は省略）
const rectangle1 = new joint.shapes.standard.Rectangle();
const rectangle2 = new joint.shapes.standard.Rectangle();

// Linkの生成
const link = new joint.shapes.standard.Link();
link.source(rectangle1);
link.target(rectangle2);
link.addTo(graph);
```

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/00ef024e-6b5b-ead4-fa31-bb00449f1f44.png)

インタラクティブな操作を許可している場合、要素の移動に追随してLinkも移動します。

![dadlink.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/9315f6a7-a511-6e35-88d1-23cd1edc59da.gif)

`source`と`target`には座標を指定することもできます。引数は`x`と`y`を含むJSONであればOKですが、JointJSのAPI群に「Geometry API」があり、その中の`Point`クラスを使用すると確実です。

```js
// JSONを使用
link.source({x: 100, y: 30});

// Geometry APIのPointクラスを使用
link.target(new g.Point(300, 40));
```

## 経由点の追加

`vertices(verticesArray)`メソッドを使用すると、Linkの経由点を追加できます。引数の`verticesArray`にはGeometry APIの`Point`の配列を指定します。

### コード例

```js
const point1 = new g.Point(20, 70);
const point2 = new g.Point(500, 100);

link.vertices([point1, point2]);
link.addTo(graph);
```

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/3845c317-f9b9-be66-deaa-dad4b631301d.png)

## Ancherの指定

Anchorを指定すると、Linkの端点の位置を調整することができます。例えば以下のコード例だと、`source`側の要素のは左下の点から、`target`の要素の右上の点へLinkが描画されます。さらに`target`側では`dx`,`dy`での座標調整があり、右上の点からズレた位置が端点となります。


### コード例

```js
link.source(rectangle1, {
  anchor: {
    name: 'bottomLeft'
  }
});
link.target(rectangle2, {
  anchor: {
    name: 'topRight',
    args: {
      dx: 20,
      dy: -10
    }
  }
});
```

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/bf98c0e2-6c37-f19a-d8d7-fee1ca18b330.png)

## まとめ

Linkを使用すると座標を意識せずに簡単に要素同士をつなぐことができます。要素をつなぐような要件がある場合は積極的にLinkを使うようにしましょう。

※この記事は [JointJS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/jointjs) の記事です。他の記事を読む場合はカレンダーのページを参照してください。

https://qiita.com/advent-calendar/2023/jointjs
cp, mv, rsync 等の verbose が遅い時は nohup か ＆ で

## verbose モードは GPU の性能にも左右される

ファイル数が多ければ多いほど verbose モードだと
インターネット回線の速度やGPUの影響を受ける事があります。

下記の例ではローカルのdockerで実行したので
--verbose 有りと無しで大した差が出ませんでしたが、
これがインターネット回線越しなら重そうだな... と伝われば幸いです。

![console.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631853/215e6208-873d-30d1-0113-7d19bb409f69.gif)

| verbose 有り | verbose 無し |
|:-:|:-:|
| real  　0m3.834s  | real  　0m3.613s  |
| user  　0m0.121s  | user  　0m0.028s  |
| sys   　0m0.962s  | sys   　0m0.582s |

### しかし verbose を OFF った cp -R [コピー元] [コピー先] じゃ画面が動かないので、どこまで進んでいるか分からんのです...

そんな時は `> result.txt  2>&1 &` 🎉　result.txt とかファイル名はお好みで。

```
$ time(cp -Rfpv qiita copy-test) > result.txt 2>&1 &
$ tail result.txt
'qiita/movabletype/xt/use_close_tag.t' -> 'copy-test/qiita/movabletype/xt/use_close_tag.t'
'qiita/movabletype/yarn.lock' -> 'copy-test/qiita/movabletype/yarn.lock'

real    0m2.582s
user    0m0.024s
sys     0m0.706s
```

作業の合間にでも tail で確認しましょう。

## サーバー上で実行するなら sh + nohup が安全

```
$ vi copy.sh
#!/bin/bash
time(cp -Rfpv /tmp/qiita /tmp/copy-test)
```
↑ シェルでやる時は絶対パスで指定した方が安全かつ一目瞭然です

```
$ chmod 700 copy.sh
$ nohup ./copy.sh > result.txt 2>&1 &
```

これでSSHの接続が切れても実行し続ける事が出来ます

別に sh を作らなくても nohup シェル芸 でいけますが、
いざという時に `ps -ajxwww | grep [スクリプト名]` で
プロセスID見つけて落とす事ができるので、慣れておいて損はないかと。

---

ところで、RHEL 9 で試したところ nohup ではないバックグラウンド実行(＆)でも
SSH接続切っても実行され続けたのですが、仕様が変わった...？
【MySQL】DB名にハイフンがあると「You have an error in your SQL syntax」になる

# 概要

以下のようなSQLだとエラーになりました。

```sql
'DELETE FROM mysql57-dummy.sample WHERE...（略）'
```

エラーメッセージは以下の通り。

```
SQLエラー [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-dummy.sample WHERE...
```

# 原因と解決方法
エラーは、データベース名にハイフンが入っていたため。
一部の文字列が正しくエスケープされていないためにエラーが発生しています。

ハイフンが入っているデータベース名の場合、バッククオートで囲んであげるとエラーが解決できます。
今まであまり気にしてなかったけど、そうだったんか...

クエリ文字列の組み立て部分を次のように変更すればOK。

```sql
'DELETE FROM `mysql57-dummy`.sample WHERE...'
```

これにより、データベース名とテーブル名が適切にエスケープされ、SQL文が正しく処理されるようになりました。
ゲーム開発において開発のフローやルールを細かく決めることは大切ですか？

[QualiArts Advent Calendar 2023](https://qiita.com/advent-calendar/2023/qualiarts)、7日目の記事です。
QualiArtsでエンジニアリングマネージャー/開発ディレクターをしている、新見です。
これまでに、4つのゲームサービスの運用、2つの新規立ち上げを経験してきました。

# はじめに
ゲームの開発において、タスクの開発規模に問わず必ずチームで定めた開発のフローやルールがあると思います。開発フローと言っても、開発フェーズの違いや組織やチームで導入するツールの違いによって全く違うものだとは思いますが、今回は一連の流れを開発のフローとしてイメージしていただけたらと思います。
本記事では、その開発フローの中でルールを細かく決めることが重要なのか、果たして必要なのかに関して、私自身の考えをまとめておこうと思います。

# 組織図を明確に示すことは大切なのか
話はずれますが、みなさんはチームの組織図を明確にすることは大切だと思いますか？
私自身もこれまで、人の入れ代わりが発生した時に「しっかりと組織図を更新してください」と、マネージャーによく言っていました。それは「大切」だと思っているからです。
しかし、最近読んだ書籍の中で、 **組織図をそのまま受け取ってしまうと、コミュニケーションをきっちりと決められた枠のなかに収めようとする。だが、組織図の線でつながっている人達だけとコミュニケーションするわけではない。** という内容がありました。
組織図の役割は組織の構造を明確に示すことであり、個人やチーム間のコミュニケーションパターンを理解するものとしては役に立たないということです。
図として明確に組織の体制を示すことができる一方で、その枠に囚われてしまい、進行が非効率になり業務に支障が出てしまうという状況が、受け取り方次第では生まれてしまうということに気づきがありました。

![Frame 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521209/fcff7bc5-bbae-b8b5-01a1-cb09aebc0600.png)

# 開発フローの場合はどうなのか
上で記載した組織図の話は、開発においても同じことが言えるのではないかと思っています。
実際に、フローや進め方をとても細かく図に起こし開発を進めているチームで開発スピードが上がらない問題に直面しているプロジェクトを経験したことがあります。
フローを明確にすること自体は、開発を進める上で確実に大切なことだと思います。それがなければ開発が成り立たないのは一目瞭然なのは全員が理解できると思います。
問題なのは、フローを明確にしたことではなくフロー通りに全てを進めようとすることで柔軟性を失ってしまうということです。
 **フローをしっかりと決めつつも、その中でいかに自由度を持って柔軟に動けるか**がとても大切だと思っています。

# 柔軟に対応できる状態をつくるために必要なこと
「いかに自由度を持って柔軟に動けるか」という状態をつくることはとても難易度が高いものだと思います。なぜなら、その状況を作るためにはメンバー自身が置かれている状況に応じて、どのような動き方をするのが最適なのか、どのような動きをしたら今以上に効率がよいのかに気づく必要があるからです。
なので、私自身が重要だと感じている事としては、フローを作る以前にそのような状態を目指したチームを作ることだと思っています。
- 自由度を持って行動できる雰囲気づくり
    - なぜ自由度もをって行動してほしいのか、なぜそれが重要なのか
    - 理想としては、そのような行動をすることが当たり前の状態
- あくまでもフローはパターンの一つでしかないということ
    - そのフローに固執してほしくない
    - 状況に応じて適切に各自が判断してほしい
- 最終的にどういう状態をチームとして目指したいのか

が重要だと考えています。つまり、その状態を作るのはディレクター・マネージャー・リーダーの役割だと思いますし日々もコミュニケーションが非常に重要だと思っています。

# おわりに
今回の記事で書かせていただいた、「柔軟に動けるチーム」という部分に対しては、当たり前のことを言っていると思う人が多いとは思います。しかし、最近ではゲーム開発において人数の規模が大きくなり開発期間も長期間になっているということもあり、よりマネジメント職の役割は重要になっていると感じています。私自身も良いチーム状態を作るためにしっかりとマネジメントを意識してチーム作りに取り組んでいけたらと思っております。
FlutterとFirebaseの連携でUnformatted Errorが出るときの解決策

最近Flutterをはじめてみました。
FlutterでよくあるのがFirebaseとの連携だと思うのですが、早速初期段階の連携で失敗したので、自分の環境での解決策を書いておきます。

```
firebase FormatException: Unexpected character
```

Firebase CLIをインストールし、flutterのアプリケーションがあるディレクトリで
```
flutterfire configure
```
したところ、このエラーが出ました。

また、FlutterをVSCodeで開いて同じコマンドをTerminalから試しましたが、作成してあるはずのProjectが見つかりませんでした。

```
i Found 0 Firebase projects.
```

前段階として、
①Firebase CLIのインストールおよびlogin
②`dart pub global activate flutterfire_cli`でdartのimport追加
③環境変数にAppDataの場所を追加
④`npm install -g firebase-tools`を叩く
が完了した状態です。（順番は忘れた）

が、このエラーが出てしまい、dart pubをdeactivateしてからactivateしてみたり、firebaseにログアウト、ログインしなおしたり色々試したのですが上手くいかず。

そして、ふとNode.jsのバージョンを最新版にインストールし直してから、`npm install -g firebase-tools`を再度叩いてインストールし直したところ、上手くいきました！

どうもNode.jsのバージョンが古かったから、firebase-toolsのバージョンも低いものがインストールされてしまっていたようです。

stackoverflowや日本語記事をいくつか読みましたが全く解決策が分からなかったので、同じように解決しない方がいれば試してみてもらえればと思います！
【AWS】ELB

# ロードバランサ
あるWebサービスが複数のWebサーバやアプリケーションサーバで構成されている時，リクエスト要求の負荷を分散させること。処理速度の向上・高可用性と耐障害性が見込まれる

# ELB(Elastic Load Balancing)
AWSが提供している完全マネージドなロードバランシングサービス。同じ構成のEC2インスタンスを別々のAZに配置することで負荷分散できる。
複数のAZにまたがりシステムを構築することで，AZ障害が発生した場合もシステムを稼働することができる。

1台のEC2がダウンしてもロードバランサは自動的に他のEC2にトラフィックを振り分けエンドユーザはサイトへ問題なくアクセスできる。

## 証明書アタッチ
ELBに証明書をアタッチすることで通信の暗号化/複号も行う。これをSSLターミネーションという。証明書はACM(AWS Certificate Manager)で作成可能。

## 外部と内部
ELBには外部向け(External)と内部向け(Internal)がある。どちらもプライベートIPアドレスを通じてターゲットと通信するので，外部向けのWebサーバであってもパブリックIPアドレスを待つ必要はない。

クライアント側のフロントエンド接続とサーバ側のバックエンド接続のコネクションを維持する。アイドルタイムの設定が60秒で設定されており，60秒間通信が無ければELBはコネクションを閉じる。

## ヘルスチェック
ロードバランシング先となるターゲットに対してリクエストを送信して**死活監視**を行う。
ELBが一定の感覚でEC2にリクエストを送信し，チェックの結果正常な状態のEC2のみにリクエストを送信する。
プロトコル，ポート，パスを指定してヘルスチェックができる。
デフォルトだと30秒間隔で80ポートで/index.htmlへアクセスし，2回連続でHTTPコードが200以外のレスポンスが応答したら異常。

# ELBのタイプ
## ALB(Application Load Balancer)
リバースプロキシ型のロードバランシングサービス。
HTTP,HTTPSプロトコルの7層(アプリケーション層)で負荷分散するロードバランサでWebアプリケーションでよく使われる。**リスナー**と呼ばれるコンポーネントを作成し，使用するプロトコルとポートを設定してルーティングルールを設定する。

例えばパス単位で**ターゲットグループ**(AZをまたいでインスタンスやコンテナをまとめた仮想的なグループ)を振り分け指定できる。

またAWS CognitoやOIDC IDプロバイダと連携するユーザ認証をサポート。認証が成功すると，ALBによってアクセストークンなどがHTTPヘッダに付与されてリクエスト転送される。

## NLB(Network Load Balancer)
TCPやUDPの4層(トランスポート層)で動作。
ALBのようにリスナーやロードバランスされる対象をターゲットグループとして設定。静的なIPアドレスを見るので，ALBのような細かい振り分けはできないが，数百万/秒のリクエストを処理できる。

# CLB(Classic Load Balancer)
ALBとNLBがリリースされる前のロードバランサ。現在使用は推奨されていない。

:::note info
**リスナー**
トラフィックを受け付けるポートとプロトコルを設定。トラフィックをターゲットグループへルーティングする。
:::

:::note info
**ルール**
ターゲットグループ(トラフィックの送信先)，条件，優先順位を指定したもの。条件に合致した場合，設定したアクションが実行される。
:::

:::note info
**ターゲットグループ**
トラフィックを流す対象(EC2,Lambda,プライベートIPアドレス)。
:::

# 利用料金
「新規接続数」「アクティブ接続数」などをもとに算定する指標である**LCU**(LoadBalancer Capacity Unit)が影響

# 参考
https://www.youtube.com/watch?v=reJ75v5KPBU&list=PLPzcoMdqG5noLR7rAc552mvPADUmmdSt1&index=4
AWSの基本・仕組み・重要用語が全部わかる教科書
Android TVの実機デバイスを安定してデバッグする

# 概要
この記事はFire TV・Android TVなどのAndorid製テレビデバイスの実機デバッグ方法や注意点についてまとめたものです

# デバッグ方法
デバッグにはPCに直接デバイスを繋げてデバッグする方法と、ネットワークを使用してデバッグする方法の2つあります。
理由は後述しますが、個人的にはネットワーク接続でのデバッグを推奨するので今回はその方法でやっていきます

## Fire TV系の場合
### 使用する端末
Fire TV Stick 4K Max
### デバッグ方法
#### 1. 開発者オプションの有効化
設定→マイFire TV→バージョン情報→デバイス名（今回は Fire TV Stick 4K Max） を開発者オプションが有効になるまで複数回クリックします
#### 2. ADBデバッグの有効化
設定→マイFire TV→開発者オプション→ADBデバッグ をクリックしてADBデバッグを有効化します
#### 3. IPアドレスの確認（同じネットワークに繋がっている必要があります）
設定→マイFire TV→バージョン情報→ネットワーク から接続しているネットワークのIPアドレスを特定します

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/e1eab4ac-608d-56ef-1099-385053531d0f.png" width="700" />

#### 4. adbコマンドで接続
[こちらをクリック](https://qiita.com/momomomo111/items/736da119af3c028a0dab#4-adb%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E6%8E%A5%E7%B6%9A-1)

## Google TV系の場合
### 今回使用する端末
Chromecast with Google TV（4Kモデル）OSバージョン：12
### デバッグ方法
#### 1. 開発者オプションの有効化
設定→システム→デバイス情報→Android TVのOSビルド を開発者オプションが有効になるまで複数回クリックします
#### 2. USBデバッグの有効化
設定→システム→開発者オプション→USBデバッグ をクリックしてUSBデバッグを有効化します（USBなどの有線接続をしていなくても有効にしないとデバッグ出来ません）
#### 3. IPアドレスの確認（同じネットワークに繋がっている必要があります）
設定→ネットワークとインターネット から接続しているネットワークのIPアドレスを特定します
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/3ce6479c-9616-e4d7-225a-bf5e5a3ba378.png" width="700" />

### ここから両デバイス共通
#### 4. adbコマンドで接続
デバッグするPCで以下のコマンドを打つ（Android Studioがインストールされている前提）
```
$ adb connect <接続しているIPアドレス>
```
`connected to <接続しているIPアドレス>:5555`と表示されたら接続成功です。
#### 5. 接続確認
下記のようなコマンドでadbが認識するデバイスを確認するかAndroid Studioを開いて`Running devices`を確認していただけると表示されると思います
- adbコマンドで確認
```
$ adb devices

List of devices attached
192.168.2.51:5555	device
```
- Android Studioで確認
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/1679f15f-988d-4213-b71f-047eb6090013.png" width="700" />

## ネットワークを使用するデバッグを推奨する理由
### 電力不足によるデバイスへのパフォーマンスなどの影響
USBデバッグの場合、使用しているPCによってはUSBの給電不足が起こり、デバイスのパフォーマンスが悪くなる場合があります。USBデバッグをしている際に下記のような表示が出てきたらネットワークデバイスに切り替えることをおすすめします

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/c8c16c2f-991c-9087-1232-b734acac0027.png" width="700" />

## モニターに接続せずに表示させる
Android TVのデバイスの場合、HDMIに繋ぐことで表示されている内容を確認できるのですが以下の方法を使えばHDMIに接続せずともデバイスでの表示内容を確認できます

### scrcpy
https://github.com/Genymobile/scrcpy

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/74203833-2ce6-0ae9-d50d-ceba9b9ce42b.png" width="700" />

PC上にミラーリングすることができるアプリです
他にadbに接続されているデバイスがない場合は`$ scrcpy`のコマンドだけで簡単にミラーリングできます

呼び名は「スクリーンコピー」らしい
>pronounced "screen copy"

### ビデオキャプチャーカード
ビデオキャプチャーカードを使用することでHDMIをUSB Type-Cなどに変換することができます。変換してPCに接続したら`QuickTime Player`などで開いて表示させることができます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479939/ec3ac770-b4fb-acb9-d61a-4db36c22706f.png" width="700" />

## 参考
- [Android TV と Google Cast](https://developers.google.com/cast/docs/android_tv_receiver/debugging?hl=ja)
- [ADBを使用してFire TVに接続する方法](https://developer.amazon.com/ja/docs/fire-tv/connecting-adb-to-device.html)
【GraphQL】Apolloって何? 

	
この記事は、[Qiita株式会社のカレンダー | Advent Calendar 2023 - Qiita](https://qiita.com/advent-calendar/2023/qiita-inc)の7日目の記事です。

https://qiita.com/advent-calendar/2023/qiita-inc

---

## はじめに
今回はGraphQLの`Apollo`について解説していきます。

https://qiita.com/kim_t0814/items/c6ef7e3c668007f920a6

上記の記事にApollo自体は出てきましたが、Apollo自体が何かを
説明していなかったので今回記事にまとめようと思いました。

## Appoloって何？
一言でいうと、**GraphQLのフロントエンド・バックエンドのライブラリ**のことです。

以下公式より図を引用

![スクリーンショット 2023-11-07 16.11.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636995/8dc3be3a-7f55-e07b-efac-4308fbba0c3a.png)

Web・iOS・Android等のクライアントはGraphQLを叩く際も`Apollo`を叩きますし、
サーバー側の場合も`Appolo`にデータを集約し、一元的に管理します。


### Apollo Client
以下公式より引用
> Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. Use it to fetch, cache, and modify application data, all while automatically updating your UI.

**Apollo Client**は、GraphQLサーバーと通信するためのJavaScriptライブラリのことです。
クエリやミューテーションはこちらで定義を行います。

### Apollo Server
以下公式より引用
> Apollo Server is an open-source, spec-compliant GraphQL server that's compatible with any GraphQL client, including Apollo Client. 

**Apollo Server**はクライアントからのGraphQL操作を処理するJSのGraphQLサーバーのことです。
GraphQLのスキーマであったり、リゾルバはここで定義します。

**リゾルバとは?**
公式より 
> A resolver is a function that's responsible for populating the data for a single field in your schema.

簡単にいうと、**スキーマで定義した型に対して実際の値や操作を定義する関数のこと**を指します。

以下が基本的な文法になります・

```graphql
type Query {
  stringDog: String! # 毎回dogを返す
  stringCat: String! # 毎回catを返す
}
```

上記の型定義を次のように、定義します。

```ts
const resolvers = {
  Query: { 
    stringDog() {
      return 'dog';
    },
    stringCat() {
      return 'cat' 
    },
  },
};
```

補足しておくと`type Query`の部分と`Query: {`の通りキー名は合わせる必要があり、
typeのフィールド名(キー名)とresolversのフィールド名(キー名)は合わせておく必要があります。

また、`String`と`String!`の差は`null`を許容するかどうかです( **!** はnullを許容しない)。
## おわりに
今回は、Apolloそのものの基本的な説明をさせて頂きました。

**Apollo**は説明した通り、クライアントとサーバー両方の機能を携えているため触るため**フロントエンド・バックエンド**のライブラリと呼ばれています。

また後日、Apolloを用いたサンプルコードを上げようと思います。

今回の記事が皆様の参考になれば幸いです!








## 参考資料
https://www.apollographql.com/docs/apollo-server/v2/

https://www.apollographql.com/docs/react/

https://www.apollographql.com/docs/apollo-server/

https://www.udemy.com/course/graphql-tutorial-with-newsapp-api/
【シェル芸】ImageMagickをワンライナーで遊ぶ

# はじめに
便利な`ImageMagick`をワンライナーで遊ぶ方法を簡単に紹介します。

# ImageMagickのインストール
下記のコマンドでインストールできます。
```sh
sudo apt install imagemagick
```

# ImageMagickワンライナー
たとえば下記のコマンドを実行すると、白い背景に黒い円が描かれた画像が表示されます。

```sh
convert -size 500x500 xc:white PNG:- | convert - -draw 'circle 250,250 200,200' - | display
```

出力画像↓

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3031721/f0b55390-d8e9-3ca4-f129-2df699f07fa6.png)

# convertコマンドの説明
- `-size 500x500`で作成する画像のサイズを指定
- `xc:white`で画像の背景色を指定
- `PNG:`でフォーマットを指定
- 最後の`-`で画像を標準出力
- `-draw 'circle 250,250 200,200'`で円を描画
- `display`コマンドで画像を表示

# おわりに
`ImageMagick`はとても便利で、いつもお世話になっています。これからもたくさん遊んでいきたいと思います。
【AWS】EBS

# EBS(Elastic Block Store)とは
EC2向けにブロックストレージを提供するサービス。作成したEBSボリュームの容量と種類に応じて利用料金が発生する。

同じAZにあるEC2にアタッチして使用する。

複数のEC2から1つのEBSにはアタッチできず，ボリュームタイプに応じてIOPSが異なる。
また，1つのEC2に対して複数のEBSがアタッチできる**マルチアタッチ機能**が存在する。

# EBSボリュームタイプ
## SSDタイプ　
料金が高いけど高速
| ボリューム | 説明 |
| ---- | ---- |
| 汎用SSD | デフォルトのボリューム。OS起動用ディスクや開発テスト環境に使用 |
| プロビジョンドIOPS SSD | 必要なIPOS(1秒当たりに処理可能な読みこみ/書き込みのアクセス数)を指定|

## HDDタイプ　
料金が安いけど低速
| ボリューム | 説明 |
| ---- | ---- |
| スループット最適化HDD | 高いスループットを実現 |
| Cold HDD | アーカイブなど利用頻度の低い大量データの格納向け |

:::note info
**スループット**
コンピュータやネットワーク機器が単位時間あたりに処理できるデータ量
:::

# バックアップ
## スナップショット
EBSからスナップショットを取得して，S3に保存(AWSの保管領域なので見えない)
EBSボリュームのバックアップは**増分バックアップ**で保存(差分だけバックアップ)

## AMI
EC2をAMIとして丸ごとバックアップする。複数のEBSをまとめてバックアップするのに便利。
AMIを起動する際にどのスナップショットを起動するのか(**ブロックデバイスマッピング**)情報を持っている

# 参考
https://it-trend.jp/words/throughput
https://www.youtube.com/watch?v=fsGBnzvKDQM
AWSの基本・仕組み・重要用語が全部わかる教科書
【AWS】EC2

# EC2(Elastic Compute Cloud)
仮想サーバを構築できるサービス。配置する仮想サーバを**インスタンス**と呼び，CPUやメモリ，ストレージといったリソースのキャパシティを定義したものを**インスタンスタイプ**と呼ぶ。
アクセス制御には**セキュリティグループ**という仮想ファイアウォールを使用

仮想サーバとEC2の対応は以下の通りである。
| 仮想サーバ | EC2 |
| ---- | ---- |
| OS | AMI(Amazon Machine Image)  |
| CPUとメモリ | インスタンスタイプ |
| SSD | EBS(Amazon Elastic Block Store) |
| NIC(Network Interface Card) | ENI(Elastic Network Interface) |

# メリット
* 様々なインスタンスタイプがある
目的に応じたインスタンスを選ぶことができる

* 俊敏性
サーバの構築が短時間で完了する

* サイジング
必要な時にリソースのスペックを変更できる。

* 料金モデルの柔軟性
目的や予算に応じた料金モデルを選択できる。

# AMI(Amazon Machine Image)
インスタンスの作成に必要な情報であり，EC2作成時に使用するAMIを指定する。
AWSが提供する**Amazon Linux**，**Windows Server**，**Linuxディストリビューション**などがラインナップ。ソフトウェア(Wordpress)などが搭載されているAMIもある。

# インスタンスタイプ
例　M5a.24xlarge
M⇒ファミリー名
数字⇒世代番号　最新の世代を使うようにする
a⇒オプション
24xlarge⇒インスタンスのサイズ

| インスタンスファミリー | 説明 |
| ---- | ---- |
| T | 小さなアプリや小規模なデータベース，開発環境用サーバなど。テスト向き |
| M | バランスがとれている汎用タイプ |
| C | CPUスペックが高い。処理の多いウェブサーバや機械学習向け |
| R | メモリ最適化。大容量のメモリを必要とするハイパフォーマンスのデータベースなどに使用 |
| G | GPU性能が付いている。高速コンピューティング最適化 |
| I | ストレージ最適化。I/Oパフォーマンスが高い |

# 料金体系
## オンデマンドインスタンス
インスタンスを利用した時間分の料金が発生する従量課金のオプション。

## リザーブドインスタンス
事前に1年または3年の利用を予約して，一部または全部前払いすることで料金がディスカウントされるオプション。

## スポットインスタンス
インスタンス起動時にAWS上で使用していないインスタンスを入札して利用することで，ディスカウントされるオプション。
デメリットとして
入札価格<インスタンス価格となった場合，インスタンスの利用が中断される可能性がある。

# 参考
https://www.youtube.com/watch?v=DcLvwNcFHJU&list=PLPzcoMdqG5noLR7rAc552mvPADUmmdSt1&index=1
https://www.youtube.com/watch?v=7MOrwgedM-I
AWSの基本・仕組み・重要用語が全部わかる教科書
【AWS】スケーラビリティ

# スケーラビリティとは
運用中のシステムの拡張性を示す。
水平スケーラビリティはサーバなどのリソース数を増やしてシステム全体のパフォーマンスを高めること，垂直スケーラビリティは既存リソースの性能を向上させることでシステムのパフォーマンスを高めることを言う。

# 水平スケーラビリティ
## 実施例
* オートスケーリング
アプリケーションの負荷に合わせて自動的にインスタンスを起動または終了させる。

* ロードバランシング
複数の機器で負荷が均等になるよう分散させることで，負荷も分散あｓる。


## メリット
* リソースを柔軟に追加できる
* スペック変更時にシステムを停止する必要がない
* リソースを増やすことで，高い可用性と耐障害性が得られる

:::note info
**可用性**
システムが継続して稼働できる能力
:::

## デメリット
* 管理するリソースの台数が増え，管理が複雑化する
* リソースの増減に伴う運用コストを考慮する必要がある
* データ整合性の確保が課題

# 垂直スケーラビリティ
## 実施例
* インスタンスタイプの変更
インスタンスのタイプを変更することで性能やリソースを向上させる。

## メリット
* 管理するリソースが少ない
* データ整合性を確保しやすい

## デメリット
* スペック変更時にシステムの停止を伴う
* 一つのリソースに障害が発生すると，システム全体に影響を及ぼす可能性がある

# 参考
https://www.ntt.com/bizon/glossary/j-k/availability.html
https://www.youtube.com/watch?v=01vFq4vGmZg&list=PLPzcoMdqG5npvpXicqEw1tjMjC725bR6L&index=5
AWSの基本・仕組み・重要用語が全部わかる教科書
【React】state変数がオブジェクトのときにやらかしがちなこと

## はじめに

[Reactの公式チュートリアル](https://ja.react.dev/learn/updating-objects-in-state)をやっていてハマったところを解説します。

## 問題

state変数にオブジェクトが入っているとします。

```react
const [position, setPosition] = useState({ x: 0, y: 0 });
```

`position`を更新したいとき、次のように書いてはいけません。

```react
position.x = 1;
position.y = 2;
```

以下もダメです。

```react
position.x = 1;
position.y = 2;
setPosition(position);
```

理由を順番に説明していきます。

## state変数の変更はset関数を使いましょう

まず1つ目のコードがダメな理由を説明します。

```react
position.x = 1;
position.y = 2;
```

前提として、**state変数が数字だろうと文字列だろうオブジェクトだろうと、set関数以外で変更してはいけません**。

ただ、数字や文字列の場合はプリミティブな値なので、それ自体を変化させることは、やろうとしてもできません。

え？ こうすれば数字でも変えられるじゃん？ と最初は思いましたが、、

```react
const [x, setX] = useState(0);
setX(5);
```

このコードは`x`というstate変数の値を0から5に変更しているだけで、**0という値自体を5に変えているわけではない**です。なので問題ありません。

しかしながら、state変数の値がオブジェクトの場合は、**オブジェクト自体の値を書き換えることができてしまいます**[^1]。

例えば、以下では`position`というstate変数自体を変化させています。

```react
const [position, setPosition] = useState({ x: 0, y: 0 });
position.x = 1;
position.y = 2;
```

これの何が問題かというと、**Reactがこの変更を検知できない**ことです。

内部的には`position`の値は確かに変更されていますが、**Reactがそれを検知できないため再レンダリングされず**、画面上なんの変更もされていないように見えてしまいます。

### 解決策

set関数を使用すればReactに変更を検知してもらえます。

新しいオブジェクト`{ x: 1, y: 2 }`を作成し、`setPosition`に渡せば、無事に再レンダリングされます。

```react
setPosition({ x: 1, y: 2 });
```

## 疑問

ここで疑問に思いました。

わざわざ新しいオブジェクトなんて作らなくても、set関数に`position`を渡せばいいじゃないかと。

冒頭に書いた2つ目のコードです。

```react
position.x = 1;
position.y = 2;
setPosition(position);
```

しかしながら、これでも画面上`position`の値は更新されません。

**set関数は、state変数の値が変化したときだけ実行されるから**です。

今回の場合、オブジェクトである`position`の`x`プロパティの値が変わっただけなので、`position`自体の変更とはみなされず、`setPosition`は実行されません。

### 解決策

なので、やっぱり新しいオブジェクトを作って、set関数に渡す必要があります。

```react
setPosition({ x: 1, y: 2 });
```

## 終わりに

2つ目のコードがなぜ上手くいかないのかがわからなくて調べて、結果的に理解が深まったので良かったです。


## 参考

https://ja.react.dev/learn/updating-objects-in-state

https://ja.react.dev/reference/react/useState#ive-updated-the-state-but-the-screen-doesnt-update

[^1]:今回は扱いませんでしたが、配列もオブジェクトと同じくミュータブルなので同じ問題が発生します
Android 13（API レベル 33）対応

「com.google.android.gms.permission.AD_ID」を利用してないのに、検知されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3324548/1ce818d6-72b1-489a-01e5-5b4a290a7a67.png)

     <meta-data
            android:name="com.google.firebase.messaging.default_notification_icon"
            android:resource="@mipmap/ic_launcher_round" />
            
を追加して解消できました

参考記事
https://qiita.com/Nkzn/items/326ad03e358b5d3fbafc
V7R5新機能（％LEFT 組込み関数

V7R5 TR3で提供された `%LEFT` を使ってみた。`%RIGHT` も同時にリリースされているが、右になるだけなので 検証は `%LEFT` のみ。

 - [IBM i 7.5 - TR3 Enhancements](https://www.ibm.com/support/pages/ibm-i-75-tr3-enhancements)
 - [7.5以降の新機能 - %LEFT および %RIGHT 組み込み関数](https://www.ibm.com/docs/ja/i/7.5?topic=new-whats-since-75#rpgrelv7r5post)

- [サンプルコード](https://github.com/ushiday/qiita-rpgle/blob/main/QRPGSRC/Q231219R1.RPGLE)

## コードサンプル抜粋

```RPGLE
//   D*-********************************************************************
//   D*-* 変数定義                                                      **
//   D*-********************************************************************
DCL-S  WTIMESTAMP    TIMESTAMP                ;  //タイムスタンプ
DCL-S  WDATE8        ZONED(8:0)               ;  //日付
DCL-S  WTIME6        ZONED(6:0)               ;  //時刻

DCL-S  W#STR11       CHAR(32)                 ;  //文字列（固定長
DCL-S  W#STR12       VARCHAR(32)              ;  //文字列（可変長

DCL-S  W#STR21       VARCHAR(32) CCSID(*UTF8) ;  //文字列（ＵＴＦ－８可変長
DCL-S  W#STR22       VARCHAR(32) CCSID(*UTF8) ;  //文字列（ＵＴＦ－８可変長
//   C*-********************************************************************
//   C*-* メインルーチン                                                **
//   C*-********************************************************************

//初期処理
EXSR      @INZ                         ;

//左より取得
W#STR11 = 'ABCDEFGHIJKL'               ;
W#STR12 = %LEFT(W#STR11  : 08 )        ;
DSPLY W#STR12                          ;


W#STR11 = '牛田　吉樹'               ;
W#STR12 = %LEFT(W#STR11  : 08 )        ;
DSPLY W#STR12                          ;


W#STR21 = '牛田　吉樹'               ;
W#STR22 = %LEFT(W#STR21  : 08 )        ;
DSPLY W#STR22                          ;

```

## 結果、感想

留意点は、バイト数指定のため、**UTF-8** の文字列は取得箇所が異なる点。
あとこの手の文字列操作系関数は、SBCS圏内の方々には重宝するのだろうが、DBCS圏内の我々は、結局 `x0e,x0f` の調整が必要となり、皆さん自作サブルーチンを作る状況は変わらないと思われます。サンプルコードでも想定どおり千切れています。
SBCSと判っているケースでは、コードの見通しが良いかも知れません。文字列に関しては、DBCS圏内の永遠のテーマに思えてしまいますね。

![2023-12-05_210519.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/5b25614a-6861-2304-7e95-fd805aae5b2a.png)
データテーブルの行数(.Rows.Count)を調べるログを入れていて助かった事例

## 1,はじめに
この内容は下記の記事を対応後、発生したエラーが**予期しない終了コードでジョブが停止されました: 0xE0434352**でした。

https://qiita.com/thxUVER2012/items/98976351694f5cb0a5ef

下記の企画で連続で記事を投稿しています！！
本日は連続投稿3日目です。

https://t.co/56WibbNlvz

## 2,問題の切り分け
調べてみるといろんな場合でエラーが出ることがわかり、現状のロボットの動きを見て、下記の方法で問題の切り分けを行いました。

:::note info
(1)新規シートに書き込むか？
(2)新しいExcelに書き込むか？
:::

:::note warn
(1),(2)ともに同じエラーになり、インプットとなるCSVファイルに問題があるとわかりました。
:::

:::note alert
データテーブルの行数をログで出力していたので、何か見落としがないか確認したところ、
CSVファイルの行数が1万5千行あり、本当か！？と思いました。
:::

CSVを確認すると5千行しかなかったです。

:::note info
書き込み先のExcelの行数を超えていたため、エラーになったかと思います。
:::

## 3,対応方法
原因さえわかれば、あとはシンプルでした！

:::note info
データテーブルをフィルターを使用して、空白を削除しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3327229/76d09588-22bd-5e47-19ef-6840c77b9559.png)
:::

## 4,おわりに
データテーブル化した直後にその行数をログで出力することが改めて大事だと認識しました！
これでエラーがなくなり、終わったと思いきや、、、。
Excel関数を使用しているため、数値でExcelに書き込んで欲しいんですが、文列かつエラーマークが出力されました。
※文列かつエラーマークの詳細は下記を確認してください。

https://www.jpita.or.jp/simin/index.php?excelziten417

この解決方法は後日載せます！！
今日から始める３年日記

年末になり、書店に手帳や日記帳が沢山並んでいます。
３年日記でも初めてみようかと思い、12月始まりのものが無いかな？と探したのだけど見当たらない。
よく考えたら、12月始まりの３年日記って作りにくいのですね。
1月まで待つと熱が冷めてしまいそうなので、Obsidianのデイリーノートを３年日記にしてみました。
これで、今日から３年日記を始められます。

今日から始められるけど、来年まで続くかな？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269407/0b711b8b-e811-88df-394d-ad8d38cca66f.png)

### 使用するプラグイン
- Templater

### 設定
- デイリーノートのテンプレートを作成
```
### 日記
ここに日記を書く
^diary

### 3年日記
- １年前：　[[<% tp.date.now("YYYY-MM-DD", "P-1Y") %>]]
	![[<% tp.date.now("YYYY-MM-DD", "P-1Y") %>#^diary]]
- 2年前：　[[<% tp.date.now("YYYY-MM-DD", "P-2Y") %>]]
	![[<% tp.date.now("YYYY-MM-DD", "P-2Y") %>#^diary]]
- 3年前：　[[<% tp.date.now("YYYY-MM-DD", "P-3Y") %>]]
	![[<% tp.date.now("YYYY-MM-DD", "P-3Y") %>#^diary]]
```
- デイリーノートの設定画面で テンプレートファイルの場所 を設定する
- Templater の設定画面で "Trigger Templater on new file creation" を有効にする

以上