OmniAICreator/Qiita-1.07M huggingface dataset:
AWS ALB のざっくり説明資料

アプリケーション畑に軸足のあるフルスタックエンジニアでシステムアーキテクトの私が、社内のオンプレ経験の長いインフラ屋さんに ALB を説明した時の図です。詳細には、違います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2210265/3012cdc6-1928-9c86-795c-c2e862a0f9d6.png)

ALB がどこにあるかを気にされていたので、VPC にどかんとあるイメージを先ず伝えました。次に各パブリックサブネットに NIC があるイメージと伝えました。その NIC は、それぞれ最大で 8 個まで増えるので、IP が各パブリックサブネットで最低 8 個は必要と伝えました。

ALB のアクセスログは、VPC の ALB からではなく、AWS が管理する ALB の元締めアカウントから S3 バケットへ送られるイメージと伝えました。バケットポリシーの設定が必要であることを伝えるための説明です。

WAF との関係や TSL 証明書の配置などについても説明しましたが、図が複雑になるので、取り敢えずはここまで。
Palworld(パルワールド)をM1Macでプレイする方法

## PalworldをMacでやりたい！！！

発売されましたねPalworld!
![スクリーンショット 2024-01-22 1.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/96f541a9-420e-56b7-f229-c0a274a10055.png)
ポケモンとマイクラとゼルダのいいとこだけを全部足していい感じに調節した感じのゲームで、怪しさ満点ですが、これがなんの！面白すぎる！！


さっきTwitterで見たら、Steamでの同時接続数が11万人で歴代1位
ダウンロードも400万突破と化け物ゲームです。


しかし、Steamでプレイしようとすると、Windowsのみ対応とのことで、
Macしか持っていない私がプレイできるまでの試行錯誤を書いていきます。

調べても全然載ってないんだもの！！

私の環境は、
MacOSはVentura13.2.1
メモリは24GBを使用しています

（Xboxにも対応しているとのこと、MacでもXboxのサブスクでもプレイできるようです！
今のところクロスプレイは非対応なので、注意！）

## 先に結論から
結論から言いますと、、、
crossoverをしようすることで、プレイすることができました。

公式サイト
https://www.codeweavers.com/crossover/

これを使うと、Mac上でwindowsのレイヤーを作ります。
ここからWindows用のSteamをinstallして、crossover上でSteamを起動、
自分のアカウントにログインして、ゲームを購入したり、プレイできます！

![スクリーンショット 2024-01-22 1.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/4e2ef4ec-40e7-f879-4482-86bded60a05f.png)
こんな感じ

無料トライアルが14日間あるので、一旦はそれを使ってみています。
有料を使うには年間74ドルかかるので、検討中である。


## まずはParallelsから試してみた
まずはwindowsの仮想デスクトップのど定番はParallelsでしょう！
ということでやってみましたが、うまくいかず、、、

windows用のSteamは立ち上がり、パルワールドの購入、インストールまでは完了したのですが、
ゲームを起動すると、Unreal Engineのエラーが表示されて、起動できず！
![スクリーンショット 2024-01-22 1.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/8fa0d46e-c6ef-b768-e1c3-f1ac338c69d5.png)
しかし、windows専用ゲームのホロキュアはプレイできたので、パルワールドはまだ対応していない、、ということかもしれない

悔しい、、、！

## そしてcrossoverを試してみた
次にcrossoverを試したわけですが、その理由はパルワールドのSteamのスレッド内で外国人の方がcrossoverでプレイできたよ！と書き込みをしていたので、試してみたわけです。
海外ニキありがとう！！

https://www.codeweavers.com/store
このリンクから１４日間のトライアルを選択、
![スクリーンショット 2024-01-22 1.51.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/e94707d2-6eec-50c1-5bf9-27534e3bc54e.png)

起動したら、steamを検索して、インストールして起動。
![スクリーンショット 2024-01-22 2.10.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/26061aa6-5114-5289-71bf-51d7d3c73724.png)


パルワールドを起動して（私はParallelsで先に購入していたので購入がまだの場合はここで購入）ゲーム開始です！！！
![スクリーンショット 2024-01-22 1.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3357049/96f541a9-420e-56b7-f229-c0a274a10055.png)

## 問題１　キーボードが反応しない
十字キー、escなどの一部を除き、キーボードが反応しません。
他の記事にキーボード設定をUSEngにすると改善する、とありましたが、私の場合は改善されず、、、
キーボード操作は諦めました。

## 問題２　ゲームパッドが反応したりしなかったり
私はPS4のデュアルショックをしようしていましたが、
操作できたりできなかったりして、苦戦しました。

これもキーボードの言語設定が関係あるのか？
原因は不明ですが、
１　コントローラ接続せずに、Steamを起動する
２　ゲームを起動する
３　ゲームの起動後にコントローラを接続する
４　反応しなかったら、ペアリングを解除して、再接続

これで私の場合はデュアルショックで操作することができました。

再現性があるかは今のところ不明。
明日も接続に苦戦するかも、、、？

## 問題３　グラフィックがカクつく
これはなかなか辛いが、Macだから仕方ないのかもしれない、、
私は2022年製のM2Macを使用していますので、比較的スペックは悪くないのかな、、？と思いますが、
それでも画質設定を最低に落としてどうにかプレイすることができるレベルでした。

ここばかりは、どうにもならないとは思いますが、
他の記事にて、 M1PROM2PROであればFPSもプレイできたとのことでしたので、
ハイスペックのMACであればぬるぬるでプレイできるかもしれませんね！

## まとめ
crossoverを使用することで、MACでプレイはすることができますが、
上記の問題点もありますので、快適プレイとはいきませんでした、、、

素直に、windowsマシンを買うか、
Xboxを購入するのが、いいのかもしれませんね！！

パルワールドはやる価値あるので、是非とも興味がある人がいたら参考にしてみてください！

制作者のnoteもめちゃ面白かったので、共有しておきます
https://note.com/pocketpair/n/n54f674cccc40

何か少しでも参考になれば、、、！
もっといい方法があればコメントしてくださいませ！！


おわり。
micro:bitでローラ式距離計を作成してみる

仕事でざっくりとした距離が測れて
5m間隔等の一定間隔が測れる距離計が入用になったのでmicro:bitで作ってみました
（センサーとブザーがオンボードの安いマイコンなら何でもよかった）
micro:bitそのものをあまり分かっていないので　今回はブロックでの作成です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/7b30164c-afad-e91a-ac1c-5065085345b6.png)

距離の測定は　別途用意した車輪に磁石をつけて磁石が磁気センサーを横切る回数をカウントすることにしました
## 磁気カウンター
まずはシンプルに磁力が一定値を超えた回数を記録するカウンター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/b60ef745-9ba3-11cb-d54f-3ee7a4c49d55.png)
「ずっと」のサイクルは20msごとに処理が実行されるようで
磁気が強い状態が継続する場合にはカウントアップしないようにフラグを入れたのだけれど・・・

どうやら磁力に変化がない状態でもセンサーの値が小さくなることがある様子で
予期しないタイミングでカウントアップされる症状が発生しました
なので　１サイクルだけ基準を下回っただけではカウント対象にならないようにフラグの使い方を調整
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/6067f151-fd9d-e8e9-47d6-65fb2f576db3.png)
とりあえず誤作動はなくなりました

# 距離カウンター
磁気でワンカウントされる度に　外周の距離をカウントするようにして
５ｍを超える毎にブザーを鳴らすコードを入れてみました

距離もLED表示したいものの
通常　Micro:bit は複数桁の数字はスクロール表示するので
２桁の数字をLED表示する　WhaleySansFontを導入してメートル単位での表示にしてみました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/de8dcf82-8373-b871-1608-67d5df6d8a7b.png)
Python

``` py:microbit_magnet_mater
Counter = 0
CountFlag = 0
StepLength = 11.5

def on_forever():
    global Counter, CountFlag
    if 400 < abs(input.magnetic_force(Dimension.X)):
        if CountFlag == 0:
            Counter += 1
            if StepLength > Counter * StepLength % 500:
                music.play(music.string_playable("C C A - - - - - ", 400),
                    music.PlaybackMode.IN_BACKGROUND)
        CountFlag = 2
    else:
        if CountFlag == 2:
            CountFlag = 1
        else:
            CountFlag = 0
    whaleysans.show_number(int(Counter * StepLength / 100))
basic.forever(on_forever)

```
【Unity】すぐにできるメタリックなオブジェクトの作り方

# 背景
Blenderで作成しUnityにインポートしたオブジェクトをメタリックな見た目にしたい。
本記事はマテリアルを作成し、オブジェクトにアタッチする手順を紹介する。

# 対象の読者
- 記事のタイトルに興味を持った方
- Unityのオブジェクトをメタリックな色味にしたい方
- メタリックなマテリアルを作りたい方

# 結論
今回はマテリアルの`Meatallic`、`Smoothness`をどちらも0.9に設定しています。
メタリック感は好みの度合いに調整できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/2b4a9ed8-8a25-8f98-7875-4083b0199ae8.png)


# ①オブジェクトを準備
Unityでオブジェクトを準備します。

GameObject > 3D Object > Sphere で球体のオブジェクトを準備する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/741c2c18-9c8a-e36a-cacc-acc1afc54074.png)

球体のオブジェクトを準備できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/1b0bd38d-e4b7-4a0e-0eb0-72576f76db88.png)

:::note info
##### 補足

Blenderで作成したオブジェクトをUnityにインポートしたい場合は、
以下の記事に記載しています。
:::

https://qiita.com/enumura1/items/4efd865137091d85c923



# ②マテリアルの作成
### ◆マテリアルの作成＋アタッチ

Unityの画面において、Assetsのタブ内を右クリック > Create > Material をクリックし、マテリアルを作成。
作成したマテリアルはオブジェクトにドラッグ＆ドロップしてアタッチする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/c78adf8c-0ca9-09ac-dbe6-747def855b09.png)

### ◆色の変更

作成したマテリアルをクリックし、インスペクターを表示。
Albedoから好きな色に変更。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/64b6971e-e481-96dc-e671-3a739d1ecb6f.png)


### ◆メタリック感を出してみる

インスペクター内のMeatallic、Smoothnessを好みの度合いに調整します。
今回はどちらも0.9に設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/2b4a9ed8-8a25-8f98-7875-4083b0199ae8.png)

### ◆マテリアルをアタッチ

作成したこのマテリアルを以下２つのオブジェクトにアタッチしてみました。
テカっててメタリック感がでてると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/c75d72b5-61fb-df95-70a6-90f812bb6aa7.png)
JavaScript とは

## JavaScriptとは？
Webページ上に動きのある表現を付けたり、入力フォームなどで選択候補を動的に表示させたりできるプログラミング言語のひとつです。
HTML,CSSだけでは表現できない動きをつけることで、ページを見ているユーザーがサイトをより魅力的に感じることが期待できます。
また、Webサイト開発の世界標準言語であるため、多くの現場で必要とされています。

:::note warn  
「Java」と名称は似ていますが、まったく異なる言語です。  
:::


## まずはじめに
外部ファイルとして読み込む場合、scriptタグは、HTMLコードのbodyタグ内に書きます。

```:index.html
<body>
  <script src="hello.js"></script>
</body>
```
jsファイルを作成し、コードを書いていきます。
JavaScriptは、console.log~で出力することができます。
```:hello.js
console.log('文字列');
```

出力結果を確認する方法は以下の通りです。
Webブラウザでindex.htmlを開き、右クリックで検証を開く。　　
検証内のConsoleで出力結果を確認できます。

## 基本操作
#### 1.変数
```:hello.js
let 変数名 = 'Hello World';
console.log(変数名);
```
letは値の再代入が可能な変数。
他にも、const(再代入できない変数)、var(最近ではあまり使われていません)などがあります。

:::note info
変数は一度決めた値（中身）を変更できます。
:::

#### 2.定数
```:hello.js
const 変数名 = 'Hello World';
console.log(定数名);
```
:::note info
定数は、一度決めた値（中身）を変更することはできません。
:::
CloudflareのSSL設定をサブドメインで分ける方法

[Cloudflareとオリジン間のSSL/TLS設定（Off、Flexible、Full、Full (strict)）](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/)は、「ルートドメインごとに1つ」というイメージが強い（気がする。実際自分は今までそうでした）ルートドメインのSSL/TLSメニューに代表的にこれが表示されるので、そうだと思い込んでいた。

このため、サブドメインに複数の種類のオリジンを抱えている場合、全てのオリジンでSSL/TLS設定を同じにすることが義務付けられている印象があって、「このオリジンだけはFlexibleじゃないと成り立たないんだよな…」というようなケースに対応できないと思い込んでいた（そういう場合は新たにルートドメインを1個別に買うしかないと思ってた）

が、そういうわけでもない。よく探せば普通にあったんだが、「Rules＞[Page Rules](https://developers.cloudflare.com/rules/page-rules/reference/settings/)」において、対象のURLパターンを入力の上、「Pick a Setting (required)」から「SSL」を選択し、ルートドメインの設定とは異なる設定を選択することで、そのURLパターンだけはSSL/TLS設定を上記の設定から別の設定に上書きできる。以下の例だと、ルートドメインにおける基本的な設定は「Full」だが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/39870754-e287-54e0-1497-8dedbd65be33.png)

Page RuleでURLを指定して「Flexible」にすると、このURLの`/*`配下のアクセスではFlexibleで動作するように設定できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/8a435171-f55e-4552-10bb-ef577a223be5.png)

実際、これで、あるルートドメインにおいて、Full＋Flexibleの異なるオリジンの運用が出来ている。

---

ただ、[Page Ruleには設定できる数に制限がある](https://developers.cloudflare.com/rules/page-rules/)（例えばFree Planだと最大で3つまでしか設定できない）。Page Ruleには他にも色々有用なものがあり、SSL設定だけで1つ消費するのも勿体ない気もしてくる。この制限はお金払うと追加できるのだが（Page Rulesの最初の画面に追加購入のためのリンクがご丁寧に設けられている）、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392942/1824d31f-f4e4-7dc4-7ef1-d9a350403e61.png)

ってかんじで最安でも5ルールの追加が必要になり、かつ追加した場合は毎月＋$5の追加費用が発生する。そう考えると年間で1000円程度のドメインを新たに買ったほうが安い気もしてくる。まあ運用次第なので一概には言えないが。

とりあえずSSL/TLS設定はドメイン事じゃなくても設定できるんだよというメモだった。
DOMの基本をまとめる

# DOMとは
DOM(Document Object Model)は、HTML/XMLなどのマークアップ言語で書かれたドキュメントにアクセスするための標準的なしくみで、JavaScriptに限らず、現在よく利用されている言語のほとんどがサポートしている（言語によって細かな記法は異なる）。

# 基本知識
* 要素ノードの取得
* イベントドリブンモデル

上の二つは開発を進めるうえで欠かせない知識となる。書き方は変わっても考え方は同じ。以下でその方法をまとめる。

## 要素ノードの取得
### getElementByIdメソッド
```js
document.getElementById(id)
```
id値をキーに要素を取得。
### querySelector(selector)メソッド
```js
document.querySelector(selector)
```
selector式で要素を取得。
#### selector式とは
もともとはCSSで利用されていた記法で、スタイルを適用する対象を特定するための仕組み。
以下のような指定の仕方がある。
| 構文 | 概要 |
|:----------|:-----------|
| *     | すべての要素を取得     |
| #id     | 指定したIDの要素を取得      | 
| .class       | 指定したクラス名の要素を取得       | 
| element        | 指定したタグ名の要素を取得          | 
| selector1, selector2, selectorX      | いずれかのセレクターに合致する要素をすべて取得       | 
| aligned    | aligned     |

## イベントドリブンモデル
* ボタンがクリックされた。
* マウスポインターが文字列の上に乗った（外れた）。
* テキストボックスの内容が変更された。

ブラウザ上でなどのイベントが起きた時にイベントに応じて実行するコードを記述できる。このプログラミングモデルのことをイベントドリブンモデルという。
### addEventListnerメソッド
```js
elem.addEventListener(type, listener, opts)
// elem → 要素オブジェクト
// type → イベントの種類
// listener → イベントの発生時に実行するコード
// opts → イベントオプション（falseが標準）
```
これを用いることで、イベントが起きた時に画像を表示したり、文字の色を変えたり、様々なことができる。

# まとめ
DOMを勉強することによってプログラミングの景色が変わってきたようで楽しい。これからも学びを深めていきたい。
StreamDiffusionをローカル環境にインストールする【Windows】

## パソコン環境
- Windows 11 Pro
- AMD Ryzen 7 5700X 8-Core：32GB
- NVIDIA GeForce RTX 3060 Ti：8GB DDR6

## 事前準備
- [Git](https://git-scm.com/download/win) のインストール
-  [Python 3.10.11](https://www.python.org/downloads/release/python-31011/) のインストール
-  [CUDA 12.1](https://developer.nvidia.com/cuda-12-1-0-download-archive) のインストール

:::details インストール出来たかの確認手順
```powershell
git -v
```
![](https://storage.googleapis.com/zenn-user-upload/a1aa89ba0349-20240109.png)

```powershell
python -V
```
![](https://storage.googleapis.com/zenn-user-upload/78a1a612c722-20240109.png)

```powershell
nvcc -V
```
![](https://storage.googleapis.com/zenn-user-upload/cd7b3455153b-20240109.png)
:::

## [StreamDiffusion](https://github.com/cumulo-autumn/StreamDiffusion)のインストール
1. 公式の"README.md"通りに進める。
    - GitHubからStreamDiffusionをcloneしてくる。（[git](https://git-scm.com/download/win)が必要）
    - StreamDiffusionのフォルダに移動
    - Pythonの仮想環境を作成
    - Pythonの仮想環境をactivate
    ![](https://storage.googleapis.com/zenn-user-upload/f6d36581a042-20240109.png)

    :::note info
    エラーが出ない場合は、ステップ 3. に進む
        :::

2. [実行ポリシーを変更](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_execution_policies)して、Python仮想環境をactivateする。

    ```powershell
    Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope CurrentUser
    .\.venv\Scripts\activate
    ```
    ![](https://storage.googleapis.com/zenn-user-upload/f0103649f199-20240109.png)
    
    :::note info
    RあるいはAを押してスクリプトの実行を許可してください。
        :::
3. pipを更新して、依存環境をインストール。
    ```powershell
    python.exe -m pip install --upgrade pip
    pip3 install torch==2.1.0 torchvision==0.16.0 xformers --index-url https://download.pytorch.org/whl/cu121
    ```

4. StreamDiffusionをインストール。
    ```powershell
    pip install git+https://github.com/cumulo-autumn/StreamDiffusion.git@main#egg=streamdiffusion[tensorrt]
    ```

## デモの実行(realtime-txt2img)
### 事前準備

- [Node.js](https://nodejs.org/en/download)のインストール
- [pnpm](https://pnpm.io/ja/installation)のインストール

    ```powershell
    node -v
    pnpm -v
    ```
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665667/bca0798a-d8a1-cbab-5c08-963ae8f5e1cd.png)

### デモの実行(realtime-txt2img)
 [README](https://github.com/cumulo-autumn/StreamDiffusion/tree/main/demo/realtime-txt2img)通りに実行
```powershell
pip install -r requirements.txt
cd frontend
pnpm i
pnpm run build
cd ..
python main.py
```
**↓実際のデモの画像**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3665667/cec1a3d2-7329-8f9b-d494-450152b48dde.png)
pandas df の基本操作

### サンプルデータの作成
```python
import pandas as pd

data = {
    "Name": ["user1", "user2", "user3", "user1", "user2", "user1"],
    "Reserve_Data": ["1/1/2024", "2/1/2024", "3/1/2024", "4/1/2024", "5/1/2024", "6/1/2024"],
    "Money": ["1000", "12000", "36000","400", "26","403330"],
}

df = pd.DataFrame(data, columns=["Name", "Reserve_Data", "Money"])
df
    Name Reserve_Data   Money
0  user1     1/1/2024    1000
1  user2     2/1/2024   12000
2  user3     3/1/2024   36000
3  user1     4/1/2024     400
4  user2     5/1/2024      26
5  user1     6/1/2024  403330
```

### dfの単独列をリストで取得する
```python
name_list = df["Name"].tolist()
print(name_list)
['user1', 'user2', 'user3', 'user1', 'user2', 'user1']
```


### dfから特定の値を持つ行を抽出する
```python
#１つの値との一致
print(df[df['Name'] == 'user1'])
    Name Reserve_Data   Money
0  user1     1/1/2024    1000
3  user1     4/1/2024     400
5  user1     6/1/2024  403330

#複数の値との一致 参考：https://hk29.hatenablog.jp/entry/2021/07/16/235822
target_list = ["user1","user3"]
df2 = df.query('Name in @target_list')
print(df2)
    Name Reserve_Data   Money
0  user1     1/1/2024    1000
2  user3     3/1/2024   36000
3  user1     4/1/2024     400
5  user1     6/1/2024  403330
```

### 行の並び替え
```python
print(df.sort_values('Name'))
    Name Reserve_Data   Money
0  user1     1/1/2024    1000
3  user1     4/1/2024     400
5  user1     6/1/2024  403330
1  user2     2/1/2024   12000
4  user2     5/1/2024      26
2  user3     3/1/2024   36000

print(df2.sort_values('Name'))
    Name Reserve_Data   Money
0  user1     1/1/2024    1000
3  user1     4/1/2024     400
5  user1     6/1/2024  403330
2  user3     3/1/2024   36000
```
WEBからAPKをダウンロードすると拡張子が.zipになる問題

APKをウェブサーバーにアップロードして、そこからダウンロードすると何故かZIPファイルになることがある。

色々試した結果、APKとしてダウンロードする方法をメモっときます。

- WEBサーバーのmimeにapkを追加する(追加方法はhttpdによって違うので自分の使っているサーバーに合わせた設定をしてください)
	```
	application/vnd.android.package-archive .apk
	```

- ダウンロードリンクに?dl=1を追加する
	```
	<a href="app.apk?dl=1">ダウンロード</a>
	```

もしかすると、リンクパラメータの方だけでも行けるかもしれないですが
念の為、mimeの方も書いてあります。
Web技術の基本

# はじめに
これからエンジニアとして学んでいくうえで基本となる技術をまとめてみました。

# 1. Webとは

**以下のようなことができるサービス**
* インターネットで調べたいことを探す
* 自分の文書、画像、動画などを世界中の人々と共有する

Web上の文書(Webページ)は **ハイパーテキスト** と言われる言語で構成されている。
私たちがWebへアクセスする時は一般的にWebブラウザを利用します。Webブラウザに表示されるWebページ内の **ハイパーリンク** をクリックすることで、次々と別のWebページに移動することができます。

# 2.Webのさまざまな要素
### Webサイト
１つのドメインにある複数のWebページの集まり
### ユーザーインターフェイス
コンピューターの機能とユーザのやり取りの橋渡しをする機能
　例えば、ハイパーテキストで作られたメールの操作画面に対してユーザーが行った操作を、Webサーバーがユーザーの代わりにメールサーバーに伝え、メールの操作を行う。
 ### プログラム用API（アプリケーションインターフェイス）
 ソフトウェア同士のやり取りを橋渡しする機能
 　例えば天気予報アプリだと、アプリが送信した地域情報をプログラム用APIの役割を持つWebサーバーが受け取り、Webサーバーは受け取った地域情報に対応する天気予報のデータをアプリに返すというような使い方。
# 3.HTMLとWebブラウザ
### HTML
ハイパーテキストを記述するための言語
ハイパーリンクは、タグと呼ばれるマークによって表現する。
### Webブラウザ
ハイパーテキストを解釈して人間が読みやすいものに作り変えて表示してくれるやつ。
* chrome
* Internet Explorer

# 4.WebサーバーとHTTP
### Webサーバーとは
Webブラウザからコンテンツの要求を受け取り、必要なコンテンツをネットワークを通してWebブラウザに送信する役割を持つ。コンテンツはWebサーバーに配信されることで「Webページ」とも呼ばれる。
### HTTPとは
WebブラウザとWebサーバーでのハイパーテキスト(コンテンツ)のやりとりの仕組みを世界共通のルールとして定めたもの。(どのWebサーバーやWebブラウザを使っていてもHTTPという共通のルールでやりとりできる！)
<br>
HTTPでは以下のようなことが定義されている
・ ハイパーテキストの要求手順
・ ハイパーテキストの送信手順
・ 要求されたコンテンツを持っていなかった場合の応答方法
・ Webサイトが移転したことをWebブラウザに伝える方法 など

# 5.Webページが表示されるまでの流れ
### URLを使ってWebページにアクセス
**URLに含まれているものは以下の３つ**
* どのやり取りの手順で （http/https）
* どのWebサーバーに  （www.~.jp）
* 何のコンテンツを      （index.html）

1.WebブラウザがHTMLの内容を解釈し、タグなどから人間が見やすい形に整形し表示
2.画像など他のファイルが必要になった場合、そのファイルの転送をWebサーバーに要求し、表示画面にはめ込む
3.以上の流れを繰り返し、必要な情報が揃えばWebページを表示する

# 6.静的ページと動的ページ
### 静的ページ
何度アクセスしても毎回同じものが表示されるWebページ
　ex) 企業や団体の紹介ページ
### 動的ページ
アクセスした時の状況に応じて異なる内容が表示されるWebページ
 　ex) 検索サイトの結果表示
# 7.動的ページの仕組み
### CGI (Common Gateway Interface)
WebサーバーがWebブラウザからの要求に応じてプログラムを起動させるための仕組み

以下のような流れで動的ページを返す
1. WebブラウザはCGIが用意された場所を示すURLにアクセス
2. WebサーバーはCGIによってプログラムを起動
3. プログラムは送られきたデータや自身が持っているデータからHTMLを生成し、Webブラウザに送信

### サーバーサイド・スクリプト
HTMLに埋め込まれ、Webブラウザによって読み込まれる際に実行されるもの。基本的にどんなプログラミング言語でもいい

# 8.Webの標準化
Web技術は日々進歩し様々な機能拡張や新技術の開発が行われています。しかし、機能拡張を開発者が独自で行ってしまうと、どのWebブラウザでも同じようにWebページが表示されないといった事態が起きてしまいます。
そこで世界共通の規格をきめようということで　**標準化** という作業が行われます。

# 9.Webの設計思想
### RESTful
WebシステムはRESTfulであることが理想であると言われます。
RESTfulとはRESTという4つの原則にしたがって設計されたシステムのことです。

RESTの4つの原則は以下の通りです。
- __統一インターフェイス__
    - はじめに定義された規格（例えば、HTTPで通信するといったこと）で情報をやりとりする

- __アドレス可能性__
    - すべての情報が一意（オンリーワンのものという意味）なURLで示される

- __接続性__
    - やり取りされる情報にはリンクを含めることができる
- __ステートレス性__
    -やり取りは一回毎に完結し、前のやり取りの結果に影響を受けない

このRESTの原則を遵守することによって円滑な情報のやり取りが実現するということです。
Ninjaが爆速でビルド出来るらしいのでMakeと比較してみた

# はじめに
最近になって、[Ninja](https://ninja-build.org/)というビルドシステムがかなり高速らしいという話を耳にしたため、どれくらいビルドが高速になるのかMakeと比較して試してみました。

今回はcmakeのソースに対して、MakeとNinjaそれぞれでビルドを実行して処理時間を計測したいと思います。

https://github.com/Kitware/CMake

また、ビルド時に使用される```Makefile```と```build.ninja```はそれぞれ```CMakeLists.txt```から生成したものを使用します。（ややこしいですが、cmakeを使ってcmakeのソースをビルドします。）

# 環境準備
## 実行環境について
実行環境はdockerで用意しました。
dockerfileを作成するのが面倒だったので、Ubuntu 22.04のイメージをベースに、必要なパッケージは後から```apt install```で追加していきます。

コンテナの作成手順はこの記事では割愛します。

## 必要なパッケージのインストール
今回のビルドに必要なパッケージをインストールしていきます。

```bash:パッケージのインストール
apt install -y gcc make ninja cmake wget build-essential checkinstall zlib1g-dev libssl-dev
```

## cmakeソースの用意
続いて、今回ビルドを試すcmakeのソースをGithubから取得します。
```bash:cmakeソースの取得
wget https://github.com/Kitware/CMake/releases/download/v3.23.3/cmake-3.23.3.tar.gz
tar -zxvf cmake-3.23.3.tar.gz
cd cmake-3.23.3
```

# ビルド実行
MakeとNinjaそれぞれを使用してビルドを実行します。
また、Makeについては並列実行した場合の速度も測定したいため、```-j```オプションを付与したケースでも測定します。

今回設定する並列実行数は、利用できるプロセッサの最大数で設定したいと思います。
利用可能なプロセッサ数は、```nproc```コマンドを実行することで確認できます。
今回の環境では最大16個のプロセッサが利用できるため、並列実行数は16で設定してビルドを実施します。
```bash:利用可能なプロセッサ数の確認
root@ubuntu-work:/# nproc
16
```

以下のコマンドでそれぞれビルドを実行します。
フルビルドでの計測を想定しているため、実行前に```build```ディレクトリが作成されていないことを確認してください。

```bash:Makeの場合
mkdir -p build
cmake -S . -B ./build && cd build && make
```

```bash:Make（-jオプション付与）の場合
mkdir -p build
cmake -S . -B ./build && cd build && make -j16
```

```bash:Ninjaの場合
mkdir -p build
cmake -S . -B ./build -G Ninja && cd build && ninja
```

# 実行結果
実行結果は下記の通りになりました。
| ビルド方法 | 実行時間 |
| --- | --- |
| make | 40m 42s | 
| make -j16 | 8m 14s | 
| Ninja | 7m 1s |

他の記事ではNinjaの方が5~10倍ほど速くなったという意見もありましたが、Makeでも並列実行数をうまく設定してやれば、Ninjaのビルド速度との差は割と小さくなりました。

とはいえ、Ninjaの方が1分ほどビルド時間は短縮できているので、高速であることは間違いないと思います。

# 差分ビルドも試してみる
とりあえずフルビルドでの実行時間を計測してみましたが、差分ビルドでの性能も気になるので測定してみました。
フルビルド実行後に、一部のソースファイルに簡単な追記を加えたうえで再度ビルドを実行しました。

（Makeの並列実行無しの場合は時間かかりそうだったので、サボって並列実行オプション付与の場合のみ測定しましたが悪しからず。）

| ビルド方法 | 実行時間 |
| --- | --- |
| make -j16 | 2m 3s | 
| Ninja | 1m 39s |

差分ビルドでもNinjaの方が20秒ほど短縮できているため、この結果からもNinjaの速さが見て取れます。

# おわりに
前評判を色々見てからNinjaのビルドを実行してみましたが、思ってたよりもビルドが速くなるというわけでは無かったなというのが正直な感想です。

今回は、ビルドを試したプロジェクトも1つのみですし、実行環境についてもコンテナ環境でしか検証してないので、もっと大きなプロジェクトだったりもっとプロセッサ数が多い実行環境だったりすると、結果も色々変わってくるかもしれません。

ただ、cmakeが利用できる環境であれば、MakeからNinjaへの切り替えは簡単なうえ、生成される```build.ninja```ファイルも```Makefile```よりも読みやすくなるよう考慮されているようなので、MakeからNinjaへ乗り換えるのはかなりアリだと思います。

# 参考
* https://ninja-build.org/
* https://zenn.dev/suudai/articles/8b484ac39fde38
* https://yuyubu-sub.hateblo.jp/entry/2019/11/11/cmake-option
* https://qiita.com/shohirose/items/a1e2fcb1ea25fb4e7644
bootstrapのダウンロードの仕方

## gemをインストール
gemfileに以下を記載
```
gem 'bootstrap', '~> 5.3.0'
```

bundle installする（コンテナ内で行う場合）
```
docker compose run web bundle install
```
## 共通ファイル作成
flashメッセージは複数のビューファイルで使うので、部分テンプレートにしておく。
views/shared/_flash.html.erb
```
<% flash.each do |message_type, message| %>
  <div class="alert alert-<%= message_type %>">
    <%= message %>
  </div>
<% end %>
```

## application.html.erbで読み込みが出来るようにする
```
<%= render 'shared/flash_message' %>
    <%= yield %>
```

## bootstrap対応して色をつける
flashはデフォルトで notice と alert の二種類のキーしか設定できないので、設定を追加する。
application_controller.rb
```
add_flash_types :success, :info, :warning, :danger
```

あとはこちらを参照
https://pikawaka.com/rails/flash
【Nuxt3】入力フォームを作る②

# はじめに
Nuxtで入力フォームを作る第二回。
現状のコードは前回の記事を見てください↓

https://qiita.com/sakuc47/items/68a5c9e7a476455b8293

# やりたいこと
- はじめは入力フォーム（グレーの部分）は非表示
- 「追加入力項目を表示する」にチェックを入れると入力フォームが表示されるようにする
- input部分をクリックすると、「お名前（姓）※必須」が入力部分上に移動するアニメーションをつける
- 上記のアニメーション時に「お名前（姓）※必須」の文字サイズが小さくなる

![スクリーンショット 2024-01-09 1.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/a9357c0a-d454-d023-4e48-a967af7fee51.png)

# チェックボックスにチェックが入ったら入力フォームを表示する

## 1.チェックが入っているかどうかを判定して、HTML側の表示を変える

▼フォーム入力バインディング

https://ja.vuejs.org/guide/essentials/forms

v-modelを使うことは何となくわかるけれど、言語化するのが難しい・・

https://qiita.com/ashketcham/items/03f139b010c5ec6dcd63

> 「dataを更新すれば HTML が更新されて、 HTML を更新すれば data が更新される」ようにしてくれる機能

v-modelはv-onとv-bindをまとめて一行で書くためのシンタックスシュガー（プログラミング構文の省略した書き方）。

今回であれば、チェックが入るor外れる　というデータを取得して、HTML側の表示を変えたい。
わかりやすいように、マスタッシュ構文を用いてチェックボックスの状態を表示する。

``` vue
<input type="checkbox" v-model="isChecked">
<label for="checkbox1">追加入力項目を表示する {{ isChecked }}</label>
```

``` vue
<script setup>
// `isChecked`の状態を初期化
// はじめはチェックが入っていない状態にする
let isChecked = ref(false);
</script>
```

チェックが入るとHTML側が「true」または「false」の表示になる。（マスタッシュ構文のところ）

![スクリーンショット 2024-01-21 23.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/44c8e753-f25c-3ab7-4bcb-dbc5bb22431c.png)

## 2.isCheckedがtrueの時にフォーム部分を表示、falseの時は非表示にする
v-ifを使うと表示・非表示を切り替えることができる。
`v-if="isChecked"`でisCheckedがtrueなら表示、falseなら非表示になる。
```vue
<div id="formArea" class="p-formArea" v-if="isChecked">
```
![Something went wrong]()


## 補足：v-showとv-ifの違い
表示にかかわるvディレクティブに`v-show`があるが、`v-if`と何が違うのか？

▼v-if="条件"
条件の真偽によって表示非表示が切り替えられる。

非表示の時、DOMから要素自体が消える。（真偽が変わるたびにDOMが操作されてる）

![スクリーンショット 2024-01-22 0.11.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/b5749f13-f31f-6133-7936-c80c272d5011.png)

▼v-show="条件"
v-ifと同様に、条件の真偽によって表示非表示が切り替えられる。
ただしv-ifと違って、偽であってもDOM上に要素自体は存在していて、`display:none;`（CSSの書き換え）で表示非表示を実現している。

v-elseのように、偽の時に別の表示をさせたい場合などは`v-show="not 条件"`と記述する必要がある。

![スクリーンショット 2024-01-22 0.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/74b732ab-0cbe-9f98-e695-06c5fa5e3b1f.png)

▼どちらを使うべきか
v-ifは初期の記述が簡単だけれど、DOM操作を行うので表示面のコストが高い。
v-showは記述に配慮が必要だけれど、CSSの書き換えで表示非表示を切り替えているため表示面でのコストが低い。

よって、頻繁に表示非表示を変えないならばv-if、頻繁に切り替えたい時はv-showを使用する方が良いよう。

次回はフォームのinput部分をクリックすると、「お名前（姓）※必須」が入力部分上に移動するアニメーションをつける！！

# 参考

https://qiita.com/Yudai_35_/items/681aa3a11026ac6eae68

https://qiita.com/seihmd/items/e4b2dfbdaba423fde6a7

https://qiita.com/ashketcham/items/4851e58a8e57a04a9bf2#%E5%8F%8C%E6%96%B9%E5%90%91%E3%83%87%E3%83%BC%E3%82%BF%E3%83%90%E3%82%A4%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0v-model

https://qiita.com/aqua_ix/items/61eac355f3c24d7676e1



・シンタックスシュガー

https://wa3.i-3-i.info/word15703.html
cargo-competeでinput_interactiveマクロを使いたい

他の方の回答をみていて、`input_interactive`を用いているのを発見したのですが、自分の環境では候補として出なかったため、記事にしました。
そのうち対応されると思いますが、それまでの前提対応です。

各コンテストに対応する`Cargo.toml`の`proconio`のバージョンをあげることで対応できます。

```Cargo.toml
(前略)
[dependencies]
(中略)
proconio = { version = "=0.4.5", features = ["derive"] }
```

以下がマージされれば特段何もしなくても使えるようになりそうです。

https://github.com/qryxip/cargo-compete/pull/208
Q学習　Sarsa　徹底解説!

# はじめに
強化学習における動的計画法、TD学習(Sarsa、Q学習）、モンテカルロ法についての記事です。
# マルコフ決定過程
マルコフ決定過程とはある状態があった時に今の状態や行動だけで次の行動を選ぶことできることを言います。過去の状態や過去からの報酬は気にしないということです。
なので迷路問題などでは右側に壁がある状態があったときにゴール付近でもスタート付近にいてもどちらでも同じ状態だと認識してしまいます。（過去の状態を考慮しないため）
# 動的計画法
最適化の１つで問題をいくつかに分割して行う手法のこと。

# モンテカルロ法
モンテカルロ法はエピソードがすべて終わってから報酬を受け取れる。なのでエピソードが終了してから方策や報酬の更新が行われる。

# TD学習
目標と現在の状態の価値のずれを修正することによって価値関数を改善することを指す。この現在のずれのことをTD誤差といいます。
TD学習はモンテカルロ法や動的計画法のようにエピソードが終了せずとも方策や報酬を受け取ることができる。
具体的にはSarsaとQ学習がある。

# Sarsa
```math
Q(s_t,A_t)\leftarrow Q(S_t,A_t)+\alpha [R_{t+1}+\gamma Q(S_{t+1},A_{t+1})-Q(S_t,A_t)] 
```
Sarsaは安全な経路を選択していきます。つまり方策オン型の更新式です。行動価値を更新するときはQ学習に比べて行動価値が小さい探索が結果として反映しれやすい。

# Q学習
```math
Q(s_t,A_t)\leftarrow Q(S_t,A_t)+\alpha [R_{t+1}+\gamma max_{\alpha'} Q(S_{t+1},A_{t+1})-Q(S_t,A_t)] 
```
Q学習は方策オフ型の探索を行う。いわゆるmaxなので最短経路を選択します。Sarsaは崖など最短経路上に何かしらの障害物があればそれを避けて通ります。しかしＱ学習はmaxなので最短経路となる場所を選択して行ないます。
ちなみにɤは割引率を表しています。この式をより具体的に説明すると今の価値Ｑは状態Ｓのときに行動Ａを選んだ価値です。そして次の報酬がＲになっています。そこに割引率ɤを掛けた次の価値が最大になるような行動と状態を選ぶことが目標です。TD学習は目標と現在の状態の誤差のTD誤差を最小にするような価値をみつける学習です。なので[]の中身を最小目標に近づけるような学習が必要です。

ちなみにＱ学習は行動を決定する方策と行動価値関数の更新に利用される方策が異なります。
[ROS 2] Jetsonとホストマシンで共通のDockerfileを使うには

# モチベーション

ROS 2 Humbleのように、JetPackで入れられるl4tのベースとなるUbuntuのバージョンでは対応できないバージョンのROS 2を活用する際には、構築済みの環境を使用する方が楽です。一方で、Nvidiaが提供しているSBCのJetsonでは、通常のUbuntuイメージだとGPUがうまく動作しないことがあり、例えば、ホストマシンではubuntu:20.04で動かしていたものは、nvcr.io/nvidia/l4t-baseを使用する必要があります。そのため、Jetsonとホストマシンでは別のイメージをベースとするDockerfileが必要になるので、管理が煩雑になるという問題がありました。本稿では、Dockerfileとイメージをビルドする際のシェルスクリプトを工夫することで、共通のDockerfileで環境構築することを目指します。

# この記事でできること

- 共通のDockerfileを用いてJetsonとホストマシンでほぼ同じDockerイメージを構築できる
- ついでに、コンテナ起動時にGPUの有無をチェックすることで、GPUのないホストマシンでもコンテナを立ち上げられる

# 検証環境

- ホストマシンOS: Ubutnu 24.04LTS
- Jetson: Jetson AGX Xavier(l4t:R35.4.1)

# Dockerfileの書き換え

作成したDockerfileの先頭部分を以下に示します。

```Dockerfile
ARG TARGET="general"

FROM ros:humble AS image_general
ENV NVIDIA_VISIBLE_DEVICES ${NVIDIA_VISIBLE_DEVICES:-all}
ENV NVIDIA_DRIVER_CAPABILITIES ${NVIDIA_DRIVER_CAPABILITIES:+$NVIDIA_DRIVER_CAPABILITIES,}graphics

# check your jetpack version with "cat /etc/nv_tegra_release" in Jetson terminal.
FROM dustynv/ros:humble-desktop-l4t-r35.4.1 AS image_jetson

FROM image_${TARGET}

#以下で必要なパッケージのインストール
```

はじめに、ホストマシンかJetsonかを識別するための引数TARGETを定義します。
その後に、ホストマシン用のベースイメージとして、ros:humbleを、Jetson用のベースイメージとしてはdustynv/ros:humble-desktop-l4t-r35.4.1を使用しています。コメントにもあるように、/etc/nv_tegra_releaseの内容を確認して使用するl4tのバージョンを合わせておくと良いと思います。
[参考]　[Jetson AGX Orin でROS 2 Humbleを動かす](https://qiita.com/porizou1/items/3ad4b0ed1e80c0dd42cf)

# イメージビルド用シェルスクリプト

イメージをビルドする際に使用するシェルスクリプトの内容を以下に示します。

```bash
#!/bin/bash

if uname -r | grep tegra; then
  BUILD_JETSON="--build-arg TARGET=jetson"
fi

docker build --build-arg NUM_THREADS=8 ${BUILD_JETSON} --rm -t hogehoge-image .
```

unameコマンドで表示される情報に"tegra"の文字列が含まれているかで、Jetsonであるかを判定しています。
"hogehoge-image"は必要に応じて変更してください。

# コンテナ立ち上げ用シェルスクリプト

コンテナを立ち上げる際に使用するシェルスクリプトの内容を以下に示します。

```bash
#!/bin/bash
xhost +local:

if type nvidia-container-runtime >/dev/null 2>&1; then
  GPU_OPT="--gpus all"
fi

docker run -it --rm ${GPU_OPT} --net host \
        --privileged -v /dev/bus/usb:/dev/bus/usb \
        --env="DISPLAY" \
        -v $HOME/.Xauthority:/root/.Xauthority:rw \
        -v /tmp/.X11-unix:/tmp/.X11-unix \
	    --workdir="/root/colcon_ws" \
        --volume="$(pwd)/../colcon_ws:/root/colcon_ws" \
	hogehoge-image:latest
 ```

使用しているDockerがGPUに対応しているかを判定するために、"nvidia-container-runtime"コマンドが存在するかを使用しています。"nvidia-smi"で判定する場合だと、Jetsonではうまく動作しなかったのでこのコマンドを使用しています。
このシェルスクリプトでは、Dockerfileやシェルスクリプトの格納されているディレクトリのひとつ上に"colcon_ws"が存在することを前提としているので、適宜変更してください。
イメージビルド用シェルスクリプト内の"hogehoge-image"を変更していた場合には、忘れずにこちらにも反映させてください。

# まとめ

本稿では、Jetsonとホストマシンで共通のDockerfileを使用する方法として、Dockerfileの引数を活用する方法についてまとめました。今回の投稿は、新しいロボットを作るたびに書き方を忘れてしまう自分のための備忘録的なものとなっています。参考になれば幸いです。
MacのターミナルでPDF操作する方法をまとめてみた

# はじめに
期末試験忙しすぎるのでちょい記事です

自分はMacユーザーなのでその目線ですが
PDF操作するコマンドをまとめてみました

最近はオンラインサービスとかもありますが、
ネット環境が遅かったりすると動いてくれないので
やっぱUnixしか勝たんということですね

twitterもやってるのでお願いしまーす

https://twitter.com/tomato_boy77


# UnixでのPDF操作ガイド

Unix環境（LinuxおよびMac OS）でPDFファイルを操作するためのコマンド、インストール方法、および基本的な使用方法を以下に示します。



| 操作 | ツール | 詳細 |
|------|--------|------|
|PDFを開く|[Open](#open) | PDFファイルを開く|
| PDFの結合 | [Poppler (`pdfunite`)](#poppler-例pdfunite-pdftocairo) | 複数のPDFファイルを一つに結合 |
| PDFからPNGへの変換 | [Poppler (`pdftocairo`)](#poppler-例pdfunite-pdftocairo) | PDFをPNG画像ファイルに変換 |
| JPGからPDFへの変換 | [ImageMagick (`convert`)](#imagemagick-convert-コマンド) | JPG画像をPDFファイルに変換 |
| PDFからJPGへの変換 | [ImageMagick (`convert`)](#imagemagick-convert-コマンド) | PDFをJPG画像ファイルに変換 |
| PDFの圧縮 | [Ghostscript](#ghostscript) | PDFファイルのサイズを圧縮 |
| PDFの分割 | [pdftk](#pdftk) | PDFを特定のページで分割 |
| PDFのページ並び替え | [QPDF](#qpdf) | PDF内のページの順序を変更 |
| PDFの保護解除 | [QPDF](#qpdf) | パスワード保護されたPDFの保護を解除 |
|PDFのページを1ページにまとめる|	[pdfjam](#pdfjam)|複数のPDFページを1ページにまとめるn-up処理

## Open

### 説明
- デフォルトで搭載されているコマンド
- 普通にファイルを開けます
### 使い方
```bash
open filename.pdf
```

## Poppler (例：pdfunite, pdftocairo)
### 説明
- PopplerはPDFレンダリングライブラリで、PDFファイルを結合、分割、変換するツールを提供します。
### インストール (Mac OS)
```bash
brew install poppler
```
### 使い方
PDFファイルを結合：
```bash
pdfunite file1.pdf file2.pdf output.pdf
```
PDFを他のフォーマットに変換（例：PNG）：
```bash
pdftocairo -png input.pdf output
```

## ImageMagick (`convert` コマンド)

### 説明
- ImageMagickは、画像ファイルを操作するためのツールキットです。
- PDFファイルをJPGや他のフォーマットに変換する場合、またはその逆の場合に使用できます。

### インストール (Mac OS)
```bash
brew install imagemagick
```
### 使い方
JPGをPDFに変換：
```bash
convert image.jpg output.pdf
```
PDFをJPGに変換：
```bash
convert document.pdf image.jpg
```

## Ghostscript
### 説明
- Ghostscriptは、PDFファイルの表示、作成、編集、印刷などに使用できます。
- PDFの圧縮や品質の調整にも使用されます。
### インストール (Mac OS)
```bash
brew install ghostscript
```
### 使い方
PDFの圧縮：
```bash
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/screen -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf
```

## pdftk
### 説明
- pdftkは、PDFファイルを結合、分割、修正、暗号化、情報取得するためのツールです。
### インストール (Mac OS)
```bash
brew install pdftk
```
### 使い方
PDFを結合：
```bash
pdftk file1.pdf file2.pdf cat output output.pdf
```
PDFから特定のページを抽出：
```bash
pdftk input.pdf cat 1-3 output output.pdf
```

## QPDF
### 説明
- QPDFは、PDFファイルの構造分析、変換、および操作に使用されます。
### インストール (Mac OS)
```bash
brew install qpdf
```
### 使い方
PDFのページを並び替え：
```bash
qpdf --empty --pages input.pdf 1,2,4 -- output.pdf
```
PDFの保護解除：
```bash
qpdf --decrypt protected.pdf output.pdf
```

## pdfjam

### 説明
- `pdfjam` はLaTeXの一部であり、PDFファイルのページを組み合わせてn-up処理（複数ページを1ページにまとめる）を行うツールです。
- これは、文書の印刷やプレビュー時にページ数を削減するのに便利です。

### インストール (Mac OS)
```bash
brew install --cask mactex
```
pdfjamはMacTeXの一部としてインストールされます。

### 使い方
6ページを1ページにまとめる：
```bash
pdfjam 入力ファイル.pdf --nup 2x3 --landscape --outfile 出力ファイル.pdf
```
このコマンドは、入力ファイルの6ページを2列×3行のレイアウトで1ページにまとめ、出力ファイルに保存します。

# まとめ
### Unix大好き
メインフレームの要: IBMのJCL、CLIST、REXXを理解する

### **IBMメインフレームの世界：JCL、CLIST、REXXを中心に**

#### **JCL (Job Control Language)の役割と特徴**
IBMメインフレームの心臓部ともいえるのが「JCL」です。このスクリプト言語は、オペレーティングシステムに対してジョブの実行や終了を指示する重要な役割を担っています。JCLの強力な制御機能は、大規模なデータ処理や複雑なシステム管理タスクを効率化します。

#### **CLIST (Command List)の使用例**
一方で、「CLIST」は対話型コマンドの列を実行するプロシージャ言語です。システム管理や日常のタスクオートメーションに使われ、繰り返し行う作業を簡略化し、効率を大幅に向上させることができます。

#### **REXX (Restructured Extended Executor)の利点**
「REXX」は、IBMメインフレームユーザーにとって親しみやすいプログラミング言語です。その直感的な構文は初心者にも理解しやすく、複雑なスクリプト作成や日々の業務のオートメーションを容易にします。

#### **IBM z Systems (z13)の高性能**
IBMのメインフレーム「z Systems (z13)」は、その高性能で知られています。大量のデータ処理、高速トランザクション処理、ビッグデータ分析など、ビジネスに不可欠なタスクを、信頼性と効率性をもってサポートします。

#### **SDF (Structured Data Format)の重要性**
データの構造化は、システムの効率化に不可欠です。「SDF」はこのようなデータを整理し、管理しやすくするためのフォーマットを提供します。特にIBMシステムでは、SDFの使用が一層の効果を発揮します。

#### **自動化テーブルの活用**
プロセスの自動化は、現代のシステム運用において重要な要素です。事前に定義されたルールや手順を含む「自動化テーブル」を用いることで、作業の効率化やエラーの削減が可能になります。

#### **PDB (Program Database)の活用**
プログラムのデバッグや最適化には、「PDB」が不可欠です。このデータベースには、プログラムの構造や動作に関する重要な情報が含まれており、開発の効率化と品質向上に寄与します。

#### **基盤技術の重要性**
最後に、これらの技術が支える「基盤」の重要性を忘れてはなりません。IBMメインフレームは、ビジネスアプリケーションの実行に必要な堅固な基盤を提供し、企業の成長と革新を支えます。
【Active Directory】Azure上にActive Directory検証環境を作る（1/n）

# 目標
Active Directoryの検証環境をAzure上に作りたい。
過程を自分用メモついでに記事にまとめたい。

# 今回やりたいこと
1. Azure上にVMを作る
2. ADDSをインストールする
3. 自分のPCからADサーバにRDPできるようにする

## 1. Azure上にVMを作る![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/992240/0f39fcec-c0e6-7236-5587-c05f65ce8010.png)

### 備考
 - 個人利用向けにOSディスクサイズが小さい（smalldisk）バージョンのOSがある
 - 「デスクトップエクスペリエンス」がないOSのサーバではCLIしか使えない

### 見積額
（月30時間利用想定）
 - インスタンス(Standard_DS1_V2)：$0.0158/h × 30 = 70円
 - OSディスク（30Gib、StandardSSD）：$2.40 = 355円
 - データディスク（4Gib、StandardSSD）：$0.6 = 89円
 計514円/月

 ## 2. ADDSをインストールする
  - ↓を参考にインストール。
Windows Server 2019 Active Directory インストール手順 
https://qiita.com/bitterrich/items/a65c92ce876eff9f05b3

## 3. 自分のPCからADサーバにRDPできるようにする
 - 作成したVMのNSGを↓のように設定する
     - ソース：自分のPCのIPアドレス（静的にしておいた方が良い）
     - 宛先：VMのIPアドレス（静的にしておいた方が良い）
     - ポート：3389（TCP）
     - アクション：Allow

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/992240/c0af7569-cf94-76c6-3adf-cf5977b47be5.png)

# 次やりたいこと
 - クライアント用VMを作成する
     - Windowsライセンスをどうにかする
 - ADにドメイン参加させる
 - GPOでポリシー設定する

## 参考
 - 小さなディスクでWindows Server VMを作る 
 https://qiita.com/chappy7121/items/1e3b856e1bc1c4d91e4c

 - 【Azure】Windows ServerのGUIが表示されない時の対処法 （躓いたので別記事にまとめました）
 https://qiita.com/wvgw1692/items/aaa042c85668b364c162 

### 追記(1/23)
 - 自宅PCからVMへのRDPを行う、最小限の疎通設定に躓いたので追記。
 NSGはLAN内部の世界っぽい。
 https://qiita.com/wvgw1692/questions/e10c1f816c16270ea1bc
強化学習　価値関数

# はじめに
強化学習における行動価値関数と状態価値関数や方策割引率など強化学習における基本的な知識を説明するものです。

# 割引率
強化学習におけるエージェントが選ぶ行動から得られる価値について後の行動から得られる価値を考慮しないように設定するもの。先に得られる価値を重視するもの。
割引率の式
```math
R(t) = \Sigma_{k=0}^{\infty}\gamma^k R_{t+k+1}
```
ɤの値を１にすると始め（１番目）の報酬しか考慮せずɤの値を小さくすると後から（エピソードが大きくなってから）もらうことのできる報酬も考慮するという考え方。

# 状態価値
強化学習において方策に従って行動した場合の今の状態における収益の期待値のことを指します。将棋で表すとある状態における盤面の状態の価値を表したもの。
```math
V^\pi(s) = E_{\pi}[G_t | S_t=s] 
```
状態価値関数をベルマン方程式に直すと以下のようになる。（ベルマン方程式とはこのままでは計算ができないため、計算ができるように直したものである）
```math
V^\pi(s) = \Sigma_a \pi(a|s)\Sigma_{s',r}[P(s',r|s,a)r+\gamma V^\pi(s')] 
```
方策に従って今の状態sから行動aを選んだ時における次の状態s'になる確率で重みづけを行った状態価値
状態sから行動aをとって状態s′に遷移した場合の報酬を返す。
# 行動価値
ある状態における行動を選択したいときにおける価値を表したもの。将棋で表すとある盤面においてある行動を選択したときの価値の期待値を表したもの。
```math
V^\pi(s) = E_{\pi}[G_t | S_t=s,A_t =a] 
```
ベルマン方程式にしたときの行動価値関数
```math
Q^\pi(s) = \Sigma_{s',r}P(s',r|s,a)[r+\gamma V^\pi(s')]
```
Pは全状態における確率を表している

# 状態価値と行動価値の関係
```math
V^\pi(s) = \Sigma_a\pi(a|s)Q^\pi(s)
```
上の式で表される。すべての行動価値における価値の総和が今の状態価値になるため。


# 参考文献
Jsonの理解度

# Jsonについて基本的なことを考えてまとめてみた

jsonの使われ方は
　1. WebサーバーからJsonをProgramに送信する
　1. 設定ファイルとして使用する

jsonを読み解くためには、3段階のステップがあるらしい。（読み解くというよりJsonは、どういったデータなのかの方が正しい）
 1. 基本の方：空データ
     [　]で表現しているデータであること
 1. 名前で探せるデータである事
     キーとバリューで構成されている
 1. 複数のデータを取り扱う

{ } or [ ] の中にデータを記述していく。

　→ { } は名前で探せるデータ（オブジェクト）が入っている
　　この値を取得する場合は、　 変数名['キー’]で指定してバリューの値を取得できる

　→ [ ]の値の取り出し方は、リストと同じでインデックス番号で取得できる
　　この値を取得する場合は、　変数名[インデックス番号]で指定してlistの中身を取得できる

jsonデータは、階層が深くなるほど難しくなるので
どの値が表しているのかの判断が重要になってくる

’キー’：　’バリュー’
などといったデータが存在存在する場合に名前で探せるデータのことを「連想配列」と言う
【git】マージ済のremoteブランチを一括で削除する方法

## 結論
```Bash
$ git branch --remotes --merged=origin/develop | grep -v "origin/master" | grep -v "origin/develop" | sed -E 's/ origin\/(.*)/\1/' | xargs -t -I {} git push origin :{}
```

## コマンドの説明
### remoteブランチの削除
単純にremoteブランチを削除する方法は以下です。
削除対象ブランチ名：deleteTargetBranch
```Bash
$ git push origin :deleteTargetBranch
$ git push origin :[削除するブランチ名]
```

なので、削除したいブランチを一つずつ上記のように指定していけば、力業で消していくことも可能です。

例として、削除したいブランチが以下の3つあって場合
- origin/feature1
- origin/feature2
- origin/feature3

```Bash
$ git push origin :feature1
$ git push origin :feature2
$ git push origin :feature3
```

とすればOK

ただこれだと数が増えた時面倒なので、削除したいブランチ名を、入力として受け取ってやればよい。

そこで、まずブランチ（今回だとorigin/develop）にマージされたブランチの一覧を出力します。

```Bash
$ git branch --remotes --merged=origin/develop
origin/feature1
origin/feature2
origin/feature3

// リモートリポジトリの一覧を表示
$ git branch --remotes

// [対象のブランチ]にマージされたブランチの一覧を表示
$ git branch --remotes --merged=[対象ブランチ]
// おまけ：今いるブランチにマージされたブランチの一覧を表示したい場合は以下
$ git branch --remotes --merged
```


念のために削除されたら困るブランチを「grep -v」明示的に外しておきます。
```Bash
$ git branch --remotes --merged=origin/develop | grep -v "origin/master" | grep -v "origin/develop"

// マッチした行は非表示
$ grep -v [文字列]
```

上で記載した「remoteブランチの削除」にある通り、
remoteブランチを削除する際には[origin/feature1]の[origin/]の部分は不要となります。
なので、sedコマンドを使って、[origin/]を除いてあげます。
```Bash
$ git branch --remotes --merged=origin/develop | grep -v "origin/master" | grep -v "origin/develop" | sed -E 's/ origin\/(.*)/\1/'
feature1
feature2
feature3

// 拡張正規表現を使うことの宣言
$ sed -E
// origin/hoge を hoge に置換
sed -E 's/ origin\/(.*)/\1/
```

最後に、出力された削除対象のブランチを引数にとって、削除コマンドに送ってあげる。

```Bash
$ git branch --remotes --merged=origin/develop | grep -v "origin/master" | grep -v "origin/develop" | sed -E 's/ origin\/(.*)/\1/' | xargs -t -I {} git push origin :{}

// 実行したコマンドを表示
$ xargs -t
// 標準入力から受け取ったものをfugaと置換
$ xargs -I fuga echo fuga
// 以下の場合、標準入力でfeature1という文字列を受け取ったら、
// git push origin :feature1　のように置換され実行されます
xargs -I {} git push origin :{}
```

という流れになっています。
なので、結論にあるコマンドを日本語訳すると以下のようになります。
- origin/develop にマージされたブランチを一覧で表示
- その中で、origin/masterとorigin/developを除く
- 出力されたブランチ名の「origin/」の文字列を削除
- 出力された（feature1等）を引数にremoteブランチを削除
- 実際に実行したコマンドを表示する
Google spreadsheetでsumif関数にor条件を使った集計をしたいとき

## 問題点
| | A | B |
| --- |--------|------|
| 1 | 商品名 | 売上 |
| 2 | 商品A  | 100  |
| 3 | 商品B  | 200  |
| 4 | 商品C  | 150  |
| 5 | 商品A  | 120  |
| 6 | 商品B  | 180  |

上記のようなスプレッドシート（実際はもっと大きな行数のデータ）で
- 商品A
- 商品B

の売上だけを合計したい場合、皆さんはどのように集計するでしょうか？
sumif関数ではor条件が使えず、ネットで探してもサクッと解決策が見つからなかったのでこちらにメモします。

## 解決策1 : sumif関数を2つ書く
具体的には以下になります。

| | A | B |
| --- |--------|------|
| 1 | 商品名 | 売上 |
| 2 | 商品A  | 100  |
| 3 | 商品B  | 200  |
| 4 | 商品C  | 150  |
| 5 | 商品A  | 120  |
| 6 | 商品B  | 180  |

```
=sumif(A:A,"商品A",B:B) + sumif(A:A,"商品B",B:B)
```

メリット　：
- 単純

デメリット：
- 対象の商品が多くなると関数が長くなり、わかりにくくなる。
- 変更があった時の修正が大変。

## 解決策2 : 対象商品のマスタを作り、flagの列を追加する。
具体的には以下です。

＜対象商品マスタ＞（自分で作る）
| | 商品名 | flag |
| - | - | - |
| 1 | 商品A  | 1 |
| 2 | 商品B  | 1 |
| 3 | 商品C  | 0 |
<br>
XLOOKUP関数を使い、集計したいテーブルにflag列を追加する。

| | A | B | C |
| --- |--------|------| - |
| 1 | 商品名 | 売上 | flag |
| 2 | 商品A  | 100  | 1 |
| 3 | 商品B  | 200  | 1 |
| 4 | 商品C  | 150  | 0 |
| 5 | 商品A  | 120  | 1 |
| 6 | 商品B  | 180  | 1 |
<br>
そしてsumif。

```
=sumif(C:C,1,B:B)
```
メリット　：
- 商品数が増えても関数が長くならない。

デメリット：
- テーブルが増える。

## 解決策3 : FILTER関数 + SUM関数
今回特にメモっておきたいと思ったのがこれです。
具体的には以下です。

| | A | B |
| --- |--------|------|
| 1 | 商品名 | 売上 |
| 2 | 商品A  | 100  |
| 3 | 商品B  | 200  |
| 4 | 商品C  | 150  |
| 5 | 商品A  | 120  |
| 6 | 商品B  | 180  |

```
=sum(FILTER(B:B,(A:A="商品A") + (A:A="商品B")))
```

メリット　：
- 対象品が増えても関数が長くなりにくい。
- 集計用のマスタテーブルが増えない。

デメリット：
- FILTER関数に慣れていないと少し難しい。

## まとめ
どの解決策がいいかはケースバイケースですね。
メモりたかったことは以上です。

## 補足：FILTER関数
この関数の基本的な形式は以下です。

```
FILTER(取り出したい範囲, 条件1, [条件2, ...])
```
### 例1
仮に商品Aの売上だけを取り出したい場合、以下です。

| | A | B |
| --- |--------|------|
| 1 | 商品名 | 売上 |
| 2 | 商品A  | 100  |
| 3 | 商品B  | 200  |
| 4 | 商品C  | 150  |
| 5 | 商品A  | 120  |
| 6 | 商品B  | 180  |

＜関数＞
```
=FILTER(B:B, A:A="商品A")
```
＜出力＞
100
120

### 例2
今度はor条件を加えます。
商品Aか、もしくは商品Bの売上だけをとり出したい場合は以下です。

| | A | B |
| --- |--------|------|
| 1 | 商品名 | 売上 |
| 2 | 商品A  | 100  |
| 3 | 商品B  | 200  |
| 4 | 商品C  | 150  |
| 5 | 商品A  | 120  |
| 6 | 商品B  | 180  |

＜関数＞
```
=FILTER(B:B, (A:A="商品A") + (A:A="商品B"))
```
＜出力＞
100
200
120
180

or条件を指定するのに+（プラス）を使うのが少し独特ですね。

あとはSUM関数で集計してやれば合計が出ますね。

＜関数＞
```
=sum(FILTER(B:B, (A:A="商品A") + (A:A="商品B")))
```
＜出力＞
600
よくある質問の構造化マークアップについて

## よくある質問の構造化マークアップについて
クローラーにwebサイトの内容を適切に理解してもらえるようなよくある質問の構造化マークアップについて、恥ずかしながら最近まで知らずにコーディングをしてしまっていたので改めて調べてみました。

## 追加する属性
FAQ全体や質問、回答を表す要素に属性を付与する必要があります。属性を与える部分は以下の5つの要素になります。

|対象  |追加する属性  |
|---|---|
|FAQ全体  |itemscope itemtype="https://schema.org/FAQPage"  |
|各FAQ  |itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"  |
|質問文  |itemprop="name"  |
|回答全体  |itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"  |
|回答文  |itemprop="text"  |


## 具体例
以下は実際に上記属性を追加したFAQの具体例です。

```ruby:index.html
<ul itemscope itemtype="https://schema.org/FAQPage">
  <li itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">
    <div itemprop="name">質問 内容</div>
    <div itemscope　itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
      <p itemprop="text">回答 内容</p>
    </div>
  </li>
</ul>
```
JavaScriptでふりがなのルビを削除する方法

以下をブラウザのコンソールに貼り付けるだけです。

```JavaScript
 const rubyElements = document.querySelectorAll('ruby');
  rubyElements.forEach((rubyElement) => {
    const rtElement = rubyElement.querySelector('rt');
    if (rtElement) {
      rtElement.textContent = ''; // rt要素の中身を削除
    }
  });

```
Pythonの文字列比較

# はじめに
業務で数値比較をするべき場所が、文字列の比較を行っていました。その結果バグの原因になっていました。文字列の比較はどのような処理を行っているのか詳しく調べてみました。言語はPythonです。
# 数値比較と数値文字列比較の挙動の違い
```py
print(100 > 2)       # True
print("100" > "2")   # False
```
数値の比較と数値文字列の比較では異なる結果が出力されました。
# 理由
リファレンスには下記のように記されていました。
>文字列 (str のインスタンス) の比較は、文字の Unicode のコードポイントの数としての値 (組み込み関数 ord() の返り値) を使った辞書式順序で行われます。 
>https://docs.python.org/ja/3/reference/expressions.html#id12

>概して、シーケンスオブジェクトは、同じシーケンス型の他のオブジェクトと比較できます。比較には 辞書的な (lexicographical) 順序が用いられます。まず、最初の二つの要素を比較し、その値が等しくなければその時点で比較結果が決まります。等しければ次の二つの要素を比較し、以降シーケンスの要素が尽きるまで続けます。比較しようとする二つの要素がいずれも同じシーケンス型であれば、そのシーケンス間での辞書比較を再帰的に行います。二つのシーケンスの全ての要素の比較結果が等しくなれば、シーケンスは等しいとみなされます。
https://docs.python.org/ja/3/tutorial/datastructures.html#comparing-sequences-and-other-types

すなわち、文字列の比較を行うときは２つの要素の先頭のUnicodeのコードポイントを比較し、等しければ次の要素のコードポイントを比較するということです。コードポイントとはUnicodeに記されている各文字に一意に定義付けされた数字のことです。
```py
print(ord("1"))  # 49
print(ord("2"))  # 50
```
"1"のコードポイントは49、"2"のコードポイントは50となりました。すなわち、"1"のコードポイントより"2"のコードポイントが大きいため"100" > "2"はFalseになります。
コードポイントを16進数に変換してUnicodeを確認してみます。
```py
print(hex(ord("1")))  # 0x31
print(hex(ord("2")))  # 0x32
```
Unicodeを取得できることが確認できました。
Nuxt3 metaタグを追加してみる（サイトの概要表示）

# はじめに
X（Twitter）やリンク共有時に説明文とか、ロゴとか自動で出て欲しい…
何もしなければただのリンクだけ表示されて怪しいサイト…？みたいな感じで。
Nuxt3でMetaタグを追加していきます。

## どんなの作ったの
最終的にTwitterとかで共有した時にこんな感じになります。
![スクリーンショット 2024-01-21 22.09.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273836/c419ba98-ecab-05a9-0703-7e7359ee1bfb.png)


↓Qiitaでも認識されました。↓

https://web.ynetlabo.net

### Step1: 必要なMetaタグを確認する
以下公式サイトでタグを確認する。

https://developer.twitter.com/ja/docs/tweets/optimize-with-cards/guides/getting-started

```html: TwitterカードとOpen Graphの例
<meta name="twitter:card" content="summary" />
<meta name="twitter:site" content="@nytimesbits" />
<meta name="twitter:creator" content="@nickbilton" />
<meta property="og:url" content="http://bits.blogs.nytimes.com/2011/12/08/a-twitter-for-my-sister/" />
<meta property="og:title" content="A Twitter for My Sister" />
<meta property="og:description" content="In the early days, Twitter grew so quickly that it was almost impossible to add new features because engineers spent their time trying to keep the rocket ship from stalling." />
<meta property="og:image" content="http://graphics8.nytimes.com/images/2011/12/08/technology/bits-newtwitter/bits-newtwitter-tmagArticle.jpg" />
```
### Step2: Nuxt3メタタグの追加方法確認
以下公式サイトでタグを確認する。

https://nuxt.com/docs/getting-started/seo-meta#defaults

charsetとかはあるけど、twitter:xxx系を追加したい…
こっち側に記載あり！

https://nuxt.com/docs/api/nuxt-config#head

```typescript:nuxt.config.ts
{
  "meta": [
    {
      "name": "viewport",
      "content": "width=device-width, initial-scale=1"
    },
    {
      "charset": "utf-8"
    }
  ],
…

```

### Step3:定義してく…
```typescript:/nuxt.config.ts
export default defineNuxtConfig({
 ...
    app: {
        head: {
          title: "Y.NetLabo | アプリ開発の情報発信ラボ",
          meta: [
            { charset: "utf-8" },
            { name: "viewport", content: "width=device-width, initial-scale=1" },
            { property: "og:type", content: "website" },
            {
              property: "og:title",
              content: "Y.NetLabo | アプリ開発の情報発信ラボ",
            },
            { property: "og:url", content: "https://web.ynetlabo.net" },
            { property: "og:locale", content: "ja_JP" },
            { property: "og:site_name", content: "Y.NetLabo" },
            {
              property: "og:description",
              content:
                "はじめまして、Y.NetLaboです。私たちは企業ではありません。アプリ開発好きな個人が作品を作ってます。",
            },
            {
              property: "og:image",
              content: "https://web.ynetlabo.net/laboicon.png",
            },
            { property: "twitter:card", content: "summary" },
            { property: "twitter:site", content: "Y.NetLabo_JP" },
            {
              property: "twitter:title",
              content: "Y.NetLabo | アプリ開発の情報発信ラボ",
            },
            {
              property: "twitter:description",
              content:
                "はじめまして、Y.NetLaboです。私たちは企業ではありません。アプリ開発好きな個人が作品を作ってます。",
            },
            {
              property: "twitter:image",
              content: "https://web.ynetlabo.net/laboicon.png",
            },
          ],
        },
 ...
```

👏動いた！
PDOでロールバックして帳消し

phpでロールバックをして帳消しします。

```php
try{
    $pdo = new PDO($dns,$user,$pass,[
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);}catch(PDOException $e){
    echo '接続失敗' . $e->getMessage();
    exit();
}

$pdo->beginTransaction(); //トランザクションの開始
$pdo->query(
    "UPDATE user SET age = age + 1 WHERE id = 1"
);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($result[0]["age"]);
```
```
26
```
間違えたことに気づきます。処理前まで巻き戻しましょう。

```php
$pdo->rollback();
print_r($result[0]["age"]);
```
```
25
```
rollbackメソッドを実行することで$pdo->beginTransaction()のところまで巻き戻しています。
ちなみに以下のやり方だとエラーが出ます。
```php
try{
    $pdo = new PDO($dns,$user,$pass,[
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);}catch(PDOException $e){
    echo '接続失敗' . $e->getMessage();
    exit();
}

$pdo->beginTransaction(); //トランザクションの開始
$pdo->query(
    "UPDATE user SET age = age + 1 WHERE id = 1"
);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($result[0]["age"]);
$pdo->commit(); //ここでコミットする

$pdo->rollback(); //コミットした後にrollbackメソッドを実行する
print_r($result[0]["age"]);
```
```
Fatal error: Uncaught PDOException: There is no active transaction in
```

また今度勉強しようと思います。
【Python】macOSでScipyのインストールが失敗する場合の対処法（whlファイル版）

# この記事の内容

macOSにscipyをインストールする方法を紹介します。

■ 結論
    [pypiの公式サイト(scipy)](https://pypi.org/project/scipy/#files) から、ご自身の環境に合った**whlファイル**をダウンロードし、`pip install ファイル名.whl`でインストールする。

https://pypi.org/project/scipy/#files


# 背景

macOSに**scipy**をインストールしようすると、エラーが発生してインストール出来ない。

・インストールコマンド
```shell
pip install scipy
```

・発生するエラー
```shell
note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
```

・環境情報
macOSバージョン: 11.6.4（macOS Big Sur）
マシン: MacBook Pro (13-inch, M1, 2020)


# scipyのインストール手順（whlファイルを使用）

### 1. Pythonバージョンを確認

venvを使用している場合は `source 仮想環境パス/bin/activate`してから
```shell
python -V
```
→ Python 3.11.5


### 2. macOSバージョンを確認
画面左上のアップルマークから「このMacについて」をクリックして確認
→ 11.6.4

### 3. pypiのサイトから環境に合ったwhlファイルをダウンロード

scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl 

- cp○□ → 1.で確認したPythonバージョン ○.□.x
- macosx_○_□ → 2.で確認したmacOSバージョン ○.□.x

※ Pythonバージョンは一致している必要あり（Python 3.11.x なら cp311）
※ macOSは一致するバージョンがなければ近いもので可（macOS 11.x.x　なら macosx_12_0 でもOK）

### 4. `pip install ダウンロードしたファイル.whl` でインストール

- ダウンロードしたファイルがあるフォルダに移動
- whlファイルをリネーム（ダウンロードしたwhlファイルのmacOSバージョンが異なる場合）

ダウンロードしたwhlファイルがmacOS 12用で、ご自身の環境のmacOSが11.xの場合
scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl 
↓
scipy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl

:::note alert
macOSのバージョンが異なっていてリネームせずにインストールすると、以下のようなエラーが発生します
```
ERROR: scipy-1.12.0-cp311-cp311-macosx_12_0_arm64.whl is not a supported wheel on this platform.
```
:::

- scipyをインストール
```shell
pip install scipy-1.12.0-cp311-cp311-macosx_11_0_arm64.whl
```

- インストールの成功確認

Pythonの対話モード起動
```shell
python
```
scipyインポート
```python
import scipy
```

エラーが出なければインストール成功