OmniAICreator/Qiita-1.07M huggingface dataset:
他クラスに値を渡したい、MainActivity以外からfindViewByIdしたい

MainActivity以外からfindViewByIdしたい、他クラスに値を渡したいとき

引数を使ってMainActivityを他クラスに渡せない場合のやり方メモ

メソッドを使う

```MainActivity.java
public class MainActivity extends AppCompatActivity {

    //context用意
    public Context conText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // conTextにMainActivityを入れる
        conText=this;

        //context受け渡し
        //メソッドでセット
        TestService.setConText(conText);

}

```


```SubActivity.java
public class SubActivity {

    //context用意　static忘れない
    public static Context conText2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //findViewByIdでconText2を使用
        textRead = ((com.example.backgroundservice.MainActivity) conText2).findViewById(R.id.text_read);

    }

    //contextをセットするメソッド　static忘れない
    public static void setConText(Context ct){
        conText2=ct;
    }

}

```


＜public＞
他クラスからもアクセス可能にする

＜static＞
staticは呼び出し時にインスタンス化しなくても使えるようにするもの
今回の場合、MainActivityではSubActivityのインスタンスを生成せずにメソッドを呼び出しているからstatic必要

クラス名.メソッド名
クラス名.変数名
で使える

※メソッドにも変数にもstaticを付けとかなければいけない

分かりにくいが、MainActivityで定義したconTextとSubActivityで定義して実際に使用しているconTextは全く別物


他クラスに値を渡す方法として
・引数
・フィールドをpublicやstaticにして参照（クラス名.変数名で使用）
・メソッドで値をセット
python-shellが動かない時に試してほしいこと

nodejsでスクレイピングをやろうと思い、pythonとの連携ができれば簡単そうだなと漠然と考えていたところにpython-shellなるnodejsの環境からpythonコードが実行できるライブラリがあると知り、試してみたが、期待通りに動かない。
自分が解決までに試したことを共有します

## 環境
MacBook Air
Apple M2
nodejs: v16.15.0
python: Python 3.11.2
python-shell: 5.0.0

### 解決までの流れ
python-shellの使い方を調べると上位の方に掲載されているサイトでは
```parent.js
const { PythonShell } = require('python-shell');

// runStringメソッド
PythonShell.runString('print("Hello world")', null, function (err, result) {
    if (err) throw err;
 
    console.log(result);
});

// runメソッド（pythonファイルを指定して実行させる）
PythonShell.runString('test.py', null, function (err, result) {
    if (err) throw err;
 
    console.log(result);
});
```

のようにrunStringメソッドやrunメソッドの第三引数にコールバック関数を与えてエラーハンドリングやconsole.logしているが、実行してもpythonが走っている形跡がない。

runStringメソッドの方ではpythonの出力がresultに格納されてconsole.logされる予定らしいがどうもこれも出力されていない。
もしやエラーハンドリングの段階でつまづいている？と思い

```parent.js
const { PythonShell } = require('python-shell');

console.log('run1');
PythonShell.runString('print("Hello world")', null, function (err, result) {
    if (err) throw err;

    console.log(result);
});
console.log('run2');
/** 結果
 *  run1
 *  run2
 *  /

```
とconsole.logで挟んでみたがしっかりrun2も出力されてる(やり方良くないかもだけど…)

axiosみたいにthen節をケツにつけてはどうかと思い下記を実行
```parent.js
const { PythonShell } = require('python-shell');

PythonShell.runString('print("Hello world")', null)
  .then((response) => {
    console.log(response);
  })
  .catch((error) => {
    console.log(error);
});
// 結果　[ 'Hello world' ]
```

コールバックの呼び出し方が変わったのか？

https://www.npmjs.com/package/python-shell

↑というか公式に書いてあった

### 結論

とっつきにくくて誰かが解説してくれてるやつもいいけど公式ドキュメント読もう🤯

### おわりに
pythonは比較的最近プログラム書き始めた人がよく使ってるイメージあるので同じような問題にブチ当たった人の為になればと思い書いてみました。
英語で難解に感じるが、コードは共通語なので公式が出してくれているドキュメントがなんだかんだ一番参考になるという自らへの教訓でもありました。
無線プロファイル用ばっちっち。


```wlan_profiles.cmd
@echo off
setlocal
%~d0
cd %~p0
:loop
echo.
echo   1. 既知の無線プロファイルを '%CD%' へ XMLファイルとして保存します。
echo   2. 無線プロファイルを '%CD%' に有る全ての XMLファイルから追加します。
echo   3. すべてのインターフェイスから、すべてのワイヤレス ネットワーク プロファイルを削除します。
echo   4. 指定したワイヤレス ネットワーク プロファイルを最優先へ設定します。
echo   5. ヤメル!?
::echo.
::echo   1. Export wifi profiles to '%CD%' as an XML file.
::echo   2. Import wifi profiles from all XML files in '%CD%'.
::echo   3. Remove all wireless network profiles from all interfaces.
::echo   4. Set a specifies wireless network profile to top of the preference order.
::echo   5. Abort!?
echo.
set made=
set /p mode="> "
if "%mode%"=="1" (
    for /f "tokens=2 delims=:" %%A in ('netsh wlan show profiles') do (
        call :export %%A
    )
    goto :end
)
if "%mode%"=="2" (
    for %%A in (*.xml) do netsh wlan add profile filename="%%A"
    goto :end
)
if "%mode%"=="3" (
    for /f "tokens=2 delims=:" %%A in ('netsh wlan show profiles') do (
        call :delete %%A
    )
    goto :end
)
if "%mode%"=="4" (
    goto :priority
)
if not "%mode%"=="5" goto :loop
:end
endlocal
pause
exit
:delete
set name=%*
if defined name netsh wlan delete profile name="%name%" i=*
exit /b
:export
set name=%*
if defined name netsh wlan export profile name="%name%" folder=. key=clear
exit /b
:priority
echo.
:loop2
for /f "tokens=2 delims=:" %%A in ('netsh wlan show profiles') do (
    call :choices %%A
)
echo.
set n=
set q=a
set /p q="Which do you prefer [%choices:~0,-1%]?"
goto :loop2
:choices
set name=%*
if defined name (set /a n=n+1) else (exit /b)
if not defined q (
    set choices=%choices%%n%,
    echo   %n%. %name%
) else if "%q%"=="1" (
    set q=a
    echo.
    echo It's already top priority.
) else if "%n%"=="%q%" (
    netsh wlan set profileorder name="%name%" interface="Wi-Fi" priority=1
    goto :end
)
exit /b
```
【Unity】フォルダ内のプレハブ群とシーン群からTagとLayerの利用箇所を検索できるEditor拡張


# 概要

見覚えのない Tag や Layer の利用状況をより詳しく把握できるEditor拡張を作りました。

Tag And Layer に作った覚えのない Tag や Layer が増えている経験はありませんか？
大抵、ライブラリのサンプルやチームメンバーによって追加されます。
IDE の検索機能を使えば、コード内でどのように Tag や Layer が使われているか調べられますが、Unity 上での利用状況は調べられません。
そこで、フォルダ内のプレハブ群とシーン群が持つ全てのオブジェクトから、特定のタグ・レイヤーが利用されているオブジェクトを探して列挙するEditor拡張を作りました。
具体的な利用箇所もパスで見つけやすくなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/0eed272f-6100-676f-a385-c33a142cf452.png)

もし開発初期に使用予定の無さそうな Tag や Layer を見つけたら、メンバーに確認を取って削除しましょう。不必要な Tag と Layer は自身や開発メンバーを混乱させたり、思わぬ不具合の原因になったりします。

# コード

https://github.com/yamara-mh/CodeStorage/blob/main/Codes/FindTagAndLayerUserEditor.cs

# 使い方

1. コードをプロジェクトに追加します
2. メニューバーから Tools → Utility → Open FindTagAndLayerUserEditor を選択します
3. 調べたいフォルダをクリックします
4. タグ名・レイヤー名を指定して Find ボタンを押します
5. 少し待ちます
6. コンソールに使用個数と使用しているプレハブ・シーンのパスが表示されます
Windows上での実行とWSL上で実行する主な違い


## Windows上で実行とWSL（Windows Subsystem for Linux）上で実行する主な違い




## 環境

- Windows
Windowsオペレーティングシステム上で直接プログラムを実行
Windowsのファイルシステムやネットワーク構成など、Windows環境を使用
- WSL
WSLはLinuxカーネルの互換性レイヤーを提供するため、Linux環境でプログラムを実行
Linuxのファイルシステムやネットワーク設定など、Linux環境を使用

## コマンドラインツール

- Windows上
コマンドプロンプトやPowerShellなど、Windowsのコマンドラインツールを使用
- WSL
Linuxのターミナルエミュレータ（Bash、Zshなど）を使用

## パッケージ管理

- Windows
Windows環境ではパッケージ管理システムとしてChocolateyやScoopなどを使用
- WSL
WSL環境ではLinuxディストリビューションに固有のパッケージ管理システム（apt、yumなど）を使用

## ネイティブアプリケーションのサポート

- Windows
Windows上で動作するネイティブアプリケーション（.exe形式など）を直接実行できる
- WSL
WSLは主にLinux向けに設計されたアプリケーションを実行するためのもので、Linuxバイナリやシェルスクリプトを実行できる
macOSでifconfigコマンドを使用してネットワークインターフェースの情報を確認する

## ifconfigコマンド

macOSでネットワークインターフェースの情報を確認するため、ifconfigコマンドを実行します。
実行結果には、各ネットワークインターフェースごとの情報が表示され、以下はその一部になっています。

```zsh
~ % ifconfig
lo0: flags=8149<UP,LOOPBACK,RUNNING,PROMISC,MULTICAST> mtu 16384
	options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
	inet 127.0.0.1 netmask 0xff000000 
	inet6 ::1 prefixlen 128 
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 
	nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8110<POINTOPOINT,PROMISC,MULTICAST> mtu 1280
stf0: flags=100<PROMISC> mtu 1280
en6: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether XX:XX:XX:XX:XX:XX 
	inet6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX%en6 prefixlen 64 scopeid 0x4 
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect (100baseTX <full-duplex>)
	status: active
...
```

## macOSのネットワークインターフェースの種類

代表的なものを表にまとめてみました。

|インターネットインターフェース|説明|
|---|---|
|lo0|[loopback interface](https://e-words.jp/w/%E3%83%AB%E3%83%BC%E3%83%97%E3%83%90%E3%83%83%E3%82%AF%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9.html)、自分自身のIPアドレス（localhost）|
|en0|かつてはEthernet、現在はWifi|
|en1,en2|[Thunderbolt](https://ja.wikipedia.org/wiki/Thunderbolt)|
|fw0|FireWire|
|stf0|IPv4からIPv6標準への移行をサポートするトンネルデバイス|
|gif0|汎用的なトンネルデバイス|
|awdl0|Appleワイヤレスダイレクトリンク。iOSとの通信。iphoneと接続するなど|
|p2p0|AWDL機能関連|
|bridge0|Dockerを使ったサーバー通信|
|utun0,utun1,...|サードパーティのネットワーキングアプリケーションが使用するTUN(L3/IP)/TAP(L2/Ethernet)インターフェース。多くのVPNがカーネル仮想ネットワーキングデバイスとして追加。|

## en0でネットワーク情報を確認

en0の情報はこのように表示されます。

```zsh
en0: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
	options=6463<RXCSUM,TXCSUM,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
	ether XX:XX:XX:XX:XX:XX 
	inet6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX%en0 prefixlen 64 secured scopeid 0xc 
	inet 192.168.0.7 netmask 0xffffff00 broadcast 192.168.0.255
	inet6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX prefixlen 64 autoconf secured 
	inet6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX prefixlen 64 autoconf temporary 
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active
```

* flags: インターフェースの状態
* options: ネットワークインターフェースのオプション
* inet: IPv4のIPアドレス
* inet6: IPv6のIPアドレス
* ether: ハードウェアアドレス（MACアドレス）
* broadcast: ブロードキャストアドレス

## 参考情報

* [ifconfigとは何か？表示内容の意味を実例で解説](https://prograshi.com/general/command/what-is-ifconfig/)
Linux未経験1年目エンジニアが5ヶ月かけてLPIC-1に合格した方法


# 【はじめに】 
こんにちは、クラウドエンジニア2年目のヒビキです。
この記事ではLinux未経験から5ヶ月かけてLPIC-1を取得した方法と、
当時の経験をもとに効率の良い勉強法をお伝えします。

ちなみに受験結果はこんな感じ。かなり苦戦しました。
![スクリーンショット 2023-06-07 23.47.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472856/bc1b0b38-03de-926a-3e83-d0908c6836b2.png)



# 【受験の背景】 
あれは新卒で入社した会社で2ヶ月間の研修を終え、配属された初日のことでした。
上司：「何から勉強したらよいかわからないでしょ？とりあえずLPIC-1を取ろう！」
私：「え、あ、わかりました。」
と、こんな感じで勉強が始まりました。
レベル1だしまあなんとかなるでしょ？とナメてましたね。。。。
（まさか2回も落ちるなんて思ってませんでした）

# 【使用した教材】 
私がLPIC-1合格までに使用した教材は以下の3つです。
##  1.Ping-t  
一つ目はおなじみのPing-t。
多少Linuxの経験がある人はこれだけで合格できると思います。
（会社の先輩もこれだけで合格したと言ってました）
Ping-tの良いところは問題数の多さと費用(LPIC-101は無料)です。
https://ping-t.com/


##  2.Linux教科書 LPICレベル1 スピードマスター問題集  
二つ目はスピードマスター問題集、(通称スピマス？)
この参考書の良いところは模擬試験の内容がかなり本番と近いことです。
全く同じ問題が何問か本番でも出題されました。
https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC%E3%83%AC%E3%83%99%E3%83%AB1-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version5-0%E5%AF%BE%E5%BF%9C-%E5%B1%B1%E6%9C%AC/dp/4798160857


##  3.Youtube動画(qtyoshimoto氏)  
3つ目はYoutube動画です。
今の時代Youtubeに解説動画がごろごろ転がってるはず！と思ってましたがそんなことありませんでした。
そんな時に見つけたのがqtyoshimoto氏の動画です。
かなり11年前の動画ということもあり、情報がやや古いところもありますがかなりわかりやすいです。
移動中などに見れるのがおすすめです！
https://www.youtube.com/@qtyoshimoto



# 【実際のスケジュール】 
##  1.LPIC-101 1回目の受験で不合格になるまで 
この期間はひたすらPing-tを解いていました。
解き方としては各単元をまとめて解答し、間違えたところを解き直してました。
![スクリーンショット 2023-06-07 23.50.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472856/35991c7d-93fb-6153-aa62-325b0c14eaed.png)

試験モードで正答率80%を達成できたあたりで受験しました。
結果は前述の通り不合格。
敗因としては”問題を覚えてしまったこと”だと思います。
深いところまで理解せず、反射的に答えてしまっていたせいで当日全く手応えがありませんでした。

##  2.LPIC-101に合格するまで  
1回目の反省を活かして、以下のサイクルで勉強しました。
①Ping-tを解く
②間違えたところをYoutube動画で学習
③スピマスを読む

この①〜③までを各単元で2週しました。
一ヶ月と少しで全ての単元を学習し、試験前日にスピマス付属の模擬問題を一回解いて受験しました。

結果は合格！勉強開始から2ヶ月ちょっとかかりました。
感想としては”スピマスやっててよかったぁ〜”です。
当日全く同じ問題が出てホッとしました。

##  3.LPIC-102 1回目の受験で不合格になるまで  
この期間は前述のLPIC-101を合格するために行った方法と全く同じ方法で学習しました。
(Ping-tは102試験から有料になります)
かなり手応えもよかったのですが、結果は不合格。
敗因はコマンドのオプションを正確に覚えられてなかったことです。(5問くらい落とした気がします)

##  4.LPIC-102 に合格するまで  
不合格から2週間ほどですぐ受験し合格したわけですが、
この期間はひたすらコマンドとそのオプションを覚えました。
この時に意識したことはオプションの意味する英単語を一緒に覚えることです。
例えば、”sshコマンドの-iオプションはidentityの意味”といった覚え方です。

それと試験前日にスピマス付属の模擬問題を2回解きました。
この時にはもうスピマス信者です。


といった感じで壁にぶつかり続け、なんとか合格できました。

# 【おすすめの勉強法】 
私のLPIC-1合格までの反省を踏まえて、おすすめの勉強法をここに示します。
できることなら昔の自分に伝えたい！！

##  ①試験を予約する  
　これが一番大事！
　人間は期限がないといつまでも後回しにします。
　受験料を払い、逃げられない環境を作りましょう！
　(前日までであれば試験日程を延期できるのでもし勉強が間に合わなくても大丈夫です！)

##  ②試験範囲を学習する  
　「Ping-t→Youtube動画→スピマス」のサイクルで各単元を勉強しましょう！
　おすすめは”移動中にPing-tとYoutube”、”カフェでスピマス”です。
　なかなか家で勉強に集中できない方も多いと思いますので、環境にも気を使ってみましょう！

##  ③試験前日にスピマスの模擬試験を解く  
　スピマスはLPI認定ということもあり、模擬試験の精度が高いです。
　前日はこれをできれば2回解き、同じ問題が出れば100%正解できるようにしましょう！

これから受験を考えている方は①〜③を試してみてください！！



# 【最後に】 
これから受験する方にこれだけは伝えたい！
「LPIC-1は難しい！！」
レベル1だから落ちたら恥ずかいなんて思ってはダメです。
コツコツ勉強して、ぜひ合格を目指してください。
この記事が誰かの役に立てば幸いです。
【Docker】docker compose run でポートマッピングする方法

## `--service-ports`

`--service-ports`を使用することで`compose.yml`に記述した`ports`を適用することができます。

```terminal
$ docker compose run --service-ports --rm service bash

$ docker container port container-name
3000/tcp -> 0.0.0.0:3000
6006/tcp -> 0.0.0.0:6006
```

`--service-ports`を使用しないと`ports`は無視されます。

```bash
$ docker compose run --rm service bash

$ docker container port container-name
# 何も出力されない
```
Win11のInsiderPreview版で起きるかもしれないバグ・エラー


私がWin11のInsiderPreview版(Devチャネル)に変更してから起きたエラーと対処法です

ちなみに私の環境は以下に
- モデル ROG Flow X13(2021)
- Windows11 Home InsiderPreview版
- Ryzen9 5900HS
- RAM 16GB
- ROM 512GB
# 現状起きてること

|内容 |対処法|
| --- | --- |
| InsiderPreview版から通常版に戻せない |おそらくバグ(MSの対応待ち?)| 
| VisualStudioを入れても再起動後に消える |OSリセットか...?(私の環境が悪い可能性)|
VScode PHP Intelephense 開いているファイルからフォーカスが外れたときにフォーマッタを実行する

# 概要

- VScodeの拡張機能である「PHP intelephense」のフォーマッタ機能の起動タイミングを「開いているファイルからフォーカスが外れた時」い設定する方法をまとめる。

# 方法

## intelephenseの設定

- 設定で「intelephense Format:」と検索し下記の項目にチェックを入れてフォーマッタ機能を有効化する。

    ![設定_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/53e17f07-5b77-e63b-d3ea-03e41362b373.png)

- 設定の「intelephense Format: Braces」を「psr12」に設定する。

    ![設定_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/13f1ddc5-cb52-0fe5-322b-c21f3a03cf54.png)

## VScodeのフォーマッタの設定

- 設定の「Editor: Default Formatter」を「PHP Intelephense」に設定する。

    ![設定_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/05dda810-c738-91fa-a7c6-0ab088df0e99.png)

- 設定の「Editor: Format On Save」にチェックを入れる。

    ![設定_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ed9b365c-54e6-592e-754c-6f01891141e2.png)

## VScodeの自動保存の設定

- 設定の「Files: Auto Save」を「onFocusChange」に設定する。

    ![設定_—_dokupro-app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/8b57b543-d90a-29ef-5752-eeff729d5da9.png)
「え‼︎Google ColabolatoryでHaskellを⁉︎」「出来らあっ！」

# Haskell on Colabolatory
## まえがき
Colabolatoryって便利ですよね。手軽にコードを試せて助かってます。
そんなある日、大学の課題でこんなものが出ました。

> サポートベクターマシンを使ったクラス識別がColabolatoryで使って出来るから試してみてね(超意訳)

情報工学系の大学生のとってはさして珍しくもない課題です。まあこういう文脈で語られるColabolatoryとは大抵お手軽なPythonの実行環境のことです。
そんな中、私は何を血迷ったのかHaskellの機械学習のことに思いを馳せていました。

そして気がついた時には`Colabolatory Haskell`で検索をしていました。

## 結論

以下のコードをそれぞれ別のセルにコピペして順番に実行するとHaskellで書いたコードが動くことがわかります。

### `ghc`のダウンロード
```py
!curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | env BOOTSTRAP_HASKELL_NONINTERACTIVE=1 sh # download ghcup
!apt-get install libgmp3-dev                                                                                    # download library for lgmp
!mkdir -p Haskell/{src,bin}                                                                                     # make directory for Haskell
import os
os.environ["PATH"] = os.environ["HOME"] + "/.ghcup/bin:" + os.environ["PATH"]                                   # specify path
```

### Haskellのソースファイルの生成
```haskell
# write code in Haskell/src/hello.hs
%%file Haskell/src/hello.hs
main = do
    putStr "Hello "
    putStrLn "Haskell!"
```

### Haskellのソースファイルを`ghc`でコンパイル
```sh
!ghc Haskell/src/hello.hs -o Haskell/bin/hello  # compile Haskell file
!rm Haskell/src/*.{hi,o}                        # remove object file and interface file
!./Haskell/bin/hello                            # execute hello
```

## Colabolatoryで使った機能

今回はPythonのコードを書かない代わりにColabolatoryの機能をいくつか使いました。

### コマンドラインモードを使える

Colabolatoryではコマンドラインモードが使えます。
```
!ls
```
のようにコマンドの前に`!`を入力することで以降をコマンドラインモードとして認識させることができます。

`ghc`のダウンロードなどにはこれを使っています。ただし私の勘違いかもしれませんが一部のコマンドはうまく動作しないみたいです。
~~特にパスを通すのがうまくいかなかったので`ghc`をパスが通ってる場所にcopyする結果となりました。~~
パスを通す場合は追記の記載を確認してください。
参考にする方はこの点に注意してください。

### ファイルの書き出しが容易にできる

Colabolatoryでは以下のようにすることでファイルを生成することができます。

```
%%file [filename]
[code]
```

## 結局何をやったのか

0. コマンドモードで`ghc`のダウンロード
0. コマンドモードで`ghc`のパスを通す(お好みで)
0. コマンドモードで必要なライブラリをダウンロード
0. コマンドモードでHaskell用のディレクトリを作成(お好みで)
0. Haskellのソースファイルを作成
0. コマンドモードでソースファイルをコンパイル
0. コマンドモードでオブジェクトファイルやインターフェースファイルを消す(お好みで)
0. コマンドモードで実行確認

## 最後に

今回はHaskellで話しましたが、コマンドラインからコンパイラをダウンロードできる系の言語全てに応用が効きます。
厄介な開発環境の構築を省略できるので受講者に体験をしてもらうハンズアウトにぴったりだと思います。

## 追記
コメントを受けて、特に興味が惹かれたものを以下に追記します。
### 「PATHはPython側で環境変数をいじればいけるよ」
Colabolatoryでは`source`コマンドなどでPATHを更新することができなかったのですが、**Pythonのosモジュールを使うことで解決**できました。
こっちの方が`copy`よりもお行儀が良さそうなのでこっちを使うように変更しました。
Excelで複数のセルに一括で "IFERROR" をつける方法

## やりたいこと
Excel関数が複数のセルに設定されている状態で、その関数がエラーになる場合があることがわかったので、IFERRORを追加して、エラーになったらブランクで表示したい。
参照先が微妙に連続していないため、オートフィルでは設定できない。

## 解決方法
一度一括置換でイコールを消してから、一括置換でIFERRORを追加する。

## 説明
例：　=IF(A1<0, "", A1\*1)　→ =IFERROR(IF(A1<0, "", A1\*1),"") としたい場合

最初は、"IF" を　"IFERROR(IF" に置換したあと、 ")" を "),"")" に置換すればよいと思ったが、
"IF" を　"IFERROR(IF" に置換した時点で、とじかっこが足りずにエラーになってしまう。
以下のステップを踏むことで、すべてのセルに一括で "IFERROR" を追加できた。

* "=IF" を "IFERROR(IF" に置換　（=先頭のイコールを消して、ただの文字列にする）
* ")" を "),"")" に置換
* "IFERROR" を "=IFERROR" に置換 (=先頭にイコールをつけて、関数に戻す）


☆もっと簡単な方法があれば、ぜひ教えていただけますと幸いです☆
奮闘記

初めまして、お恥ずかしながら30歳からエンジニア目指して奮闘中。
りょうです。

今までVBAで少し、マクロを組んでキャッキャしてたのが始まりですが
元々のガジェット好きも高じて、新しいチャレンジを頑張りたいと思います。

年齢的に難しいところはあると思いますが、よろしくお願いします。
RailsのPuma（v4系）でCapistranoのデプロイでゼロダウンタイムを実現する設定

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提
Capistranoでのデプロイの際に、ゼロダウンタイムで行わなければならなくなった際のメモ。

# 設定内容
Capistranoでデプロイする際にPumaのv4系でゼロダウンタイムを実現するためには、`phased_restart`でPumaを再起動させます。
`deploy.rb`に以下の記述を行うと実現ができます。

```ruby:/deploy.rb
set :puma_workers, 2
set :puma_preload_app, false
set :prune_bundler, true
set :puma_phased_restart, true
```

# 参考記事

https://qiita.com/selmertsx/items/a0c94f201b0130988910
【脳死でVercel？】JAMstack構成のWebサイトを作った話 ~ホスティング先選定~【Next.js × GitHubActions(CI/CD) × microCMS】

みなさんこんにちは。`massu159`です。
今回はJAMstack構成のWebサイトを作りましたので、そのお話です。
# 使用技術
- Next.js
- React
- Typescript
- TailwindCSS 
- eslint
- prettier

# システム構成
![Next.js+GitHubAction+Webhook+microCMS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619375/33541274-687e-2b9d-a1d5-5c916ca5362f.png)

基本的な流れとしては、`microCMS`でコンテンツを更新した時に、Webhookを利用して`GitHub Actions`が動作します。`GitHub Actions`でCI/CDを構築しており、ビルド時の静的ファイル生成からデプロイまで自動で行うことで、常に最新のコンテンツを高速かつ快適にユーザーに届けることができます。

# ホスティング先
当初、ホスティング先としては`Vercel`を選択していましたが、再度検討を行い`Firebase　Hosting`を採用しました。
他の候補に、
- レンタルサーバー
- Netlify
- AWS Amplify
- AWS S3
- Firebase
...
等があり、いろいろと比較しました。

まず`Vercel`をやめた理由としては、
1. サーバー費用を抑えるためです。今回は商用利用でしたので、商用利用可を条件にサーバーを選択する必要がありました。（`Vercel`は商用利用の場合$20/月かかる ←ヤダ）
2. サーバーサイドでのデータフェッチ・レンダリングを行わず、すべてのページにSSGを採用したこと。

次に`Firebase Hosting`を選んだ理由としては、
1. 無料枠が大きいこと。DAU（デイリーアクティブユーザー）を確認して、費用感を算出しました。他の候補としては`AWS Amplify`や`S3`×`CloudFront`があるが、費用面で若干`Firebase Hosting`が優位でした。今後DAUが大幅に増加するようであれば、`AWS`へ移行した方がメリットが大きいので、移行も視野に入れています。
2. 全世界にCDNがあること。すべてのページが静的コンテンツで作成するので、自動的にCDNでキャッシュに保存してくれるので、レスポンスが高速になることはありがたいです。また、`Firebase Hosting`の場合デプロイ時に自動でCDNのキャッシュをクリアしてくれるので、常に最新の情報を公開できます。`AWS S3`×`CloudFront`の場合、デプロイ時に自動ではキャッシュがクリアされないので、自分でクリアする必要があり、率直に言うと、、面倒なので今回はラクさせていただきました(笑)。
GoogleのCDNのキャッシュについては[こちら](https://firebase.google.com/docs/hosting/manage-cache?hl=ja)を参照。

他にもドメイン費用が無料であったりと色々メリットが多かったので、`Firebase Hosting`にしました。
みなさんも、脳死で`Vercel`を選んでしまう自分をぶん殴って、クライアントの要件に寄り添いながらベストを尽くしましょう。

# まとめ

次回は実際にNext.jsのプロジェクト作成からCI/CDの構築までサンプルコードを使って紹介できたらと思います。
Rails6.1 + Webpackerでのデプロイの際のアセットコンパイルでのエラーの対処

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提
Rails6.1 + Webpackerで今更感がありますが、まとめておいたことをせっかくなので公開しました。

#　エラーの内容
デプロイの際のアセットコンパイルの際にエラーになってしまい、コンパイルができない状態になっていました。

# 対処法
`config/webpack/loaders/sass.js`を以下の記述で作成します。

```javascript:config/webpack/loaders/sass.js
module.exports = {
  test: /\.s?css/i,
  use: ['style-loader', 'css-loader', 'sass-loader'],
}
```

`config/webpack/environment.js`に以下の記述を追加して、さきほど作ったsass.jsファイルを読み込ませます。

```javascript:config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const sass = require('./loaders/sass') //ここを追加

const webpack = require('webpack')
environment.plugins.prepend(
  'Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    Popper: ['popper.js', 'default']
  })
)
environment.loaders.append('sass', sass) //ここを追加
module.exports = environment
```

これでアセットコンパイルができるようになり、デプロイすることができました。
wsl2(Ubuntu 22.04.2)環境でviteの開発サーバーをhttpsに。

# 概要
localhostでスマホのブラウザのカメラ機能を試してみたかったが、
iOS, Android端末では`https`でないと`navigator.mediaDevices`を利用できなかったため、
ローカル環境で`https`を利用できるようにするために`mkcert`を使用したときの備忘録。

[getUserMedia()で静止画を撮影する](https://developer.mozilla.org/en-US/docs/Web/API/Media_Capture_and_Streams_API/Taking_still_photos#using_specific_devices)

# 補足
このプラグインのほうが簡単そう

https://github.com/vitejs/vite-plugin-basic-ssl

# 環境

```bash:環境
$ uname -a
Linux <pc_name> 5.15.90.1-microsoft-standard-WSL2

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy

$ sudo lshw -class processor
  *-cpu                     
       product: AMD Ryzen 7 6800U with Radeon Graphics
```

# 必要なパッケージをインストール
[パッケージ:libnss3](https://packages.debian.org/ja/sid/libnss3)
> これは、セキュリティを考慮したクライアント・サーバアプリケーションのクロス プラットフォームな開発の補助を目的としたライブラリ群です。SSLv2 および v4, TLS, PKCS #5, #7, #11, #12, S/MIME, X.509 v3 証明書や、その他のセキュリティ 標準に対応しています。

```bash
$ sudo apt install libnss3-tools
```

# mkcertを取得

```bash
$ wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.3/mkcert-v1.4.3-linux-amd64
```

# mkcertを/user/bin/にコピー（または移動）し、実行権限を付与

```
$ sudo cp -p mkcert-v1.4.3-linux-amd64 /usr/bin/mkcert
$ chmod +x /usr/bin/mkcert
```

# バージョン確認

```bash
$ mkcert --version
v1.4.3
```

# ローカル認証局を作成

```bash
$ mkcert -install
Created a new local CA 💥
The local CA is now installed in the system trust store! ⚡️
The local CA is now installed in the Firefox and/or Chrome/Chromium trust store (requires browser restart)! 🦊
```

# ローカル認証局を確認

```bash
$ mkcert -CAROOT
/home/<user>/.local/share/mkcert
```

# 証明書を作成

```bash
$ mkdir certs
$ cd certs/
$ mkcert localhost
Created a new certificate valid for the following names 📜
 - "localhost"

The certificate is at "./localhost.pem" and the key at "./localhost-key.pem" ✅

It will expire on 7 September 2025 🗓
```

# 証明書を確認

```bash
$ ls
localhost-key.pem  localhost.pem
```
# vite.config.jsを編集（または作成）

```javascript:vite.config.js
import { defineConfig } from "vite";
import fs from "fs";

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync("./certs/localhost-key.pem"),
      cert: fs.readFileSync("./certs/localhost.pem"),
    },
  }
});
```
# 開発サーバーを起動
`https://~`で起動していること確認

```bash
$ npm run dev
 VITE v4.3.9  ready in 193 ms

  ➜  Local:   https://localhost:5173/
  ➜  Network: https://172.21.214.107:5173/
  ➜  press h to show help
```
【ポエム】ABC304参加記

# [A - First Player](https://atcoder.jp/contests/abc304/tasks/abc304_a)

ABCのAにしては難しい
- if文とfor文だけでも解けないことはない

まず$ 人_i $について`(年齢,i)`の順番でtupleに格納し
min関数で年齢が最小となる$ i $を求める

円卓の順番を崩さないために、双方向キューを利用した
- 一番左のデータを取り出して一番右に移せるデータ構造
- 双方向でなくてもよいが…

本音を言うと、ACできるか恐々としながら提出した

# [B - Subscribers](https://atcoder.jp/contests/abc304/tasks/abc304_b)
問題文が長い
桁数が1ずつ増えていることを確認してから実装に入った
こういう問題では$ N \in [0,1] $の時がコーナーケースになりがち
- 今回は違ったけど

# [C - Virus](https://atcoder.jp/contests/abc304/tasks/abc304_c)
感染した順番は覚えておく必要がない
- そのため、UnionFindをコピペした
- DFSやBFSでも解ける

距離判定をする場合、両辺を二乗すると実行時間が短くなる
あと`<=`と`<`、`>=`と`>`を間違えるのはやりがち
- 余談だが、sqrtを利用するとfloatの誤差でWAが出る問題が稀にある
- - sqrtを利用しない形に式変形する必要がある

# [D - A Piece of Cake](https://atcoder.jp/contests/abc304/tasks/abc304_d)

異様に悩んでしまった
- 延長された20分の間に天啓が降ってきた
- なんとかコンテスト中にACできた

ケーキの縦分割と横分割を独立に考える
ケーキの切れ目ではなく、切れ目によって分配されるイチゴに注目する
- ケーキの左端（下端）を0個目の切れ目と考える
- それぞれのイチゴについてすぐ左（下）にある切れ目がどこにあるか覚えておく
- あとはPythonのCounterに突っ込む
- - keyがtupleでもちゃんと数えてくれるので便利
- $ \big\[ m=0 \leftrightarrow $ イチゴが1個以上あるピースが $ (A+1)(B+1)$ 個未満$\big\]$に注意

# [E - Good Graph](https://atcoder.jp/contests/abc304/tasks/abc304_e)

慣れないタイプの問題だったが解けて気持ちよかった
- この問題で扱うのは無向グラフであるため
-  $\big\[$点$ x $と$ y $のパスが存在する$\leftrightarrow$連結である部分グラフ$S$が存在して、$x,y \in S\big\]$
-  が成り立つ

オレよく分かんねーけどよ、任意頂点間の**パス存在性**を変えずに分割した時、その分割は一意に定まるんじゃねーか？
- よわよわなので証明できません

とにかく
- UnionFindを使って頑張る
- 分割して、部分集合に付番することで
- <font color="#edb647">「存在したら良さが損なわれるパス」</font>
- <font color="#477eed">「クエリによって生やされる辺」</font>
- - 入力で与えられるやつです
- これらが格段に扱いやすくなる

<font color="#477eed">「クエリ〜」</font>が<font color="#edb647">「存在〜」</font>を生むか判定することで解ける
- 具体的には、tupleをkeyにしたdictを使うとか

# 総括
推定パフォーマンス的には悪くなかったが、unratedとなってしまった
 - 無料でコンテストに参加させてもらえる運営さんには感謝しています

# 余談
考察を紙に残せば「天啓」が来るのを早めることができる
- ……のだろうか？
- - というのも、Twitterに上がっていた考察用紙がそれなりに埋まっていたので
【エラー】Herokuにデプロイできない。

# Herokuへのデプロイエラーとその解決

 Qiita初投稿となります。難しく考えすぎてしまうのでChatGPTを頼りにまず投稿してみます。分かりづらいところ、間違えているところありましたら遠慮なくご指摘ご指導よろしくお願いします。

## 問題の発生

RailsとNode.jsを使ったアプリケーションをHerokuにデプロイする際にエラーが発生しました。具体的には、Herokuでアプリケーションをビルドする際にNode.jsのバージョンが一致しない問題が起きました。

## 問題の特定

エラーメッセージを確認すると、Node.jsのバージョンに関連した問題が原因であることがわかりました。Herokuはデフォルトで最新のLTS（Long Term Support）バージョンのNode.jsを使用しますが、私のアプリケーションでは異なるバージョンのNode.jsが必要でした。

## 解決策

### Step 1: ローカル環境のNode.jsバージョンの確認

まず、ローカル環境で使用しているNode.jsのバージョンを確認しました。次のコマンドを実行してバージョンを確認しました。

```bash
node -v
```
## Step 2: package.jsonへのバージョン情報の追加

次に、使用しているNode.jsのバージョンをpackage.jsonファイルに明示的に指定しました。"engines"セクションを追加し、そこにバージョン情報を記述しました。

```json
"engines": {
  "node": "16.x"
}
```
## Step 3: Herokuへの再デプロイ

上記の変更を行った後、再度Herokuにアプリケーションをプッシュしました。Herokuはpackage.jsonの"engines"セクションで指定されたバージョンのNode.jsを自動的に使用するため、エラーは解決しました。

## まとめ

Herokuでアプリケーションをデプロイする際には、使用する技術スタック（今回の場合はNode.js）のバージョンを明示的に指定することが重要であることがわかりました。これにより、ローカル環境とデプロイ先の環境の差異による問題を避けることができます。
[SendGrid] "The from address does not match a verified Sender Identity.・・・"のエラー解決方法

SendGridを使ってメールを送ろうとしたところ、ログに以下のエラーが出ていました。

```
Sendgrid delivery failed with 403: {"errors":[{"message":"The from address does not match a verified Sender Identity. Mail cannot be sent until this error is resolved. Visit https://sendgrid.com/docs/for-developers/sending-email/sender-identity/ to see the Sender Identity requirements","field":"from","help":null}]}
```

文字通り、***送り主のメールアドレスが認証できてないんだろうなー***とは思いつつ、どんな認証方法があるのかきちんと把握できていなかったので、メモとして残しておこうと思います。

# 認証方法
認証には以下の2通りの方法があるようです。

## 1. メールアドレス認証
#### メリット
・設定、認証が簡単
#### デメリット
・テスト用に推奨される認証方法
・From(メール送信者)のメールアドレスの下に“sendgrid.net 経由”という記載や、また送信元・署名元のドメイン情報に“sendgrid.net”という表記が追加される
・同じドメインでもいちいちアドレスを登録する必要がある
#### 手順
SendGridの管理画面 > Settings > SenderAuthentication を開く
![スクリーンショット 2023-06-07 21.53.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/d92b4732-1c18-c929-fc96-993936200cc1.png)
Single Sender VerificationのGet Startedをクリック
![IMG_4971.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/92193709-7a1c-03cb-efb7-36a465b3ce7f.jpeg)

送信者情報を入力し、届いた認証メールのリンクを踏んで認証
![スクリーンショット 2023-06-07 21.54.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/113611ed-ebe1-e336-fe95-8048c241d3d9.png)



## 2. ドメイン認証
#### メリット
・送信元、署名元のドメイン情報がFromアドレスと同一ドメインで、信頼性が上がる。
・迷惑メール扱いもされにくい。
・同一ドメインであればどのアドレスでも送信可能
#### デメリット
・設定が複雑で比較的時間がかかる
#### 手順
SendGridの管理画面 > Settings > SenderAuthentication を開く
![スクリーンショット 2023-06-07 21.53.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/d92b4732-1c18-c929-fc96-993936200cc1.png)
Domain AuthenticationのAuthenticate Your Domainをクリック
![IMG_4971.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/92193709-7a1c-03cb-efb7-36a465b3ce7f.jpeg)
1で設定したいドメインを選択、2はNoを選択
![スクリーンショット 2023-06-07 21.56.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/032dcec9-eb62-1a32-8113-c83cf3416b6d.png)
設定したいドメインを記入
![スクリーンショット 2023-06-07 21.56.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/91e5f935-aa10-8d8f-6f2a-ab3d5842292a.png)
表示されているDNSレコード情報をDNSレコードに追記
![ltFt34ne4kMq4QK1686144410_1686144478.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415437/ddb934b8-d838-88af-f965-7c40a334168a.png)


以上の設定が完了すれば、設定したドメインのどのアドレスでもメールが送信できるはずです。
JavaScriptで$_GETを実装する

# はじめに
JavaScriptでPHPの$_GETのようなことが出来る関数を作ったので紹介します。
# 関数
コピペしてお使いください。見ての通り、とても簡単です。
```js:get.js
function $_GET(arg) {
    return new URL(location).searchParams.get(arg)
}
```
# 使い方
下のように使うことができます。PHPとほぼ同じですね。
```js:main.js
const example = $_GET('example')
```
また、下のように書くことでデフォルト値を設定できます。これもPHPとほぼ同じですね。
```js:main.js
const example = $_GET('example') ?? 'default'
```
# おわりに
指摘、提案、その他のコメントは大歓迎です。
Elixir Nx Pelemay Backend の OnnxToAxonBench を run して Nx のメモリ消費量を実感する


組み込みソフトウェアの有識者や有志の集う高知組み込み会 #6 (2023/06/07 18:00〜) にリモートで参加させていただきました。今回は「[FPGA]と[半導体]」という興味深い話が聞けました。日本語環境でこういった最先端技術の教育を受けられることは大変ありがたいです。ありがとうございます。

https://kochi-embedded-meeting.connpass.com/event/284564

[Elixir]: https://elixir-lang.org/
[FPGA]: https://ja.wikipedia.org/wiki/FPGA
[半導体]: https://ja.wikipedia.org/wiki/%E5%8D%8A%E5%B0%8E%E4%BD%93
[EXLA]: https://hexdocs.pm/exla/EXLA.html
[EXLA.Backend]: https://hexdocs.pm/exla/EXLA.Backend.html
[Nx]: https://hexdocs.pm/nx/Nx.html
[zeam-vm/pelemay_backend]: https://github.com/zeam-vm/pelemay_backend

Elixir言語関連では、登壇者の一人である @zacky1972 先生が、[FPGA] を [Elixir] や [Nx] に関連付けて話をされていました。
そこで現実的に [EXLA.Backend] はメモリ消費量が大きいため、組み込み機器でイゴかすのは厳しいと指摘されていました。論より run 。その時に披露されていたベンチマークを早速 run してみようと思います。

:::note info
@zacky1972 先生からアドバイスをいただきました。ありがとうございます。

> このベンチマークは，EXLAを動かしていません．あくまでNxでの数値です．
なお，EXLAは，Elixirの管理外のメモリを使うので，Bencheeでは，使用メモリを正しく計測できません．

ベンチマークはあくまで目安と考えてください。
:::


## やりかた

まずは [zeam-vm/pelemay_backend] プロジェクトを Github からダウンロード（クローン）します。

```
git clone git@github.com:zeam-vm/pelemay_backend.git
```

ベンチマークを収容するディレクトリに入ります。

```
cd pelemay_backend/benchmarks/onnx_to_axon_bench
```

依存関係を解決し、コンパイルします。

```
mix do deps.get, compile
```

ベンチマークのプログラムを RUN します。

```
mix run -e "OnnxToAxonBench.run"
```

3つのファイルが比較に使用されます。45MB の モデルふたつと 比較的大きめ（171MB）の [ResNet] モデル　のファイルひとつです。この [ResNet] モデルは 1000 クラスの画像を高い精度で分類できるそうです。

[ResNet]: https://github.com/onnx/models/blob/main/vision/classification/resnet/README.md

![CleanShot 2023-06-07 at 08.49.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/ecba9caa-40be-c34e-50ec-31be5ba9f674.png)

![CleanShot 2023-06-07 at 08.32.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/66e8100a-ce5e-dff6-742f-1afaaa693223.png)

実行環境等がプリントされます。

![CleanShot 2023-06-07 at 19.37.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/3cbd11fb-3e02-c1a3-5731-d9f550cef4b4.png)

結果はこんな感じです。

![CleanShot 2023-06-07 at 08.30.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/bb8dd61e-4f0b-e6be-09c5-cbb9e0e51394.png)

 [ResNet] モデルを [Nx] でイゴかした場合に 9GB ものメモリを消費しうる事がわかりました。組み込み機器で使うのが容易でない事が想像できます。

## PelemayBackend(第2版)

これを解決し、組み込み機器でもバリバリ [Elixir] と [Nx] で AI できる環境を整える試みが、「PelemayBackend(第2版)」と理解しました。詳しくは [PelemayBackend(第2版)のコンセプト](https://zacky1972.github.io/blog/2023/05/26/pelemay_backend.html) をご覧ください。

## Elixir Chip

以前からウワサになっている Elixir Chip の実現へも着々と進んでいる明るい雰囲気を感じました。夢と希望でいっぱいで元氣がでます。ワクワクします。

https://qiita.com/piacerex/items/b99baebf284243fb6d6b

## コミュニティ

[Elixir]、[Nx] や [PelemayBackend][zeam-vm/pelemay_backend] にご興味のある方はぜひお気軽にお立ち寄りください。

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

https://elixir-lang.info/topics/entry_column

https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian
EC2 + Rails + Nginx + Puma + MySQLでのチューニング

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提

EC2で動いているRailsアプリケーションで、多くの同時接続を捌けるようにするためにチューニングをしました。
その際にどこの設定を考慮するのかや参考になった記事をまとめました。

前提として以下の記事を読めば、詳細などを知ることができます。

https://tech-book.precena.co.jp/software/backend/ruby-on-rails/rails-process-and-thread

# 考慮することの大枠は以下の5つ
- Linux（EC2）の設定
  - バックログの最大値の設定
  - ファイルディスクリプタの最大値の設定
  - vCPUの数
  - メモリ容量（RAM）
- Nginxの設定
  - ワーカー数
  - スレッド数
  - リミット数
- Pumaの設定
  - ワーカー数
  - スレッド数
- Railsの設定
  - DBのコネクションプール数の設定
- MySQLの設定
  - MaxConnection数

# 参考記事
https://tech-book.precena.co.jp/software/backend/ruby-on-rails/rails-process-and-thread

https://qiita.com/sakusrai/items/5e3e9b9475d7ff3ba64e

https://qiita.com/sakusrai/items/5e3e9b9475d7ff3ba64e

## 同じような構成でのチューニング

https://qiita.com/fritz22/items/fcb81753eaf381b4b33c

https://tech.unifa-e.com/entry/2020/08/28/161733

https://qiita.com/snaka/items/029889198def72e84209

## Nginxのアーキテクチャ

https://blog.mosuke.tech/entry/2016/06/04/180122/

https://qiita.com/kamihork/items/296ee689a8d48c2bebcd

## Nginxの設定値

https://study-infra.com/nginx-tuning/

https://qiita.com/toshihirock/items/f3aac142882c9c320b7f

https://log.dot-co.co.jp/nginx-perfomance/

## backlogの設定値
https://qiita.com/sakusrai/items/5e3e9b9475d7ff3ba64e

https://blog.cles.jp/item/12276

https://github.com/puma/puma/blob/master/docs/architecture.md


##　ファイルディスクリプタについて
https://qiita.com/toshihirock/items/78286fccf07dbe6df38f

https://note.dimage.co.jp/blog_011_linuxtuning.html

https://oji-cloud.net/2022/03/16/post-6951/
GitLabのCI/CDパイプラインでvirtualboxを動かす。(gitlab runner - virtualbox executor)

# これは何？

[参考](https://docs.gitlab.com/runner/executors/virtualbox.html)

要約

GitLabのCI/CDパイプライン実行を担うgitlab Runnerには、複数のexecutor（パイプライン実行環境）がある。

virtualbox executorに関する日本語の情報が少なかったため記載。


VMに可能なことはほぼすべて可能であり、スナップショットから実行するため、安定して同じ結果が得られます。

例えば、CI/CDのユースケースとして、
巨大なmavenプロジェクトでdocker imageをbuild, pushするといった用途には、docker executorより向いていると思われます。
（docker でもdoodで出来なくはない）
shell executorでも可能ですが、セキュリティや冪等性に難があるため、このようなユースケースの場合、virtualbox executorが向いています。

蛇足ですが、KVMを使っているproxmox上では特段の設定を必要とせず、ネストした仮想化が使えた。

# 動作に関して
virtualbox executorは、VMの制御以外はssh executorとほぼ同じ挙動になるようで、
単にVMに対してSSHを行っているだけのよう。


# Runnerのインストール・実行
[参考](https://docs.gitlab.com/runner/install/linux-manually.html)

インストール

~~~bash
arch=amd64
curl -LJO "https://gitlab-runner-downloads.s3.amazonaws.com/latest/deb/gitlab-runner_${arch}.deb"
sudo dpkg -i gitlab-runner_${arch}.deb
~~~

systemdに再登録
virtualboxのVMを作ったユーザーを指定
本来これだけで良いハズだが、VMが存在しないと言われてしまったので、.serviceファイルにUser, Groupを追記

~~~bash
your_username=user
sudo gitlab-runner uninstall
sudo gitlab-runner install --user $your_username --config $HOME/.gitlab-runner/config.toml

sudo nano /etc/systemd/system/gitlab-runner.service
# または
sudo sed -i "s/\[Service\]/\[Service\]\nUser\=$your_username\nGroup\=$your_username\n/" /etc/systemd/system/gitlab-runner.service
~~~    


# VMの作成
とりあえずvirtualboxとvagrantのインストール

~~~bash
sudo apt-get install -y vagrant virtualbox
~~~

vagrantでVMを作成

~~~bash
mkdir executor_vm
cd executor_vm
vagrant init generic/ubuntu2004

# 適当に編集
# VM名と、GitLabへの名前解決、ciで必要なツールなど
nano Vagrantfile

vagrant up
~~~

# Runnerの登録

対話、非対話形式に問わず最低限、

- gitlabのURL
- gitlabのトークン
- executor
- VM名
- VMのユーザー名
- VMのパスワード

を指定。
手元の実験環境では、`--ssh-disable-strict-host-key-checking "true"`を指定しないとVMへのSSHに失敗した。
それよりしたの設定項目は任意。

runner登録の例
~~~bash
URL=" your gitlab url "
TOKEN=" your token "
VM_NAME=" your vm name "
VM_USER="your vm user"
VM_PASS="your vm password"

# virtualboxのVMを作ったユーザーで実行している点に留意
gitlab-runner register \
      --non-interactive \
      --url "$URL" \
      --registration-token "$TOKEN" \
      --executor "virtualbox" \
      --virtualbox-base-name "$VM_NAME" \
      --ssh-user "$VM_USER" \
      --ssh-password "$VM_PASS" \
      --ssh-disable-strict-host-key-checking "true" \
      --description "virtualbox-runner" \
      --maintenance-note "Free-form maintainer notes about this runner" \
      --tag-list "virtualbox" \
      --run-untagged="true" \
      --locked="false" \
      --access-level="not_protected"
~~~
vimの基本操作について

# Vimってなに
Vimはテキストエディタの一種でプログラミング言語ではありません。
> Vim（ヴィム。「ヴィアイエム」という読み方は誤り）は、vi から派生し、発展した高機能なテキストエディタである。
Vimという名称は、オリジナルのviエディタに近づくことを目標として、開発当初Vi IMitation（viの模倣）の略とされていた。しかし、やがてviを超えることを目指してVi IMproved（viの改良）とされるようになり、今日ではオリジナルのviを大きく上回る機能を持つに至っている。(脚注：https://ja.wikipedia.org/wiki/Vim ）

Atom、VSCodeがGUI（マウスとかで操作できる）なのに対し、**Vim**はCLI（ターミナルでコマンド操作）です。

# nvimってなに
NeoVimの略称がnvimです。
Vimができることは、ほぼNeoVimでできます。
使い方やコマンド操作もほぼ一緒です。
なので今から勉強を始める方は、nvimを使いましょう。


# メリット
メリットしては下記の三つになります。

・マウスやパッドを使わないので、作業効率が上がる
・サーバー内で操作可能
・コードを修正が簡単

# 4つのモード
1. ノーマルモード
2. インサートモード
3. コマンドモード
4. ビジュアルモード

それぞれのモードについて見て行きましょう

### 1. ノーマルモード
vim立ち上げ時のデフォルト画面のことで
改行、行の削除・挿入、コピペができます。

### 2. インサートモード
ノーマルモードの時に、「i」をクリックするとインサートモードになります。
ファイルの編集で使います。

### 3. コマンドモード
ノーマルモードで「:」を押すとコマンドモードになり
保存、終了ができます。

### 4. ビジュアルモード
コピペや削除で使用するモードで範囲選択などができます。


# コマンド操作
それでは具体的なコマンド操作を見ていきましょう。

### ファイル設定
| コマンド（カーソル移動） | 動き |
|:-:|:-:|
|  i | Insert Mode  |
|  esc |  Normal mode |
|  :w |  上書き保存 |
|  :q | 編集終了  |
| :q!  |  保存しないで編集終了 |
|  :wq |   保存して終了|
|  a | 次の文字からInsert mode  |
|  :5 | 5行目に移動  |
|  0 | 先頭に移動  |
|  $ | 行末に移動  |
|  ＾ | インテント䛾先頭に移動  |

### Normal mode 
| コマンド（カーソル移動） | 動き |
|:-:|:-:|
|  h  | ←に移動  |
|  j |  ↓に移動 |
|  k |  ↑に移動 |
|  l  | →移動  |
| x |  1文字削除 |
|  dd |   1行削除 （コピー可能）|
|  dw | 単語の削除  |
|  2 dd|  2行削除 |
|  u |  Undo |
|  Control + r  |Undo redo   |
|  yy |   1行コピー|
|  p | 下にペースト  |
|  P|  現在行にペースト |
|  2 yy |  2行コピー |
|  .  |Repeat   |

全部で約2000コマンドあるらしいのですが、
上記のコマンドを覚えていれば基本的な操作はできます。

# プラグイン
vimの操作を勉強していると
マウス使わなくていいから効率は上がるけど
最低限過ぎるなあと思っていたあなたに...（わたしもです）

https://github.com/junegunn/vim-plug

はい！そうです、もちろんプラグインがあります。

### NERDTree
https://github.com/preservim/nerdtree

### fzf
https://github.com/junegunn/fzf

などあったら良いのになというものは
すでにあるのでぜひ探して自分好みにカスタマイズしましょう。

# 最後に
Vimを習得するにはとにかく慣れるしかないので
マウスを触りたい手を抑えてコマンド操作ガシガシ使っていきましょう！
ubuntuに動画編集ソフトopen shotをインストールしてみた

参照サイト
https://www.openshot.org/ppa/

安定版をインストールする
```shell
$ sudo add-apt-repository ppa:openshot.developers/ppa
$ sudo apt update
$ sudo apt install openshot-qt python3-openshot
```


無事インストールできた
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/9ce383c0-6f73-9ef8-990f-8d0ea1362ad7.png">
HTMLファイルを配布したい

# はじめに

HTMLファイルを配布するなんて普通の人は考えないでしょう。
Webページとして提供するべきだからです。

しかし、もしかしたらHTMLファイルを直に渡したい人がいるかもしれません。
この記事では、配布するHTMLファイルに画像を埋め込む方法を紹介します。

# 結論

以下のPythonスクリプトを使ってください。
HTMLファイルと画像ファイルはローカルに保存されていることが前提です。

使い方は`python script.py --help`で表示されます。

```python
import argparse
import base64
import re
from pathlib import Path

# parse command line arguments
parser = argparse.ArgumentParser(description='Convert images in HTML into Base64')
parser.add_argument('input', type=Path, help='input HTML file path')
parser.add_argument('-o', '--output', type=Path, help='output HTML file path')
args = parser.parse_args()

input_path: Path = args.input
output_path: Path = args.output
if output_path is None:
    stem = input_path.stem
    output_path = input_path.with_stem(stem + '_')

parent_path = input_path.parent

# load a HTML file
with open(input_path, 'r') as f:
    input_html = f.read()

# convert an image data into a data url
def path2base64(match):
    img_src = match[2]
    img_path: Path = parent_path / img_src

    try:
        with open(img_path, 'rb') as f:
            img_type = img_path.suffix.strip('.')

            img_data = f.read()
            base64_data = base64.b64encode(img_data).decode('utf-8')

            new_img_src =  f"data:image/{img_type};base64,{base64_data}"
            return match[1] + new_img_src + match[3]
    except:
        return match[0]

# replace `src` attribute value of `img` element
output_html = re.sub(r'(?ims)(<img.+?src\s*=")([^ "]+?)(".*?>)', path2base64, input_html)

# save as a new HTML file
with open(output_path, 'w') as f:
    f.write(output_html)
```

# 解説

正規表現でimg要素のsrc属性を抜き出し、パスをデータURLに変換しているだけです。

# おわりに

これで晴れてHTMLファイル単体で送れるようになりましたね（JSやCSSも埋め込まれている限り）。
Store 非経由でWSLをインストールした場合の再インストール方法

# 背景
MS Store 経由せずに WSL をインストールしていたが、環境リセットしたかったのでその方法の備忘録

アプリの設定で、リセット／アンインストール出てたので試したところダメ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/340e9ebc-e3b8-6cac-a0e6-7f680f0f63bb.png)

# 解決法

> wsl --help

ヘルプを確認すると以下が見つかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/efbc4a96-10f3-d5e0-ac50-9188259825a3.png)

ってことで、<code>--unregister \<Distro></code> を利用すれば、問題なく削除出来る。

削除出来たら、再度インストールすれば、WSL環境がきれいになります。
綺麗になったら、インストールは以下で。

https://qiita.com/baku2san/items/6e09a0dc2f38b1e3ab9b
サーバー側でバリデーションメッセージを解決する

既存の（比較的簡易な）登録機能があって、一括登録機能を追加開発したい。
エラーはファイルとして返却する。
既存のBeanValidationを流用したい。

と、なったときに困ったのがエラーメッセージ。
Springでは適当にリクエストを受け付けるメソッドのパラメーターとしてBindingResultを設定したり、@ValidateをつけたFormを用意しておけばよしなにバリデーションをかけられるし、メッセージはview側で解決できる。
JSPでは（確か）`<form:error>`で表示できる。

が、今回はサーバー側でメッセージを解決せねばならない・・・。
幸い、`MessageSourceResolvable`を実装しているようなので、
```
@Autowired ms: MessageSource
@Autowired validator: Validator

/* formに値をつめるとして */
val e = new BeanPropertyBindingResult(form, "form")
ValidationUtils.invokeValidator(validator, form, e)
val msges = e.getFieldErrors.asScala.toSeq.map(e => ms.getMessage(e, Locale.JAPAN)

```

みたいな感じで解決できた。
電卓アプリは初心者卒業の登竜門

## はじめに

よくプログラミング演習や初心者向けスクールなどで、総合演習として「電卓」を作成する課題を与えられることは少なくないと思います。
電卓は簡単そうに見えて初心者には意外と実装の難しいアプリで、市販の電卓に機能が近くなればなるほど難易度が上がります。
どこまで市販電卓との機能を近づけられるか？それをいかに複雑でない構造のコードで実装できるか？が電卓アプリ実装の大きな壁になるとともに、不具合のないすっきりしたコードで実装できれば脱初心者認定しても良い題材であると思います。

本記事はそのような電卓アプリを設計、実装するにあたっての考え方を解説します。もちろん本記事で紹介する方法が唯一無二ではなく、なるべく初心者レベルでも実装と理解がむずかしくなく、かつ特定のプログラミング言語に依存しない考え方を紹介いたします。

## 前提知識

以下の用語に1つでも聞き覚えがない、理解度が低いモノがあればまだ電卓アプリの実装は時期尚早と考えます。復習しましょう。

- スタック
- 状態遷移
- ifまたはswitchによる場合分け

## 電卓アプリの基本設計

おそらく一般的な最低限の機能を持った電卓のレイアウトは以下のような画像であると思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653626/5a237cf1-02bd-2c1e-329a-102d2ed9edf3.png)

- **Display**: 計算結果や入力過程を表示するディスプレイ
- **NumberButton***: 0～9、小数点を入力する数字キー
- **OperatorButton**: 加減乗除、計算結果を表示する"="キー等、演算子キー
- **ClearButton**: クリアキー "C" （電卓によっては"AC"）

## 具体的な実装

最初の段階として、"xxx + yyy = "のように毎回"="で計算結果を出すようにするパターンを考えます。

### 用意する状態変数

- **buffer** : 入力途中の数字が入る
- **stack** : 式の左辺と右辺として入力が確定した数値が入る配列
- **operator** : 入力された演算子が入る

### 状態遷移図

```mermaid
graph TB
  Start([開始])-->B[左辺キー入力]
  B-->|Number| C{入力値は数値として妥当か}
  C-->|Yes| D[bufferに追加]-->B
  C-->|No| B
  B-->|Operator| Ope[operator変数にセット]-->ST[stackにbufferを追加]-->CLBF[bufferを空にする]-->B2[右辺キー入力]
  B2-->|Number| C2{入力値は数値として妥当か}
  C2-->|Yes| D2[bufferに追加]-->B2
  C2-->|No| B2
  B2-->|"="| ST2[stackにbufferを追加]-->EQ[stackとoperatorで計算]-->End([End])
```

### 開始

開始状態は「左辺の数値入力」からとなります。

### 数字入力の扱い

数字ボタンを押された場合、buffer変数に数字をどんどん追加していきます。
その際、buffer変数の中身が「数値表現として妥当か」を考えなければいけません。
今回の電卓は、数字を入力する分にはどれを入力しても大丈夫ですが、小数点を入力した際は小数点込みの文字列が数値にきちんと変換できるかどうかをチェックしなければなりません。
簡易に実装するのであれば、「小数点が2つ以上存在しない」ことが確認できれば問題ないでしょう。

- 123..
- ..
- 1.2.

などといった表現は数値として適切でないので、こうなる場合は入力された小数点をbufferに追加しないという条件分岐が必要になります。

### 演算子入力の扱い

プラス、マイナスなどの演算子が押された場合、bufferに入っている文字列をstackに追加します。
stackは配列で、`stack[0]`が式の左辺、`stack[1]`が式の右辺の扱いとします。
また押された演算子を`operator`変数に入れておきます。最後の計算で使用します。
stackにbufferの内容を移したらbufferは空にして右辺の数値入力の状態になります。

### "="が押された場合

右辺にも数値を入力し、"="が押されたら`stack`に`buffer`の数値を追加し、計算をする処理に入ります。
`operator`変数の中身が何かによって条件分岐を行います。
`operator`が"+"だったら`stack[0]`と`stack[1]`を足し算してdisplayに表示させる、"-"だったら`stack[0]`から`stack[1]`を引いてdisplayに表示させる、という処理を行います。

計算結果を表示したら、新しい計算をするために`stack`と`operator`,`buffer`の中身を空にしておく必要があります。以前の入力状況が残っていたら次の計算に支障が出ます。

## 発展的な実装

### 繰り返し演算

通常の電卓は、"1 + 2 + 3 + 5 + ..." というように連続して計算を行うことができます。
上記の処理をどのように改良すればこの機能が実現するか考えてみてください。

2度目の演算子を押されたかどうかは `operator`の中に既に演算子が入っているかどうかで判別できます。
その場合は、

- "="が押された時と同じように計算結果を算出する
- 計算結果を`stack[0]`に入れて、`stack[1]`は空にする
- `operator`変数には、2度目に押された演算子をセットする

という処理を行うことにより、状態遷移図の「右辺キー入力」の状態に戻すことができます。
この状態から続けて数字を入力して計算を行うことができるはずです。
ubuntu(virtual box)とwindows(ホスト)でファイル共有をしてみた


# Guest Additionsをインストールする

## Guest Additionsをマウントする
<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/bc97ef6d-d65c-5336-3082-fd1b25dac416.png">

## 実行する
```shell
$ cd /media/`username`/VBox_GAs_0.0.0/
$ sudo ./VBoxLinuxAdditions.run

```


# vboxsfグループへユーザー追加する
```shell
$ sudo gpasswd -a `username` vboxsf
```

# 共有フォルダを設定する

<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/4fbbd45d-105f-afe1-fe06-212bca731fc6.png">

<img width="400" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106311/755378d0-8b83-7ca3-9be5-ce1a52082f14.png">

- フォルダのパスにはwindowsのフォルダ
- フォルダ名は自動入力される
- マウントポイントはubuntuのディレクトリ
変数の使い方（TeX・Tikzで数値計算）

# 変数の使い方（TeX・Tikzで数値計算）

$$
\def\DIS{\displaystyle}
\def\fraction(#1/#2){\frac{#1}{#2}}
\def\ff(#1/#2){\frac{#1}{#2}}
\def\dd#1#2#3{\frac{d ^{#1}#2}{d #3^{#1}}}
\def\pdd#1#2{\frac{\partial ^{#1}#2}{\partial #3^{#1}}}
\def\bi#1#2{{}_{#1}\! \, \mathrm C_{#2}}
\def\bm{\boldsymbol}
$$

TeXで数値計算をするときは，2種類の変数の使い方があります。次のように定義します。

```tex
\def\hogehoge{数値}
```

```tex
\tikzmath{
    \tikzhoge = 数値;
}
```

数値計算は`\tikzmath`内で行うので，後者の変数を使う方が便利です。

しかし，`\tikzmath`の変数は，環境をまたいだりすると数値を忘れてしまうことがあります。次のように，0,1,2,3,4を表示するTeXを書きます。

```tex
\def\stepA{5}
\newcount\countA

\tikzmath{
    \tikzhoge =0;
}

\countA = 0 \loop\ifnum\countA < \stepA
{
    \begin{preview}
        \tikzhoge
    \end{preview}

    \tikzmath{
        \tikzhoge = \tikzhoge + 1;
        }
}
\advance\countA by1\repeat
```

これを実行すると0が5個表示されます。`\tikzhoge`に1ずつ足した結果が有効になっていません。

次のように変更して，数値を忘れないようにします。

```tex
\def\stepA{5}
\newcount\countA

\tikzmath{
    \tikzhoge =0;
}

\def\hogehoge{\tikzhoge}

\countA = 0 \loop\ifnum\countA < \stepA
{
    \begin{preview}
        \hogehoge
    \end{preview}

    \tikzmath{
        \tikzhoge = \hogehoge;
        \tikzhoge = \tikzhoge + 1;
        }

\global\edef\hogehoge{\tikzhoge}
}
\advance\countA by1\repeat
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349076/d173a696-6442-e729-d9a6-436da1458316.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349076/fe873c63-b85e-918b-efea-65f931fe6bb1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349076/6a22a351-5af4-d410-9930-a03d3d1b701e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349076/0d52b9d9-e9d3-3518-47f7-a144459bd36a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/349076/8c2d1224-0566-d568-893c-73702197dac6.png)


と表示されます。

`\global`はTeX文章内全体で有効にする，`\edef`は数値を代入するという意味で，この2つを組み合わせます。

## 変数に番号をつける・配列 \expandafter

`\def`，`\edef`は次のように使うことはできません。

```tex
\foreach \x in {1,...,5}{
    \global\def\csname hogehoge[\x] \endcsname{\tikzhoge}
}
```

`\x`の数値を有効にしなければいけません。次のように`\expandafter`を入れます。

```tex
\foreach \x in {1,...,5}{
    \global\expandafter\def\csname hogehoge[\x] \endcsname{\tikzhoge}
}
```


`\tikzmath`の変数にも番号をつけることができます。
```tex
\tikzmath{
        \tikzhoge{1} =1;
        \tikzhoge{2} =2;
            }
```

ただし，次のような事はできません。

```tex!
\foreach \x in {1,...,5}{
    \global\expandafter\def\csname hogehoge[\x] \endcsname{\tikzhoge{\x}}
}
```

理由は分かりませんが（\xの取る値が整数型ではないのが理由かも），少々面倒ですが整数型の変数を導入し，カウンターを用いて解決します。

```tex
\countB = 0 \loop\ifnum\countB < 2
{
    \tikzmath{
        int \tikzcountB;
        \tikzcountB = \countB + 1;
    }
    \global\expandafter\edef\csname hogehoge[\tikzcountB] \endcsname{\tikzhoge{\tikzcountB}}
}
\advance\countB by1\repeat
```

`\foreach`では，整数形の変数を用いても解決しませんでした。