OmniAICreator/Qiita-1.07M huggingface dataset:
はじめてのDockerfile

# はじめに

前回までの記事ではDocker Hubにアップされているイメージをそのまま使いましたが、今回はDockerfileを使ってカスタマイズしたイメージを利用する方法を備忘録としてまとめてみました。

* [Windows上にDocker環境を構築する](https://qiita.com/nkojima/items/89c2f0130c00528d8956)
* [Dockerで任意のフォルダをマウントする](https://qiita.com/nkojima/items/86c4d0e70995d7cd8254)

# やりたい事

* AlmaLinux9のイメージをベースにして、Apacheの入ったコンテナを作る。
* 任意のフォルダをマウントして、Apache上でサンプルのHTMLを動作させる。

# 作成したDockerfile

* OSはAlmaLinux 9を使うため`almalinux:9`と書いていますが、AlmaLinuxの最新版（latest）を使う場合は`almalinux`と指定するだけで良いそうです。
  * 実際の開発環境だと、しっかりバージョン指定した方が無難だと思います。
* docker run時に実行する`CMD`については、以下のDockerfileでは推奨されている「exec形式」を使っています。
  * `CMD /usr/sbin/httpd -D FOREGROUND`のような「シェル形式」は非推奨のようです。
* EXPOSEで80番ポートを明示的に開放していますが、これはもしかすると不要かもしれません。

```dockerfile:Dockerfile
# OSの名前とバージョン
FROM almalinux:9

# 作成するイメージに付けるラベル情報
LABEL maintainter="nkojima" \
      version="1.0"

# RUN, CMD, ENTRYPOINT, docker run, execで実行するコンテナプロセスのユーザーを指定する
USER root

# システム全体を更新
RUN dnf update -y

# httpdをインストールして起動
# コンテナは起動後、実行しているプロセスがなかったら停止してしまうためFOREGROUNDで起動する
RUN dnf install -y httpd
RUN systemctl enable httpd
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]

# 80番ポートを開放する
EXPOSE 80
```

# イメージの作成（構築）

* Dockerfileのあるフォルダに移動した後、以下のコマンドを実行してDockerfileでカスタマイズしたイメージを作成します。
* `-t`オプションを使い、作成したイメージの名前を `alma9_httpd`としました。

```powershell:PowerShell
PS> docker build . -t alma9_httpd
```

# コンテナの作成と実行

* [前回の記事](https://qiita.com/nkojima/items/86c4d0e70995d7cd8254)で書いた方法で任意のフォルダをマウントした上で、コンテナを作成・実行します。
  * 前回と違いマウント先が`target=/var/www/html`となっていますが、これはAlmaLinux上のApacheのDocumentRootが`/var/www/html`となっているためです。

```powershell:PowerShell
PS> docker run --name alma9_test -p 10088:80 -it --mount type=bind,source=D:\test,target=/var/www/html alma9_httpd
```

# 参考URL

* [Dockerfileの基本的な書き方](https://alterbo.jp/blog/ryu2-2106/)
* [Dockerfileによるビルド](https://www.tohoho-web.com/docker/dockerfile.html)
20240314~0315の日記 WezTermに背景をつける

二日分だから日記といえるのか微妙なところ

### WezTermの設定する

RushRoyaleのイベントで、みんなで背景画像をラロワのにしよう、というのをやっている。スマホの壁紙でもいいんだけどどうせなら凝ったことをしたい、ということでターミナルの壁紙を変えることにした

Alacrittyのを変えようとおもったが、ない、本当にない、っぽい、、、

ということでWezTermでやることにした。ノーマルのまま使っているのでフォントや色など設定する。まず設定ファイルの場所がわからずあれこれしたが、参考サイトに導かれ、--config-file　で渡すことにした

参考：
* [Weztermをセットアップしたい](https://zenn.dev/ino4x/scraps/787dd3b2136d26)
* https://wezfurlong.org/wezterm/config/files.html

#### やったこと
habamaxというNeovimで使っている色合いを使いたいが、初期セットにはないのであきらめて'Solarized Darcula (Gogh)'を使うことにした、なんとなく似てる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740499/2bdcb393-15a1-ed78-df5c-ff82100e128f.png)

他、フォントを白源35コンソールNF、高さ調整、背景画像、titleバーの削除、nvim透明化、でいまこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740499/c86b2848-183c-c351-a513-515ad7ccd8ec.png)

#### 設定内容

```lua
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
local grey_radial = {
  colors = { 'grey', 'slategrey' },
  orientation = {
    Radial = {cx=0.65, cy=0.65, radius=0.45}
  }
}
local app_path = 'D:\\Users\\(myname)\\scoop\\apps\\wezterm\\current\\'

config = {
  window_decorations = 'RESIZE',

  color_scheme = 'Solarized Darcula (Gogh)',

  font = wezterm.font('HackGen35 Console NF') ,
  font_size = 10.5,
  line_height = 0.9,

  background = {
    {
      source = {
        File = app_path .. 'Spring_post.png',
      },
      attachment = { Parallax = 0.05 }, --"Fixed",
      hsb = { brightness = 0.09, saturation = 0.5 },
      height = 1020,
      width = 650,
    },
    {
      source = {
        File = app_path .. 'Spring_post.png',
      },
      attachment = { Parallax = 0.3 }, --"Fixed",
      hsb = { brightness = 0.07, saturation = 0.2 },
      height = 620,
      width = 325,
      opacity = 0.5
    },
  },
}

return config
```

#### 今後の改善
いずれ画像は別の画像にして、スクロールしたときに奥行きがあるようにしたいと思っている

#### 知ったこと

* nvimの背景透明化、Qiitaかどこかの記事読んでうええ、面倒くさーとおもったけどこのプラグインで一発でした。
[xiyaowong/transparent.nvim: Remove all background colors to make nvim transparent](https://github.com/xiyaowong/transparent.nvim)
* luaでは文字列の連結には..（ピリオド２つ）を使う
nvimのinit.lua書くときはやってなかったかも
【JavaScript】Exponential Backoff And Jitter

## 方法1

```js
// 待機時間を1秒, 2秒, 4秒, 8秒...と増加させる。（最大32秒）
const backoff = Math.min(Math.pow(2, retryCount) * 1000, 32000)
// 待機時間にばらつきを出す
const jitter = Math.random() * 1000  
const jitteredBackoff = backoff + jitter

await new Promise((resolve) => setTimeout(resolve, jitteredBackoff))
```

### 待機時間の例

```console
1回目 1541.7146030710737ms
2回目 2808.2306075308397ms
3回目 4565.012911744703ms
4回目 8919.909323193897ms
5回目 16987.425867053946ms
```

### 参考ページ

https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja

## 方法2

Full Jitter

```js
const backoff = Math.min(Math.pow(2, retryCount) * 1000, 32000)  
const jitteredBackoff = backoff * Math.random()  

await new Promise((resolve) => setTimeout(resolve, jitteredBackoff))
```

### 待機時間の例

```console
1回目 794.2005031744484ms
2回目 1627.3717991131734ms
3回目 780.8109128801161ms
4回目 2029.0619185410499ms
5回目 10193.744317147111ms
```

### 参考ページ

https://aws.typepad.com/sajp/2015/03/backoff.html

## 方法3

Equal Jitter

```js
const backoff = Math.min(Math.pow(2, retryCount) * 1000, 32000) 
const jitteredBackoff = backoff / 2 + Math.random() * backoff

await new Promise((resolve) => setTimeout(resolve, jitteredBackoff))
```

### 待機時間の例

```console
1回目 889.4631476869306ms
2回目 2791.704999468895ms
3回目 3734.710652151566ms
4回目 7685.752867284689ms
5回目 13774.910498958634ms
```

### 参考ページ

https://aws.typepad.com/sajp/2015/03/backoff.html
mysqlのユーザーに権限を与える

# ユーザーの権限を確認する
```
SHOW GRANTS FOR 'jeffrey'@'localhost';
```
### 出典
https://dev.mysql.com/doc/refman/8.3/en/show-grants.html

アカウントの権限を確認するためにはshow grantsを使用します。
### 出典
https://www.shoeisha.co.jp/book/detail/9784798161488

https://qiita.com/shuntaro_tamura/items/2fb114b8c5d1384648aa

### 気づき
他のqiitaの記事にも書いてあったから本当だろう。


USAGEは接続できるだけの権限です。接続してもデータベースやテーブルに対して操作は何もできません。
アカウントに権限を付与するためには前述のようにGRANTを使用し、権限を剥奪するにはREVOKEを使用します。
...
```
GRANT USAGE ON *.* TO 'jeffrey'@'localhost'
```
グローバル（G)
```GRANT USAGE ON *.*```を指定したときに適用されるレベルです。mysql全体に影響します。

### 出典
https://www.shoeisha.co.jp/book/detail/9784798161488

### 気づき
USAGEはとりあえず何もできないためにこのユーザーではデータベースに接続できなかったのか。
なのでこのユーザーに権限を与えることがこれからの課題か。

# ユーザーに権限を与える
```js
GRANT ALL ON DB名.* TO 'ユーザー名'@'localhost';
```
### GRANT ... ON DB.*
指定したデータベース配下だけに影響します。

### ALL
全ての機能

### 気づき
とりあえず全ての機能をこのユーザーに適用させた。
なので与える権限は考えてください。

# 出典
https://www.shoeisha.co.jp/book/detail/9784798161488
異なるScalaバージョンのアプリがあるプロジェクトにおけるsbtのクロスビルドについて

sbtは、異なるScalaバージョンであってもクロスビルドの設定により、一度にビルドできます。ただ、シチュエーションによっては難しいようです。

# 背景

最初にアプリが1つありました。古くから運用されているプロジェクトで、そうですね...とにかく古いScalaを使っていて、仮にバージョンを2.11としましょうか。

```plantuml
artifact "app@scala2.11\n(root)"
```

流石に令和になって5年ほど経ったので、そろそろScalaのバージョンもあげたくなってきました。最近はScalaにもLTSの概念が導入されたので、LTSである3.3のバージョンを作りました。

```plantuml
artifact "app@scala2.11\n(root)"
artifact "app2@scala3.3"
```

appは規模がでかいので、一気にapp2にはせずに、少しずつ機能を移していこうと思います。切り出す機能はドメインオブジェクトを使っていたので、appとapp2の両方で使えるように、共通コード置き場を用意しました。ここに、ドメインオブジェクトがどんどん増えていく予定です。

```plantuml
artifact "app@2.11\n(root)" as p1
artifact "app2@3.3" as p2
artifact "domain@2.11\ndomain@3.3" as d

d <-- p1
d <-- p2
```

# 設定ファイル

```properties:project/build.properties
sbt.version=1.9.9
```

```scala:build.sbt
ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.11.12"

lazy val domain = project
  .settings(
    crossScalaVersions := Seq("2.11.12", "3.3.3")
  )

lazy val root = (project in file("."))
  .dependsOn(domain)
  .settings(
    scalaVersion := "2.11.12"
  )

lazy val app2 = project
  .dependsOn(domain)
  .settings(
    scalaVersion := "3.3.3"
  )
```

これをビルドする場合、クロスビルドが必須になります。

```shell
sbt +compile
```

```shell
sbt +app2/compile
```

どういうことかというと、`ThisBuild/scalaVersion`が2.11.12なので、Scala3.3.3が存在しないものとされ、`sbt compile`だと`domain`のScala3.3.3バージョンが存在せず失敗してしまいます。

# IntelliJ IDEAの場合

IntelliJ IDEAはsbtのプロジェクトを認識してプロジェクト構成をセットアップしてくれるのですが、それがうまくいきません。以下の魔法を唱えると、うまくいきます。

```shell
sbt +updateClassifiers +app2/updateClassifiers
```

`sbt clean`しても消えませんが、消えてしまうこともあるので、`clean`コマンドをこの2つも呼び出すようにオーバーライドしてしまっても良いかもしれません。

# まとめ

これらは動く組み合わせを探したらこれだったというログで、論理立ててこの設定が良い、というものではありません。もしこの辺の上手い設定や運用方法があれば、コメントお願いします :pray:
MonoBehaviour.OnDestroyについて

有名な話ではあると思いますが時々やらかすことあるので備忘録。

MonoBehaviourは==をオーバーライドしていて、
OnDestroy以降はnullを返す。
OnDestroyが呼ばれてもメモリから消えているわけではない。

まあC#なんだからそりゃそうなんだけれど、
この余計な親切のおかげでメモリリークしやすい。

例えば下記のように二つのMonoBehaviourがあったとして。
```
public class Sub : MonoBehaviour
{
    void Update()
    {
        if (Input.GetMouseDown(0)) {
            Destroy(this);
        }
    }
}

public class Main : MonoBehaviour
{
    Sub ReferenceToSub;

    void Start()
    {
        ReferenceToSub = gameObject.AddComponent<Sub>;
    }

    void Update()
    {
        if (ReferenceToSub == null) {
            Debug.Log("SubはすでにDestroyされている。");
            return;
        }
    }
}
```

マウスクリックすることでReferenceToSubはnullを返すようになる。
しかしMainが死ぬまでSubはメモリに残り続ける。

これを防ぐには例えば下記のように明示的にnullを入れてやる。
```
    void Update()
    {
        if (ReferenceToSub == null) {
            Debug.Log("SubはすでにDestroyされている。");
            ReferenceToSub = null;
            return;
        }
    }

```


あと、下記のようにインターフェースを使った場合。
```
public interface ITest
{
    void Test();
}

public class Sub : MonoBehaviour, ITest
{
    void Update()
    {
        if (Input.GetMouseDown(0)) {
            Destroy(this);
        }
    }

    public void Test()
    {
    }
}

public class Main : MonoBehaviour
{
    ITest ReferenceToSub;

    void Start()
    {
        ReferenceToSub = gameObject.AddComponent<Sub>;
    }

    void Update()
    {
        if (ReferenceToSub == null) {
            Debug.Log("SubはすでにOnDestroyされている。");
            return;
        }
    }
}
```
これはSub.OnDestroyが呼ばれた後も
ReferenceToSubはnullを返さない模様。

なので保持するインターフェースの実態が
MonoBehaviourである可能性があるなら、
そいつがOnDestroyされたことは別の手段で知る必要がある。

インターフェースはGC.Allocを回避しつつ
コールバック処理できるありがたい存在なんだけど、
こういう罠もある。


最後に、これも有名な話ですが
OnDestroyが呼ばれた後、
ReferenceToSub==nullはtrueなのに
ReferenceToSub?はnullを返さない。
これ何とかしてくれんかなあ。
kubernetesのパッケージレポジトリがいつのまにか削除されてた

## apt updateでコケていた
自宅のubuntuサーバーで久しぶりに `apt update` を実行したところ、kubernetesの該当レポジトリがもうなくなってるよと言われていた。

```
E: The repository 'https://apt.kubernetes.io kubernetes-xenial Release' no longer has a Release file.
```

https://github.com/kubernetes/release/issues/3485
こちらのissueにある通り、 2024-03-04以降削除されているらしい。

## 解決方法

kubernetes公式のブログに対処方が記載されている。
https://kubernetes.io/blog/2023/08/15/pkgs-k8s-io-introduction/#how-to-migrate

以下に対応を抜粋

apt参照のレポジトリ更新
```
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
```

gpg keyのダウンロード
```
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
```

packageのアップデート
```
sudo apt-get update
```

これで正常に更新できるかと思います。
`./gradlew build` で `Value '/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home' given for org.gradle.java.home Gradle property is invalid (Java home supplied is invalid)` が出てエラーになる

# これは何

`./gradlew build` で `Value '/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home' given for org.gradle.java.home Gradle property is invalid (Java home supplied is invalid)` が出てエラーになる

# 環境

macOS Sonoma
IntelliJ

# 結論

`/Users/${user_name}/.gradle` 配下の `gradle.properties`に`org.gradle.java.home` が設定されていた（なぜ）

# 行き着くまでの道のり

1. エラー出る
1. ググる
1. よくある解決策：`JAVA_HOME`の設定など確認する -> ちゃんと設定できてる
1. 次によくある解決策：**プロジェクト配下**の`gradle.properties`の設定を確認する -> プロジェクト配下には`gradle.properties`がない。さらに、プロジェクト配下のどこにも`adoptopenjdk-11.jdk`のキーワードはない
1. ググる。が、有効な解決策が見当たらない
1. 沼る。でも諦めない
1. ひょんなことから[IntelliJのGradle設定](https://pleiades.io/help/idea/gradle-settings.html)に行き着く
1. `Gradle ユーザーホーム`の項目を見つける。`/Users/${user_name}/.gradle`がデフォルトらしい。 -> まさかと思って見にいく。該当のデフォルトディレクトリに`gradle.properties`が存在していて `org.gradle.java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home` の記載あり
1. 該当の行を削除する -> `./gradlew build` 成功

# おわりに

おそらく昔ごにょごにょやってたときに、システムのとこに設定入っちゃったんだろうなあ（それかデフォルトなんかな。まさかな。）。
Qiitaに複数画像を同時にアップロード

```javascript
const image_urls = [
  'https://cors1.deno.dev/https://cdn.qiita.com/assets/public/image-qiitan_for_login_modal-014e085d3e40a240e3fe8d61b70b29a9.png',
  'https://cors1.deno.dev/https://blog.qiita.com/wp-content/uploads/2023/05/45e8009e-2099-0308-3579-5bfe6fcd61d9.png',
  'https://cors1.deno.dev/https://cdn.qiita.com/assets/public/push_notification/image-qiitan-572179a3bbde375850422ea48b2b6272.png',
]
const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));

for await (const url of image_urls) {
  const temp1 = await fetch(url).then(r=>r.blob())
  const file = new File([temp1], Date.now() + '.png', {type: 'image/png'})

  const dataTransfer = new DataTransfer()
  dataTransfer.items.add(file)

  const pasteEvent = new ClipboardEvent('paste', {
    bubbles: true,
    cancelable: true,
    clipboardData: dataTransfer,
  })
  document.querySelector('.cm-content').dispatchEvent(pasteEvent)
  await sleep(500)
}
```

// TODO: <input type=file multiple>によるアップロード実装
【研究紹介】情報処理学会第86回全国大会にて学生奨励賞をいただきました(スライド付き)

2024/3/15~17に行われている(3/15執筆)情報処理学会第86回全国大会にて自分の主著論文に学生奨励賞をいただきました。

深層学習における分布外汎化と不確実性の較正の関連性に注目した研究になります。
以下が発表スライドになります。

<iframe src="https://www.slideshare.net/slideshow/embed_code/key/b0thkYKTDz7VYL?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
QiitaのOGPをキャッシュクリアする

## 結論（伝統的手法）

正確にはキャッシュクリアではないけど、代替策として...

これを

```zsh
https://revisnote.com
```

![スクリーンショット 2024-03-15 21.52.06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267156/680bf4e1-c29e-0641-8847-431410d12363.jpeg)

こうする

```
https://revisnote.com?1710501811980
```

![スクリーンショット 2024-03-15 21.53.01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267156/f1bc1218-1e6b-e275-06f6-c65e1629e793.jpeg)

## 説明

世の中の各種サービスと同様にQiitaもOGPをキャッシュしているみたい。だけど、キャッシュを削除する方法は公式には提供されていなかったはず。

だからキャッシュクリアは諦めて、「元々キャッシュされていたページとは別のページだよ」と誤認させることで、新たにOGP取得させたい。そのために、URLにタイムスタンプのクエリパラメータをつけている。

この「クエリパラメータをつけて強制的にキャッシュを参照させない」という手法は、割と昔からあって、単純かつ強力な方法だから、OGPに限らず他の場面でも見ることがあるかもしれないね。

## 著者プロフィール

faable01です。かつては創作仲間と小説を書いたり、製菓業界で楽しくやっていたはずが、紆余曲折を経て、サーバーレス技術を触るのが好きなITエンジニアになっていました。AWSのIaC兼サーバレス爆速開発ツール **「SST」** が好きです。個人ブログでもたまに記事を書いています。

https://signote.link

それから、業務日報SaaS **「RevisNote」** を運営しています。リッチテキストでの日報と、短文SNS感のある分報を書けるのが特徴で、組織に所属する人数での従量課金制です。アカウント開設後すぐ使えて、無料プランもあるから、気軽にお試しください。

https://revisnote.com?1710501811980
Dockerで任意のフォルダをマウントする

# はじめに

前回の「[Windows上にDocker環境を構築する](https://qiita.com/nkojima/items/89c2f0130c00528d8956)」に続いて、Dockerのコンテナに任意のフォルダをマウントする方法を備忘録としてまとめてみました。

# イメージのダウンロード

* 前回の記事と同じく、`httpd`というイメージを利用します。

```powershell:PowerShell
PS> docker pull httpd
```

# コンテナの作成と実行

* 前回は以下のコマンドを実行しましたが、これにパラメーターを加えて任意のフォルダをマウントします。

```powershell:前回のコマンド
PS> docker run --name httpd_test -p 10088:80 -it httpd
```

* 任意のフォルダをマウントする際は、`--mount type=bind,source={マウント元},target={マウント先}`というオプションを付けます。
  * 今回はホストの`D:\test`フォルダを、コンテナの`/usr/local/apache2/htdocs`にマウントしています。
* なお[Dockerの公式リファレンス](https://docs.docker.jp/storage/bind-mounts.html#v-mount)では、**「新しいユーザは --mount 構文を使うべきです。経験のあるユーザは -v や --volume 構文に慣れているでしょうが、調査によって、より簡単に利用できると分かっている --mount の利用を推奨します。」** と書かれているので、今回はそれに従いました。

```powershell:任意のフォルダをマウントする際のコマンド
PS> docker run --name httpd_test -p 8888:80 -it --mount type=bind,source=D:\test,target=/usr/local/apache2/htdocs httpd
```

# 参考URL

* [Windows上にDocker環境を構築する](https://qiita.com/nkojima/items/89c2f0130c00528d8956)
* [-v と --mount フラグの選択 - バインド マウント(bind mount) の使用](https://docs.docker.jp/storage/bind-mounts.html#v-mount)
ハッカソンに参加する良さについて

# 初めに
こんにちは
@PoPodadaです。
2024年3月8日~2024年3月11日に開催された **関西ビギナーズハッカソンvol.3** に参加しました。
ハッカソンに参加するのは2回目になるのですが、参加する上で学べる事、参加するメリットを備忘録として残しておきたいと思いました。
今回のハッカソンでは嬉しいことに企業賞であるProgate賞を頂くことができたのですが、反省点はかなりありました...
それについて思い出せるようにしたいという面でもこの記事を作成しています。
良さについてわかりやすく読んでもらうために３つ伝えます。

https://kansai-hackathon.com/

## 自己紹介
情報科学部所属の大学２年生(2024年3月時点)
普段はWebアプリ開発についての学習をしている
webアプリ開発をするエンジニアになりたい
ハッカソン２回目の参加

## 関西ビギナーズハッカソンとは

関西ビギナーズハッカソンとは、関西を中心に活動する情報系学生団体のビギナー学生が一同に会し、開発・交流を促進するためのオフライン宿泊型のハッカソンイベントです。

### 刺激を得られる


まず一つに **刺激を得られる** があげられると思います。ハッカソンに参加すると自分と同じような普段からプログラミングを学習している人、アプリ開発を学習している人など自分の似たような学習をしている人と出会うことができます。そういった人に出会うだけでも刺激を得られますし、なんて言ってもオフラインのハッカソンでは、ずっと開発をしている人たちがそこら中にいるわけです。そんな中集中力が切れないわけがありません！みんなどんなものを完成させるんだろうと楽しみになりながら最終日に向けて自分も完成に近づけるべく、開発を続けることができるのです！！
### 開発に集中できる


開発に集中できます！
普段だったらアルバイトだとかほかの用事があるだとか、個人開発だとしても家にいるとほかのことに気を取られて開発に集中できないかもしれません。でも、ハッカソンはやることは最終日に向けて開発をするのみです！！朝から晩まで開発に集中することができます！
### たくさんの人と話せる

ハッカソンにはたくさんの人が来ています！普段Xで見ている人、自分が知っている企業の方、エンジニアとして働いている人...と話すことができます！また、自分がハッカソンで開発したアプリについてもありがたいお言葉を頂けるので、個人開発をしているだけでは気づくことのできないような詰めの甘さに気づかされたりもします！


## まとめ
この記事でまとめたような事以外にもハッカソンに参加する良さはたくさんあります。
受賞を目指すとなるとまだ参加するべきじゃないんじゃないか...と思うかもしれませんが、参加してみるとまた違う感想も生まれるかもしれません。
僕は今回のハッカソンで初めの2日間ログイン機能にてこずっており、ハッカソンに一番必要なコア機能の開発への着手がかなり遅れていました。それは一番の反省ですし、ほかにも反省することは数え切れません。これからも学習したりハッカソンに参加したり、個人開発を繰り返して今回の反省点も改善していきたいです！！

ここまで読んでくださりありがとうございました！！
これからももっとハッカソンに参加します！！！
Windows でコマンドのエイリアスを作る方法 ( Linux の .bash_aliases みたいな感じ)

# 🎯 結論
1. 任意のディレクトリに `.cmd` ファイルを作成する
2. ↑ のディレクトリに PATH を通す

実質、バッチファイルを作って PATH 通して呼び出せるようにしてるだけ。

# 🔍 経緯
.bash_aliases に `ll` というエイリアスを作って `ls -laF` を呼び出す、
ということをやるのがクセになっていて
どうしても毎回 `dir` ではなく `ll` と打ってしまうので作りました。

# 🙋 具体例 (自分の場合)
### `.cmd` ファイルを集めるディレクトリを作る
C:\src\aliases を作って、そこに `.cmd` ファイルを集めました。

### `.cmd` ファイルの中身を書く
Linux の `ls -laF` と似た動きをする `ll.cmd` ファイルの中身は例えば以下。
```winbatch:ll.cmd
:: Linux の ls -laF みたいな動きをするコマンド
@echo off
dir /A /Q

```

`::` がついている行はコメントなのでなくても大丈夫です。

`@echo off` は実行コマンドの内容を表示しないためにつけています。
(コマンドの出力結果は表示されます)

`.cmd` ファイルの作成は VS Code とかを使うと楽だと思います。

### PATH を通す
PATH の通し方は先輩方のわかりやすい記事を参照。
コントロールパネルからできます。

参照：
- [Windows11でのPathの通し方](https://tech.gijukatsu.com/windows11_path/)


# 🙏 最後に
いくつか先輩方の記事等も拝見したんですが、
個人的にしっくり来る方法が見つからず現在の方法に着地しました。

理想は .bash_aliases のような形でエイリアスを管理できることなので
もっとより良い方法を知っている方がいらっしゃいましたらぜひ教えてください🙏

自分の備忘録も含めた内容となっており
気張らずゆるく書いた内容ですので悪しからず。
Amazon RDS におけるエンジンアップグレードと OS アップデートの違い

RDS は、クラウド上でリレーショナルデータベースのセットアップ、運用、スケーリングを簡単にするマネージドサービスです。このサービスはセキュリティ、パフォーマンス、メンテナンスの面で多くの利点を提供しますが、適切な運用にはデータベースエンジンのアップグレードとオペレーティングシステムのアップデートの理解が不可欠です。

## データベースエンジンのアップグレード
データベースアップグレードは、RDS インスタンスが使用するデータベースエンジンのバージョンを新しいものに更新するプロセスです。これには、セキュリティ修正、新機能、パフォーマンス改善などが含まれることがあります。アップグレードには 2 種類あります。
以下、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html)から引用します。 [1]

### マイナーアップグレード
>マイナーバージョンのアップグレードには、既存のアプリケーションとの下位互換性がある変更のみが含まれます。

### メジャーアップグレード
>メジャーエンジンバージョンのアップグレードは、既存のアプリケーションと互換性のない変更を導入する場合があります。


## オペレーティングシステムのアップデート
オペレーティングシステム（OS）のアップデートは、RDS インスタンスを支える基盤となる OS にパッチを適用することを指します。これには、セキュリティパッチ、バグ修正、システムの安定性向上が含まれます。OS のアップデートは、システムの脆弱性を減らし、全体的なセキュリティを向上させるために重要です。

こちらのアップデートも 2 種類あります。[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_UpgradeDBInstance.Maintenance.html#OS_Updates)から引用します。[2]

### オペレーティングシステムのディストリビューションのアップグレード 
> サポートされている最新のメジャーバージョンの Amazon Linux への移行に使用します。保留中のメンテナンスアクションの説明は `New Operating System upgrade is available` です。

### オペレーティングシステムパッチ 

> さまざまなセキュリティ修正を適用するために使用され、場合によってはデータベースのパフォーマンスを向上させるために使用されます。保留中のメンテナンスアクションの説明は `New Operating System patch is available` です。


## 影響の範囲
データベースアップグレードはアプリケーションの互換性に影響を与える可能性があります。
一方、OS アップデートは通常、アプリケーションレベルでの変更を必要としません。

## ベストプラクティス
- 計画とテスト：大きな変更を実施する前に、変更がアプリケーションに与える影響を理解し、適切なテストを行うことが重要です
- メンテナンスウィンドウの活用：影響を最小限に抑えるために、アップグレードやアップデートをメンテナンスウィンドウ中に計画します
- 自動アップデートの検討：RDS はマイナーアップグレードを自動的に適用するオプションを提供しますが、メジャーアップグレードとOSアップデートには手動で対応する必要があります

## 結論
RDS のデータベースアップグレードと OS アップデートは、インスタンスの健全性とセキュリティを維持するために重要です。これらのプロセスを正しく理解し、適切に管理することで、アプリケーションの安定性とパフォーマンスを最大限に高めることができます。

## 参考資料
[1]  [DB インスタンスのエンジンバージョンのアップグレード](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html)
[2] [Amazon Aurora DB クラスターのメンテナンス](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/USER_UpgradeDBInstance.Maintenance.html#OS_Updates)
Amazon Linux 2023のRSA認証でどハマりした件

久しぶりに認証キーでハマりました。
いくらRSAキー作成しても外部とSSH公開鍵認証出来ないと思ったら、
RSAが使えなくなってた（汗

```
Amazon Linux 2023 (AL2023) には、従来の ssh-rsa ホストキーアルゴリズムを無効にして・・・（略）
```

外部のSSHサーバなどがレガシーなSSH公開鍵認証の場合は次のコマンドでAmazonLinux側も設定する必要が有る。

```
$ sudo dnf install crypto-policies-scripts
$ sudo update-crypto-policies --set LEGACY
```

念のためRSAキーを再度設定して無事に接続完了。


ちなみにChatGPTにこの件知ってた？ と問い合わせたら。。。

Amazon Linux 2023でRSA認証ができなくなっているという情報は、直接知りませんでしたが、最近のLinuxディストリビューションやSSHのアップデートに関連するセキュリティ強化の一環である可能性があります。

なかなかの推論。
やるなGPT。
もうAIに負けてるレガシーエンジニアな古参兵からお届けでした👴
オフライン・オンラインのハイブリット開催の設定について

# どんな方が読むとよい記事か
- 社内でオフライン・オンラインのハイブリット開催のイベントやることになった人
- イベント運営でOBS周りを知りたい人

# 何が書かれているか
- オフライン・オンラインのハイブリット開催イベントで利用できる機材接続など
- OBSとZoom, meet周りの繋ぎ込み方など

# 記事
[こちら](https://tech.excite.co.jp/entry/2024/03/14/135347)に記載しております。
【React】Compound Components

## はじめに
業務の中でデザインパターンの一つである Compound Components というものを知ったので、どんなふうに使うのか？を記事にまとめてみました。

## Compound Components とは
Compound Components は、全体を親コンポーネントで囲み、子コンポーネントをユーザーに指定させるパターンです。
データを Props 経由で渡し、一つのコンポーネントの中で全てを処理するのではなく、子コンポーネントとして渡すようにします。

https://www.patterns.dev/react/compound-pattern

## Compound Components の利用例
Header / Body / Footer を共通レイアウト化して使えるようにしたいが、ページによって少しカスタマイズしたい、といったケースで考えてみます。

#### Compound Components を使わない実装例

「Footer は全ページ共通だが、Header は条件により出し分けたい」とします。

```React
type Props = {
  globalMenuList?: GlobalMenu[]
  pageTitle: string
  children: ReactNode
}

export const CommonLayout: React.FC<Props> = ({ globalMenuList, pageTitle, children }) => (
  <div>
    {globalMenuList ? (
      <Header  pageTitle={pageTitle}>
        <GlobalMenu globalMenuList={globalMenuList} />
      </Header>
    ) : (
      <Header pageTitle={pageTitle} />
    )}
    {children}
    <Footer />
  </div>
)
```
<br>

↓使用イメージ
```jsx
<CommonLayout globalMenuList={globalMenuList}>
  <div>
    body の中身
  </div>
</CommonLayout>
```

JSX のなかで条件によって表示を出し分けたいときは条件付きレンダーを使うことが多いと思います。

https://ja.react.dev/learn/conditional-rendering

上記のコード例は非常にシンプルなのでそこまで複雑には見えないですが、実務だとコード量がさらに大きく、条件つきレンダーを使用する箇所も増えてくるため、見づらく感じることがあります。


また、Header まで全て `CommonLayout` のなかで表現しようとすると、レイアウトの共通化をしたい目的で作っているのに、 `CommonLayout` が知っていることが増えてしまっています。


#### Compound Components を用いた実装例

`CommonLayout` から Header 部分を `CommonLayoutHeader` に切り出してみます。
```react
type CommonLayoutHeaderProps = {
  children?: GlobalMenu[]
  pageTitle: string
}

type CommonLayoutProps = {
  children: ReactNode
}

export const CommonLayoutHeader: React.FC<CommonLayoutHeaderProps> = ({ children, pageTitle }) => (
  <Header pageTitle={pageTitle}>
    {children}
  </Header>
)

export const CommonLayout: React.FC<CommonLayoutProps> = ({ children }) => (
  <div>
    {children}
    <Footer />
  </div>
)
```
<br>

↓使用イメージ
```jsx
// グローバルメニューを出したいページでは children として GlobalMenu を渡す
<CommonLayout>
  <CommonLayoutHeader  pageTitle={pageTitle}>
    <GlobalMenu globalMenuList={globalMenuList} />
  </CommonLayoutHeader>
  <div>
    body の中身
  </div>
</CommonLayout>

// グローバルメニューを出さないページでは children を渡さないようにする
<CommonLayout>
  <CommonLayoutHeader  pageTitle={pageTitle} />
  <div>
    body の中身
  </div>
</CommonLayout>
```

使う側から GlobalMenu を渡すことができるようになり、 適切に CommonLayout との責務の分割ができています！

## さいごに
なんでも props として渡すと渡すものがどんどん膨れ上がったり、props が多いと「これを渡すとどうなるのか？」がどんどん複雑になっていってしまいます。
こんなときに Compound Components を取り入れ、データを子コンポーネントへ渡すようにすることで直感的にも使いやすいし、責務の分割も適切にできるようになる、と感じました。

適材適所で使い分けができるようになっていきたいです。

## 参考

https://www.patterns.dev/react/compound-pattern

https://ja.react.dev/learn/conditional-rendering
Prettier互換の爆速フォーマッターBiomeを試してみた

JavaScript、TypeScript、およびJSX用のツールチェーンであるBiomeを実際のプロジェクトで試しました。Biomeは、高性能なフォーマッター、リンター、およびその他の開発者向けツールを提供します。本稿では、Biomeの特徴、インストール方法、設定ファイルのカスタマイズなどについてのレポートを書きます。

## Biomeの特徴

- 高性能なフォーマッターとリンター
- Prettierとの97%の互換性
- CLIおよびLSPを介した利用可能性
- コミュニティ駆動の継続的な改善

https://biomejs.dev/

## インストール

```bash
yarn add --dev --exact @biomejs/biome
```

プロジェクトの`package.json`ファイルがあるディレクトリで上記コマンドを実行します。

## 設定ファイルの初期化

```bash
yarn biome init --jsonc
```

このコマンドにより、`biome.jsonc`設定ファイルが生成されます。デフォルトの設定ではインデントがTABになっていますが、これをスペースに変更することを選択しました。(Prettierの設定がそうだったため)

## 設定変更

インデントスタイルを「スペース」に変更するため、`biome.jsonc`ファイルに以下の設定を追加しました：

```jsonc
"formatter": {
    "enabled": true,
    "indentStyle": "space"
}
```

## 実行

以下のコマンドでとりあえずディレクトリ内のすべてのファイルをフォーマットしてみました。

```
yarn biome format . --write
```

Biomeを使用して、以前Prettierを使用していた126ファイルが含まれるプロジェクトディレクトリをフォーマットしてみました。結果は非常に印象的で、Biomeは1ファイルを除く全てのファイルで問題なくチェックを通過しました。互換性すごい！

特に注目すべきは、Prettierを使用した場合の処理時間が2秒であったのに対し、Biomeではわずか34ミリ秒で処理が完了したことです。速すぎて正直おどろきました。

## おわり

Biomeはその高速性とPrettierとの高い互換性で、JavaScriptプロジェクトのフォーマットにおいて非常に優れた選択肢です。今回のお試しを通して、Biomeの潜在能力と効率性を実感しました。今後はリンター機能も試してみたいと思います。
Cloudflare Pagesのデプロイ時に"A request to the Cloudflare API failed.Project not found. The specified project name does not match any of your existing projects."が出た時の対処法

# エラーが起こった状況

Honoを使用してCloudflare Pagesにデプロイした。

`$ bun run deploy`

https://hono.dev/getting-started/cloudflare-pages#_4-deploy

しかし、設定を間違えたため一度プロジェクトを削除し、再度`$ bun run deploy`

### "A request to the Cloudflare API failed.Project not found. The specified project name does not match any of your existing projects."


おこられちゃった(そりゃそう)

# 解決策

先ほど作ったプロジェクト情報がどこかに登録されているようだが、どこにあるか分からずエラー文で検索。

Cloudflare Communityに同様のエラーを発見。

https://community.cloudflare.com/t/using-wrangler-for-pages/557242

> You can delete the cache (node_modules/.cache/wrangler/pages.json) to get back to us not knowing a project at all or specify --project-name

「キャッシュ(node_modules/.cache/wrangler/pages.json)を削除して、プロジェクトを全く知らない状態に戻すか、-project-nameを指定してください。」とのこと。

念の為ドキュメントで確認。

https://developers.cloudflare.com/pages/get-started/direct-upload/#set-up-wrangler

> Subsequent deployments will reuse both of these values (saved in your node_modules/.cache/wrangler folder).

「以降のデプロイでは、これらの値（node_modules/.cache/wranglerフォルダに保存されている）を再利用します。」

あってそう。消す。

```node_modules/.cache/wrangler/wrangler-account.json
{
  "account": {
    "id": "aaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "name": "aaaaaaaaaaaaa@sample.com's Account"
  }
}
```
`$ bun run deploy`

同じエラーが出る😇

node_modules/.cache/wrangler/pages.jsonの中にもプロジェクトの情報があったので削除してみる

```
$ $npm_execpath run build && wrangler pages deploy dist
$ vite build
vite v5.1.5 building SSR bundle for production...
✓ 48 modules transformed.
dist/_worker.js  31.49 kB
✓ built in 232ms
✔ Enter the name of your new project: … project name
✔ Enter the production branch name: … main
✨ Successfully created the 'project name' project.
🌏  Uploading... (5/5)

✨ Success! Uploaded 5 files (2.74 sec)

✨ Compiled Worker successfully
✨ Uploading Worker bundle
✨ Deployment complete! Take a peek over at https://aaaaa.projectname.pages.dev
```

できました。
The Power of Point of Sale (POS) Systems in Modern Business

In today's fast-paced retail and hospitality industries, efficiency and accuracy are paramount. Enter Point of Sale (POS) systems, the backbone of modern businesses. A POS system is a combination of hardware and software that facilitates transactions, manages inventory, and provides valuable insights into business operations. Let's delve into why POS systems are indispensable for businesses of all sizes:

Streamlined Transactions:
POS systems streamline the checkout process, allowing businesses to process transactions quickly and efficiently. With features like barcode scanning and integrated payment processing, POS systems minimize wait times for customers and ensure smooth transactions at the point of sale.

Inventory Management:
Managing inventory is a breeze with POS systems. These systems track product sales in real-time, automatically updating inventory levels as items are sold. This real-time visibility into inventory helps businesses avoid stockouts, optimize reorder points, and reduce the risk of overstocking.

Insightful Reporting:
POS systems provide businesses with valuable insights into sales performance, customer trends, and product profitability. Through detailed reporting and analytics, businesses can identify top-selling products, track sales trends over time, and make data-driven decisions to drive growth and profitability.

Enhanced Customer Experience:
With POS systems, businesses can provide a seamless and personalized customer experience. Features like customer relationship management (CRM) enable businesses to track customer preferences, purchase history, and loyalty program participation, allowing for targeted promotions and tailored experiences.

Integration Capabilities:
POS systems integrate seamlessly with other business systems, such as accounting software, e-commerce platforms, and marketing tools. This integration streamlines operations, reduces manual data entry, and ensures consistency across various aspects of the business.

Accessibility and Scalability:
Modern POS systems offer cloud-based solutions, providing businesses with anytime, anywhere access to their POS data. This accessibility allows businesses to manage operations remotely, track sales in multiple locations, and scale their operations as they grow.

In conclusion, POS systems are essential tools for businesses looking to streamline operations, enhance customer experiences, and drive growth. By leveraging the power of POS technology, businesses can stay ahead of the competition and thrive in today's dynamic marketplace.
Windows TerminalでGitBashを表示する設定をした後にすること


[こちら](https://qiita.com/yokra9/items/bdd0882268b308cf22ca)の記事を参考にWindows Terminal上にGitBashを表示する設定をしました。

https://qiita.com/yokra9/items/bdd0882268b308cf22ca

不具合というほどではないのですが、いくつか気になった点があったので対応しました。
自分用の覚書です。

## GitBashでコマンド履歴を有効にする
Windows Terminalに表示させる前まではコマンド履歴が記録されていたのですが、設定後から無効になってしまいました。
コマンド履歴を復活させるコマンドです。
```
& history -a
```

## .configファイル関係の置き場所変更
GitBashの.bash_historyファイルに限らずGit関係の設定ファイルが、ホームディレクトリに丸見えの状態で置かれるようになりました。
ホームディレクトリを開くたびに気になっていたので、設定ファイル関係を置いておく専用ディレクトリ「.config」を作成し、隠しフォルダ設定にしました。

ディレクトリが用意出来たら、Pathを通します。
設定＞システム＞詳細情報＞システムの詳細設定で「システムのプロパティ」を開きます。
詳細設定タブ＞環境変数(N)をクリック。
上段のユーザー環境変数(U)の新規作成をクリックして、下記内容を入力しOKを押す。
```
変数名(N)：HOME
変数値(V)：%USERPROFILE%\.config
```
これでホームディレクトリは元のままで、設定ファイル関係だけ「.config」ディレクトリに保存されるようになりました。
Laravel11 アップデートが来たった！！

# Laravel11 アップデート

Laravel11 がリリースされたので色々な記事を参考に自分なりにまとめていきます。

ReleaseNote : https://laravel.com/docs/11.x/releases

## 前提情報

PHP8.2 以上

## スリム化された構成

> 新しいアプリケーション構造は、Laravel 開発者がすでによく知っている概念の多くを保持しながら、より無駄がなく、より現代的なエクスペリエンスを提供することを目的としています。

```
app/
├── Http/
│   └── Controllers/
│       └── Controller.php
├── Models/
│   └── User.php
└── Providers/
    └── AppServiceProvider.php
bootstrap/
├── app.php
└── providers.php
routes/
├── console.php
└── web.php
```

※今回は上記の 7 ファイルについて記述していきます。

## コントローラは何も継承しない

https://github.com/laravel/laravel/blob/11.x/app/Http/Controllers/Controller.php

```
<?php

namespace App\Http\Controllers;

abstract class Controller
{
    //
}
```

何も継承せず空ファイルになっています。
`AuthorizesRequests` や `ValidatesRequests` はなくなったのでデフォルトの状態では記述方法が変わっているようです。

## モデルには特に変更なし

https://github.com/laravel/laravel/blob/11.x/app/Models/User.php

ver10 では `$casts` であったが ver11 では `casts()` と関数型に変更されている。用途は同じだと思いますが、検証が必要ですね。

## サービスプロバイダは１つに統一

ver10 では`AppServiceProvider`, `AuthServiceProvider`, `BroadcastServiceProvider`, `EventServiceProvider`, `RouteServiceProvider`と 5つのサービスプロバイダがあったが、ver11 からは `AppServiceProvider.php` の１つとなり、削除されたファイルの機能は `bootstrap/app.php` に組み込まれたようです。

https://github.com/laravel/laravel/blob/11.x/bootstrap/providers.php

サービスプロバイダを作成した時には今まで、手動で `config/app.php` に追加していたが、make コマンドで作成していたが、自動的に `bootstrap/providers.php`に追加されるとのこと。

## 一番変わった bootstrap/app

https://github.com/laravel/laravel/blob/11.x/bootstrap/app.php

今まではほとんど触る事のなかった、このファイルですが機能が増えています。
`bootstrap/app.php` を使って、アプリケーションのルーティング・ミドルウェア・サービスプロバイダ・例外処理などのカスタマイズができるようです。今まで、Kernel.php で行っていた Middleware の設定も `bootstrap/app.php` で行う。

```
<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        //
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();
```

## バッチ処理のスケジュールを routes/console.php に集約

今まで `app/Console/Kernel.php` に記載していたスケジュールさえ r たタスクを `routes/console.php` にまとめて定義することができるようになりました。

https://github.com/laravel/laravel/blob/11.x/routes/console.php

```
<?php

use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote')->hourly();
```

## 新しい make:xxxx コマンド

```
php artisan make:enum
php artisan make:class
php artisan make:interface
```

`interface`と`enum`は嬉しい。独自で作っていたものが標準搭載されるようになっている。

## その他気になったところ

- .env 内の database のデフォルトが sqlite になった（たぶん mysql だったと思う）
- migrations の中に cache テーブルの作成が入っている（cache も DB がデフォルト？）
Javascriptでファイルのアップロード・ダウンロードを簡単にするライブラリを作ったので使用方法をメモ

# ファイル操作ライブラリ
とりあえずeasyfile.jsと名付けます
アクセス用オブジェクトはEasyFile(window.EasyFile)とします
## EasyFile(window.EasyFile)のPromise非同期イベント
### Promise(EasyFileData) EasyFile.upload(String accept)
ファイルを入れてもらう
引数acceptは、image、audioなど、MIMEタイプの左側を記入してください。
返り値：ファイルのクラス(EasyFileData)のPromise非同期イベント
　　　　選択されなかった場合nullのPromise非同期イベント
### Prmise(EasyFileData) EasyFile.upload(String[] accept)
上の関数の複数のMIMEタイプ・拡張子バージョン
### void EasyFile.download(String fname, String content, String mimetype)
特定のString情報をダウンロード
返り値：無し
## EasyFileData
### Promise(String) EasyFileData.toBinaryString()
ファイルの内容をバイナリ文字で返す
返り値：ファイルの内容のバイナリ文字の非同期イベント
### Promise(String) EasyFileData.toDataURI()
ファイルの内容をDataURIに変換して返す
DataURIとは、
```
data:[MIMEタイプ];base64,XXXXXX....
```
と記述される、URL感覚で画像・音声等をHTMLに埋め込めるURIです。
返り値：ファイルの内容のDataURIの非同期イベント
### Promise(String) EasyFileData.toBase64()
ファイルの内容をBase64エンコードして出力
返り値：ファイルの内容をBase64エンコードしたものの非同期イベント
### String EasyFileData.MimeType()
ファイルのMIMEタイプを返す
返り値：ファイルのMIMEタイプ
### Int EasyFileData.Size()
ファイルのサイズ(単位はバイト)を出力
返り値：ファイルのバイト数
### String EasyFileData.Fname()
ファイルのファイル名(image.png、sound.mp3という風な)
返り値：ファイル名

以上です。
[Githubで投稿しています。](https://github.com/TNTSuperMan/EasyFile.js)
他に欲しい機能がある場合はコメントお願いします。
VSCodeのLive Serverで立ち上げたサーバーにスマホからアクセスする

# 目標

VSCodeのLive Serverで立ち上げたサーバーにスマホからアクセスする。

![Screenshot_20240315-200614.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599663/3e32eb79-6a54-27e3-62f1-6e4c8957f0fa.png)

## 1. パソコンでローカルサーバーが起動されてることを確認

![Screenshot 2024-03-15 at 20.04.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599663/3f04e4c2-5850-a21f-2d77-6e39c3720e4a.png)


## 2. 接続しているルーターのIPアドレスを確認する
### Mac
「設定」→「Wifi」→「詳細」から確認。

![Screenshot 2024-03-15 at 20.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599663/669d5c32-ef05-f315-b550-9ce1324301bd.png)


### Windows
手元にWindows PCが無いので確かでありませんが
「ネットワーク」→「プロパティ」
から見られるそうです。

## 3. スマホのアドレスバーにIPアドレスとポート番号を打ち込む

![Screenshot_20240315-200614.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599663/8320fbc3-3b51-b1ac-cd13-cd596548ff98.png)

Live Serverで立ち上げたサーバーにスマホからアクセスすることができました。
競プロの問題をnibblesで解く①

# はじめに
コードゴルフ用言語のnibblesについて、記事が全く存在しなかったので作ってみました。
気になるけど資料が無くて始めにくい。。。という方の参考になればと思います。

あまり詳しいことには触れないので、気になる方は[こちら](http://www.golfscript.com/nibbles/index.html)をご覧ください。

今回は、簡単な入力かつ単純な計算で解ける問題を扱います。
ABC001 - 005 A問題の難易度がちょうど良かったため、解いてみます。

各問題のフォーマット下記の通りです。
（kotatsugameさんの[こちらの記事](https://qiita.com/kotatsugame/items/184bfd63d9b21f214475)から、丸パクリさせていただきました。）

> 入力形式

解法

```:Byte数
コード
``` 
コメント

# 問題
## [ABC001 A - 積雪深差](https://atcoder.jp/contests/abc001/tasks/abc001_1)
> $ H_1 $
> $ H_2 $

$H_1 - H_2$を出力します。
```nibbles:4byte
-$;$
```
3byteの解答が存在しますが、foldの知識が必要になるため、今回はこちらの解答を考えます。
nibblesの演算は大体が下記の形で行われます。
**演算子 引数1 引数2 $\cdots$**

[リファレンス](http://www.golfscript.com/nibbles/quickref.html)で引き算に該当する演算を確認してみましょう。
引き算（subtract）のLit, Arg Typesを確認すると、
|演算子|引数1|引数2|
|:---:|:---:|:---:|
|-|num|num|

がわかります。
演算子 引数1 引数2 の通りに 「- 5 3」 と書いてみると、 $5 - 3$ ができるわけです。
nibblesでは入力1つ目の数字を「\\$」、2つ目の数字を「;\$」で受け取れますので、
```nibbles:6byte
- $ ;$
```
最後に不要なスペースを削除すれば完了です。
ちなみに出力にprint文のようなものは必要ありません、勝手に出力してくれます。

## [ABC002 A - 正直者](https://atcoder.jp/contests/abc002/tasks/abc002_1)
> $ X  \quad  Y $

${\rm max} (X,Y)$を出力します。
```nibbles:3byte
];$
```
maxの演算は以下となります。
|演算子|引数1|引数2|
|:---:|:---:|:---:|
|]|num|num|

先ほどの問題と同様に、
```nibbles:4byte
]$;$
```
で正しく出力が行われます。
ここで、nibblesには **Implicit Args（暗黙的引数）** というものが存在します。
簡単に説明すると、最後が\\$で終わるとき、大体省略できちゃうよってやつです。
※「\\$」単体である必要があります。「;\$」を「;」とすることはできません。
先ほどの
```nibbles:4byte
]$;$
```
について、\\$と;\$の場所を変えても結果は変わりませんから、
```nibbles:4byte
];$$
```
$で終了しているので、これは省略可能です。
```nibbles:3byte
];$
```
無事3byteとなり完了です。

## [ABC003 A - AtCoder社の給料](https://atcoder.jp/contests/abc003/tasks/abc003_1)
> $ N $

$(N+1) \times 5000$を出力します。
```nibbles:7byte
*5000+1
```
足し算、掛け算の演算はそれぞれ以下です。
（実際は他の引数にも対応可能なため、リファレンスの表記は異なります。）
|演算子|引数1|引数2|
|:---:|:---:|:---:|
|+|num|num|
|*|num|num|

そのまま実装して、
```nibbles:9byte
*+$1 5000
```
5000を前に持ってくるとスペースが削減できますね。
```nibbles:8byte
*5000+$1
```
最後に\$と1の場所を反転して、省略すれば完了です。
```nibbles:7byte
*5000+1
```

## [ABC004 A - 流行](https://atcoder.jp/contests/abc004/tasks/abc004_1)
> $ N $

$2 \times N$を出力します。
```nibbles:1byte
+
```

$2 \times N$をそのまま実装すると
```nibbles:3byte
*2$
```

\\$を省略して「*2」の2byteでしょうか。
ここで、$2 \times N$を$N + N$と考えてみます。
```nibbles:3byte
+$$
```
\$が2個並んでますね。
しっかりどちらも省略可能です。よって
```nibbles:1byte
+
```
となるわけです。

## [ABC005 A - おいしいたこ焼きの作り方](https://atcoder.jp/contests/abc005/tasks/abc005_1)

> $x \quad y$

$\lfloor y/x \rfloor$を出力します。

```nibbles:3byte
/;$
```
割り算は以下の通りです。
|演算子|引数1|引数2|
|:---:|:---:|:---:|
|/|num|num|

実はnibbles, 整数しか扱えません。
そのため、自動的に切り捨て除算となるので、これをそのまま実装すればOKです。
最後の\$省略を忘れずに。

# おわりに
下記の問題も簡単な演算で解けるのでぜひ解いてみてください。
- [ABC008 A](https://atcoder.jp/contests/abc008/tasks/abc008_1)
- [ABC009 A](https://atcoder.jp/contests/abc009/tasks/abc009_1)
- [ABC011 A](https://atcoder.jp/contests/abc011/tasks/abc011_1)
- [JOI 2021/2022 一次予選 (第2回) A](https://atcoder.jp/contests/joi2022yo1b/tasks/joi2022_yo1b_a)
- [パ研合宿2021　第2日「SpeedRun」 B](https://atcoder.jp/contests/pakencamp-2021-day2/tasks/pakencamp_2021_day2_b)

次回はもう少し複雑な入力を扱ってみたいと思います。
【Rails】楽天APIで一度に複数のジャンルIDで検索してみた

## はじめに
Railsでのアプリ作成で楽天APIを使用することになったのですが、その際に一度の検索で複数のジャンルIDを使用した検索機能を実装しました。使用機会は多くないものだと感じましたが、記事にまとめたいと思います。


※このページの情報は2024年3月時点の情報となります。公式の最新情報などと照らし合わせてお読みください。

## 楽天APIの使用準備

まず、楽天APIの使用準備について簡潔に解説したいと思います。

(1) [Rakuten Web Service](https://webservice.rakuten.co.jp/)のページに移動

(2) 右上にログインボタンや言語選択ボタンがあります。言語を選択してRakuten Web Serviceのアカウントを作成し、ログイン。

(3) ログイン後、言語選択ボタン近くの「アプリID発行」の項目をクリック。新規アプリ登録画面に映るので、必要な項目を入力。

(4) アプリ登録後は「アプリ情報の確認」をクリック。アプリ一覧画面が表示されますが、その項目にあるアプリID(applicationId)が楽天APIを使用する上で必要になります。Rakuten Web Serviceでの作業はこれで終了です。

(5) ここからRailsアプリでの作業です。
Gemfileに次のgemを記載してインストールしましょう。

```ruby
gem 'rakuten_web_service'
gem 'dotenv-rails'
```
アプリIDをGithub上にそのまま上げると悪用される可能性が生じるので、環境変数を設定するgemの使用がおすすめです。今回はdotenv-railsを使用します。

(6) gemのインストールが終わったら、カレントディレクトリで.envファイルを作成し、ファイル内で環境変数を定義します。
```ruby
RWS_APPLICATION_ID='applicationId'
```
applicationIdの部分は、「アプリ情報の確認」ページで確認したアプリIDにしてください。


(7) 楽天APIを使用するためのファイルをconfig/initializersディレクトリ内に作成します。そして、作成したファイルの内容を次のようにします。

```ruby
RakutenWebService.configure do |c|
  # (必須) アプリケーションID
  c.application_id = ENV['RWS_APPLICATION_ID']

  # (以下の項目は任意で入力)
  # c.affiliate_id = 'YOUR_AFFILIATE_ID' # default: nil
  # c.max_retries = 5 # default: 5
  # c.debug = true # default: false
end
```

最低限必要になるのはc.application_id = ENV['RWS_APPLICATION_ID']の1行です。他は必要があれば追加してください。また、gemの詳しい解説については[公式ドキュメント](https://github.com/rakuten-ws/rws-ruby-sdk/tree/master)を確認してください。

これで楽天APIを使用する準備は完了です。


## 複数のジャンルIDを使用した検索の必要性

そもそも一度の検索で複数のジャンルIDを使用する必要があるかですが、以下の状況で使用を検討できるのではないかと考えています。

(1)特定の商品ジャンルで商品検索を行いたい、かつその商品が複数のジャンルIDに分かれている場合

(2)ユーザーが商品検索を行う際にジャンルを選択する手間を省きたい場合

(3)ユーザーが商品ジャンルを選択する際、探したい商品がどのジャンルに含まれるかわからないことが想定される場合

いずれも実際の開発では稀だと思いますが、遭遇する可能性は少なからず存在すると思います。


## 複数のジャンルIDを使用した検索機能の実装

楽天APIを使用した検索でジャンルIDを設定する場合、次のような形での実装が考えられます。

```ruby
def search
 if params[:keyword]
  @results = RakutenWebService::Ichiba::Item.search(keyword: params[:keyword], 
                                                         genreId: '506384')
 end
end
```

キーワード引数genreIdでジャンルIDを定義することになるかと思いますが、この形だと単一のジャンルIDでしか検索できません。

ではどうやって複数のジャンルIDで検索するかですが、今回私はeachメソッドを使用した繰り返し処理での実装を行いました。
```ruby
def search_results
  @results = []
  genre_ids.each do |genre_id|
    results = RakutenWebService::Ichiba::Item.search(keyword: params[:keyword], 
                                                     genreId: genre_id,).to_a
    @results.concat(results)
  end
  p @results
end

def genre_ids
  %w[506385 506386 506387 506389 568329 551692 551693 208522]
end

```

genre_idsメソッドで定義したジャンルIDを取り出して検索し、検索結果を配列にした後、concatメソッドで破壊的に連結するのを繰り返し、最後にpメソッドで検索結果を出力します。

本来であれば、検索結果を格納する配列を用意せずとも配列で返すmapメソッドを使用できれば良いのですが、どうしてもmapメソッドを使用した形に修正できませんでした・・・ここは改善すべき点だと思うので、引き続き調査を行っていきたいと思います。

## まとめ
使用する機会は少ないと思いますが、解説されている記事を発見できなかったので記事にまとめました。執筆するのは今回が初めてで、プログラミング学習も日が浅いので内容面、技術面で拙い部分が多いかもしれませんが、こういうやり方もあるのかと何かの参考になれば幸いです。

最後まで読んでいただき、ありがとうございます！
Laravel 11のアーティさん【php artisan make:class/enum/interface/trait】

Laravel 11で追加されたartisanの挙動を確認しよう！

https://laravel.com/docs/11.x/releases#new-artisan-commands

# Laravel 11のインストール
Laravel 11はPHP8.2以上が必要です
```bash
composer create-project laravel/laravel:^11.0 example-app
cd example-app
```

# php artisan make:class

```bash
$ php artisan make:class Hoge

   INFO  Class [app/Hoge.php] created successfully.
```

```php:example-app/app/Hoge.php
<?php

namespace App;

class Hoge
{
    /**
     * Create a new class instance.
     */
    public function __construct()
    {
        //
    }
}
```

# php artisan make:enum

```bash
$ php artisan make:enum Hoge

   INFO  Enum [app/Hoge.php] created successfully.
```

```php:example-app/app/Hoge.php
<?php

namespace App;

enum Hoge
{
    //
}
```

# php artisan make:interface

```bash
$ php artisan make:interface Hoge

   INFO  Interface [app/Hoge.php] created successfully.
```

```php:example-app/app/Hoge.php
<?php

namespace App;

interface Hoge
{
    //
}
```

# php artisan make:trait

```bash
$ php artisan make:trait Hoge

   INFO  Trait [app/Hoge.php] created successfully.
```


```php:example-app/app/Hoge.php
<?php

namespace App;

trait Hoge
{
    //
}
```
VBAで現在時刻をセルに書き出す

Ctrl+Shift+;で現在時刻を出すことができるが３つ同時押しはめんどくさいのでVBAにした。
意外とこういう細かいところは役に立つ

```ruby:VBA
Sub InsertCurrentTime()
    ' アクティブセルに現在時刻を出力する
    ActiveCell.Value = Now
End Sub

```
【GCP】ログインしてプロジェクト作成、VMインスタンスを立ち上げる

こんにちは
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
ちょっとGCP(Google Cloud Platform)を学ぶ必要が出てきたので、
とりあえずのGCP環境をどうやって作るかという事をざっとメモっていきます。

GCPと検索掛けて以下にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/0c27c009-e162-90c4-971e-26e1bad7bb06.png)

ログイン画面が表示されますので、持っている任意のGoogleアカウントでログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d25fec66-3398-65df-2d21-33cd958829b5.png)

Welcomeページ的なのが表示されます。画面左上のプロジェクトの選択を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/812a4ada-5db7-d8d6-36d6-3ba6c646cd21.png)

デフォルトで色々用意されていますが、新しく作りたいと思います。
画面右上の新しいプロジェクトを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/76d0a380-07b0-0535-a540-3f188af44705.png)

プロジェクト名のところに任意の名前を入力します。
今回はmy-projectとしました。作成を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/0780e72c-ce84-0d19-3b3e-bbe2d485d4aa.png)

画面左上に作成したプロジェクト名が表示されていることがわかります。
または作業中のプロジェクトにも記載がされています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/952bd8b8-dfdf-9bb7-fc61-c7059d0c6a5e.png)

次にVMを立ち上げるためのGCE(Google Compute Engine)を有効化します。
画面左上の三本線を押下してCompute Engine > VMインスタンスを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/175b15d3-e562-fba0-4bfe-216c74e410f5.png)

Compute Engine APIが表示されます。有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/125e5f07-1af2-e0f0-62ea-b5c48ff6e1c6.png)

有効化が完了すると以下のような画面が表示されます。
インスタンスを作成ボタンを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/b2370dfc-696b-57d3-65e8-aa9d3d711787.png)

名前・リージョン・マシン構成・マシンタイプ・ファイアウォールにそれぞれ設定を入れて作成します。
![screencapture-console-cloud-google-compute-instancesAdd-2024-03-15-17_53_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/ad2dbef4-cfbb-7a71-12dd-ca7a307f0ca3.png)

暫くするとVMインスタンスが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/05a0576a-aeb1-006b-d611-3a96de6ec452.png)

VMインスタンスの名前を押下するとそのインスタンスに対する詳細画面に遷移することが出来ます。SSHの右にある▼を押下して、ブラウザウィンドウで開くを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d8fb390b-a7ce-c16b-85b7-e0035f4b97d8.png)

別のタブが開き、CUIが表示されサーバを操作することが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/a89b488b-74da-b705-ae4a-a28f74d7bbb2.png)
Rでの計算の進捗確認（progress bar）

時間のかかる計算をするとき、きちんと動いているのか、あとどれくらい時間がかかるのか、確認したくなります。
自分はそんな時、以下のようなprogress barを表示させることで進捗を表示するようにしています。
```
|========================              | 60%
```

よく使う割にはいつもコードの書き方を忘れて調べなおしているので、備忘録として残しておきます。なおここに記す方法は、`for`文などを用いた繰り返し計算の進捗確認方法です。

## コード
```

# 1
n.rep <- 100000 

# 2
pb <- txtProgressBar(min = 1, max = n.rep, style = 3, char = "=")

# 3
for(i in 1:n.rep){
    # calculation

    # 4
    setTxtProgressBar(pb, i)
}

```

## コードの内容
1. `for`ループの繰り返し数を決める
1. プログレスバーの下限（`min`）・上限（`max`）・スタイル（`style`）・進捗を表示する記号（`char`）を指定する
   - `for`ループ全体が終わるときに進捗100%となるように、maxには繰り返し数`n.rep`を、minには最小の1を指定している
   - `style`は何種類かあるが、1, 2だと`char`で指定した記号（上の場合は`=`）が
   ``` ==================== 　　　　　　　　　```
   とコンソール画面の幅いっぱいに伸びる形で進捗が示される。3を指定すると、
   ```|===　　　　　　　　　　　　　　　| 10%```
   のように進捗状況をパーセントでも表示してくれるのでわかりやすい。
1. `for`ループで繰り返し計算を行う
1. ループを一周するたびに、progress barを現在の`i`の値の位置まで伸ばす
Pythonで自分にLINEを送る

# ※LINE Notifyは2025年3月末をもってサービスを終了するとのことです。
LINEをNotifyを使って送るスクリプトを作成したので追加

```ruby:Python
def send_line(token,msg):
        print("LINEに送信中")
        url = "https://notify-api.line.me/api/notify"
        headers = {"Authorization" : "Bearer "+ token}
        payload = {"message" :  msg}
        r = requests.post(url, headers = headers, params=payload)
```
DeepMindがどんなゲームでもプレイできるエージェントを開発

本記事は[Fastcompany](https://www.fastcompany.com/91058360/deepmind-new-ai-agent-video-games)により翻訳されたものです。
![QQ20240315181441.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2298092/17151b82-c9f8-ef48-9012-e58cc3ec84fa.png)

研究者たちは長年、AIモデルにビデオゲームをプレイさせることで、日常生活で特定のタスクをこなせるように訓練してきました。グーグル傘下のDeepMindは今週、様々な仮想環境をナビゲートする方法を学習できる「ジェネラリスト」AIエージェントをリリースし、AIゲームに関してさらにレベルアップしました。

SIMA（スケーラブル・インストラクタブル・マルチワールド・エージェント）と呼ばれるこのエージェントは、仮想世界の中で自然言語の指示に従ってさまざまなタスクを実行することができます。例えば、資源を採掘する方法、宇宙船を操縦する方法、ヘルメットを作る方法、ビルディングブロックから彫刻を作る方法などを学習し、これらすべてをキーボードとマウスを使ってゲームの中心人物を操作して実行しました。

SIMAを動かすAIシステム（複数のモデルで構成）は、言語を画像に正確にマッピングするように設計されています。ビデオモデルは、エージェントが特定の行動を取った場合に次に何が起こるかを予測するために訓練されました。その後、ゲームに特化した3Dデータでシステムを微調整しました。

最終的には、DeepMindの研究者たちは、現実世界で物事を行う方法を見つけ出すことができるAIモデルやエージェントを構築するためのステップを踏みたいと考えています。DeepMindのリサーチ・エンジニアであるフレデリック・ベッセは火曜日、記者団との電話会見で、「エージェントが見たこともないような環境下での行動こそが、我々が本当に興味を持っている領域なのです」と語りました。

SIMAにはまだまだやるべきことがあります。ベッセ氏によると、ハロー・ゲームズの『No Man's Sky』をプレイした場合、人間の能力の60％程度しか発揮できませんでしたという。「エージェントが失敗するときによく見られるのは、彼らの行動は多くの場合意図的に見えますが、必要な行動を開始できないということです」とベッセ氏は言います。

ディープマインドのリサーチエンジニアでSIMAプロジェクトのリーダーであるティム・ハーレイは、火曜日の電話会議で、この技術の応用について話すのは時期尚早だと強調しました。「我々はまだ、これがどのように機能するかを理解しようとしています...どのように真に一般的なエージェントを作成できるか…」

以上、DeepMindがどんなゲームでもプレイできるエージェントを開発したという情報を伝えました。ほかのAIトレンドに関心を持つ方に、ポートレート写真をアップロードすると、[AI 似顔絵](https://vanceai.com/ja/toongineer-cartoonizer/)を自動的に生成してくれるToongineer、最高な[ぼかし除去 サイト](https://vanceai.com/ja/sharpen-ai/)を目標に働いているVanceAI画像鮮明化という二つのAI製品を試すのをお勧めします。