OmniAICreator/Qiita-1.07M huggingface dataset:
Slack API の使い方

#temperature というチャンネルが次のようになっていた時の操作です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/49399868-daff-f3bc-bfde-ea78706f8cdd.png)

## Token の取得
　App の作成
　Scope の追加

## Token が有効かの確認

https://api.slack.com/methods/auth.test/test
https://api.slack.com/methods/conversations.list/test

次のスクリプトでも確認が出来ます。

```bash
TOKEN="xoxp-22829108884-22835664966-5533445229095-145fdab56b******"
#
URL_A=https://slack.com/api/auth.test?pretty=1
#
curl -H GET $URL_A -H 'Content-Type:application/json;charset=utf-8' -H 'Authorization: Bearer '$TOKEN
#
URL_B=https://slack.com/api/conversations.list?pretty=1
#
curl -H GET $URL_B -H 'Content-Type:application/json;charset=utf-8' -H 'Authorization: Bearer '$TOKEN
```

## channel_id を調べる
右クリックで、「チャンネル詳細を表示する」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/dfe2345b-6f33-3a73-0928-291806d81406.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/ae9b4124-df0d-23ac-b089-f27a33493475.png)

## メッセージの一覧

```bash:list_slack.py
#! /usr/bin/python
#
#	list_slack.py
#
#					Jul/08/2023
#
import requests

def list_slack_messages(channel_id, token, limit=20):
	url = "https://slack.com/api/conversations.history"
	headers = {
		"Authorization": f"Bearer {token}",
		"Content-Type": "application/x-www-form-urlencoded"
	}
	params = {
		"channel": channel_id,
		"limit": limit
	}
	response = requests.get(url, headers=headers, params=params)
	if response.status_code == 200 and response.json().get("ok"):
		messages = response.json()["messages"]
		for message in messages:
			str_out = message["ts"] + "\t" + message["text"]
			print(str_out)
	else:
		print(response.json())
		print("メッセージの取得に失敗しました。")

# 使用例
channel_id = "C05FH3HQ***"
token = "xoxp-22829108884-22835664966-5533445229095-145fdab56b******"
list_slack_messages(channel_id, token)
#
```

## メッセージの削除

```py:slack_delete.py
#! /usr/bin/python
#
#	slack_delete.py
#
#					Jul/08/2023
#
import requests

def delete_slack_message(channel_id, message_ts, token):
	url = "https://slack.com/api/chat.delete"
	headers = {
		"Authorization": f"Bearer {token}",
		"Content-Type": "application/json; charset=utf-8"
	}
	data = {
		"channel": channel_id,
		"ts": message_ts
	}
	response = requests.post(url, headers=headers, json=data)
	print(response.status_code)
	print(response.json())
	if response.status_code == 200 and response.json().get("ok"):
		print("メッセージを削除しました。")
	else:
		print("メッセージの削除に失敗しました。")

# 使用例
channel_id = "C05FH3HQ***"
message_ts = "1688795734.342379"

token = "xoxp-22829108884-22835664966-5533445229095-145fdab****"

delete_slack_message(channel_id, message_ts, token)
```
(BizRobo!)内蔵ブラウザ(Webkit)でサポートしないJavaScriptを一部実行可能にする方法(Polyfill/ポリフィル)

# はじめに
BizRobo!の内蔵ブラウザのWebkitでは、JavaScriptの規格であるECMAScript 5はサポートしていますが、
ECMAScript 6で追加された記法は対応していません。
そのため、新記法で書かれたJavaScriptを利用しているWebシステムの操作をうまくできないことがあります。

その場合、内蔵ブラウザの一つであるChromiumブラウザやデスクトップ上のブラウザを起動して操作する等の方法もあるのですが、
Webkitのままでも、v10.4から追加されたポリフィル(Polyfill)機能により、ECMAScript 6の一部が実行可能になっています。

今回はその設定方法について記載します。
公式ナレッジにそういう記事がなくて他のメンバーに共有できなかったので、半ばそのためのメモ書きな感じです。


# 設定方法
まず、ロボットを開き、ロボット設定を開きます。
![ロボット設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/1d33d3da-d02e-ef18-01ef-85d63298e3b4.png)

デフォルトオプションの「設定」から
![デフォルトオプション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/71f975a3-641b-0893-f81f-6ebd72f60d6e.png)

「JavaScript実行」タブに移動後「JavaScriptポリフィル」の「+」をクリックし「すべて」を選択
![ポリフィル追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/671d6a5d-0b26-bb33-788a-d03e133f5647.png)

これでポリフィルの設定ができます。

また、変数宣言でECMAScript 6から追加された「let」を使用している場合もありますので、「var」に置き換えることで動くこともあります。
こちらも設定してみましょう。

「JavaScript変更」のの「+」をクリックし「テキストフォーマット」⇒「テキストの置き換え」を選択
![テキストの置き換え選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/dea1149c-c71f-b36d-1590-52ebfe7c6ad9.png)

「let 」を「var 」に置き換えるよう設定します。
![let置換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/c8eadb08-b459-c23f-fe06-f3bdb826c718.png)

必ず、「let」にも「var」にもそれぞれ後ろに半角スペースを入れるようにしてください。
でないと、変数宣言時だけでなく、JavaScript中に「let」の文言が入っているものがすべて置き換わってしまいます。

これで設定は完了です。

しかし、これでもうまく動かないものは多々ありますし、
その後のWebシステムの改修でもやはり動かなくなることがあります。
また、他にもうまく動かない場合の対処は色々あります。

その場合はまた別の方法を試したり、Chromium等での操作を試してみましょう。
BizRobo!CAMPUS!!の第7回 Chromium編では、今回のポリフィルの設定方法以外にも、
その他の対処方法やChromiumの使い方について分かりやすく解説しています。
興味のある方はそちらも見てみてください。

# 参考リンク
＜ナレッジ＞
・内蔵ブラウザエンジン（Webkit/Classic）でサポートしていないJavaScript
https://knowledge.bizrobo.com/hc/ja/articles/360031148771

＜BizRobo!CAMPUS!!＞
https://portal.bizrobo.com/ja/%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88/bizrobo_campus
WSL で Ubuntu のユーザーパスワードを忘れた場合のリセット方法

# はじめに

久しぶりに WSL を起動して Ubuntu で sudo しようとした際にパスワードが分からなくなってしまいました。

# リセット方法

以下のコマンドで root ログインする。

```powershell
wsl -u root
```

以下のコマンドで [username] にリセットしたいユーザー名を入れる。
新しいパスワードを求められるのでリセットする。

```bash
passwd [username]
```
【Flutter】グラデーションカラーを描画する

# 何の記事か
私が運用している、Flutterで点線の描画を簡単に行えるようにするパッケージ`dotted_line`に、グラデーションで点線を描画できる機能を追加しました。
この記事では、点線にグラデーションを付ける機能をどのように実現したかをご紹介します。

https://pub.dev/packages/dotted_line

https://github.com/umechanhika/dotted_line

# 何故作ったのか
きっかけはコントリビューターが挙げてくださったIssueでした。

https://github.com/umechanhika/dotted_line/issues/36

「グラデーションを追加したらもっと良くなるよ」との提案に賛同して開発に取り組み始めました。

# どう実現したか
グラデーションといえば、最初に描画された色から徐々に別の色に変化していくものを想像すると思います。
これをRGBA値に当てはめると、始点のRGBA値と終点のそれとの差分を割り出し、その差分を点線の数で割った値が点線の点1つ単位の変化量と捉えらることができます。
その変化量分だけ各点ごとのRGBA値を増加させていけば、点線でグラデーションを描画できるというわけです。

例）255個の点で描画される点線において、白(R:255, G:255, B:255)から黒(R:0, G:0, B:0)に向かってグラデーションする場合

```
以下は、RGBそれぞれで共通
255(始点) - 0(終点) = 255(差分)
255(差分) / 255(点の数) = 1(点1つ単位の変化量)
```

これをコードに落とし込むとこうなります。

```dart
  // 各点に設定する色を算出するメソッド。
  // List.generateメソッドのgenerator内で呼ばれて、各点のindexが受け取れる前提
  Color _calculateGradientColor(
    Color startColor,
    Color endColor,
    int maxItemCount,
    int index,
  ) {
    // RGBAごとに始点と終点の差分を算出
    var diffAlpha = (endColor.alpha - startColor.alpha);
    var diffRed = (endColor.red - startColor.red);
    var diffGreen = (endColor.green - startColor.green);
    var diffBlue = (endColor.blue - startColor.blue);

    // RGBAごとに点1つ単位の変化量を算出
    var amountOfChangeInAlphaPerItem = diffAlpha ~/ maxItemCount;
    var amountOfChangeInRedPerItem = diffRed ~/ maxItemCount;
    var amountOfChangeInGreenPerItem = diffGreen ~/ maxItemCount;
    var amountOfChangeInBluePerItem = diffBlue ~/ maxItemCount;

    // 始点の色に対して点の数だけ変化量を上乗せした色を返却
    return startColor
        .withAlpha(startColor.alpha + amountOfChangeInAlphaPerItem * index)
        .withRed(startColor.red + amountOfChangeInRedPerItem * index)
        .withGreen(startColor.green + amountOfChangeInGreenPerItem * index)
        .withBlue(startColor.blue + amountOfChangeInBluePerItem * index);
  }
```

これにより、下の画像のようなグラデーションが実現できました。
1個目は赤から青にグラデーションさせていて、2個目は赤と青の点線のアルファ値をグラデーションさせています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136368/85a1399b-f361-e441-9d66-7fb7ce7c7272.png)

# 余談
前述のコードのメソッド名を見ていただくと分かるのですが、今回はこの機能のメソッド名やプロパティ名を`gradient`としています。
後から知ったのですが、英語のグラディエント(gradient)とグラデーション(gradation)は厳密には別の意味らしく、グラディエントは勾配でグラデーションは段階的な変化だそうです。
つまり、今回の実装は厳密にいうと`gradation`に当たりそうです。
stable diffusion afterdetailer で表情を変更

# 何ができる？

・顔をきれいに
・表情を変更

Extensions > Install from URL

```
https://github.com/Bing-su/adetailer.git
```

再起動


# 使い方


きれいにしたい画像をpngInfoに読み込ませ、Send to txt2img

ADetailerに

face_yolov8n.pg を選択

Generate

# 元画像

![00042-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/2cfca722-80c5-5cd9-714a-7cb2f919f36a.png)

# 加工後

![00109-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/ae6c75b9-4388-35c1-9b7b-c48925ac135a.png)

ほっぺたにほくろができてより人間らしくなりました。

# 表情を変更

先程の

ADetailerに

face_yolov8n.pg を選択した、下の枠に表情を入れてみましょう。

より強調するため((()))で区切ります。

# 喜 (((pleasure)))

![00110-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/19b12312-2636-7f2c-4237-73510e189adc.png)

# 怒 (((angry)))

![00112-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/0564a703-6626-6edf-738b-df5b79fa7bcd.png)

# 哀 (((sad)))

![00113-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/c103638b-a959-7e1b-cf05-30e065d7098e.png)

# 楽 (((happy)))

![00114-3824750586.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/dbd6af32-82a1-fbec-3e5a-59a2e0c40e29.png)
ABC300 - D - AABCC 自己解法

# 問題

https://atcoder.jp/contests/abc300/tasks/abc300_d

# 考察
$$a < b < c$$
$$a, b, c:素数$$
$$a^2×b×c^2≦N$$
これらを満たす$a,b,c$の組み合わせはいくつありますかという問題です。便宜上、上から条件①・②・③とします。制約が$N≦10^{12}$と緩いこともあり、どこから手をつければいいか分かりづらいかもしれません。ですが、$a,b,c$について、「大きくてもどれくらいの大きさにしかならないか。」上界を見積もることで活路が見えてくるかと思います。

### cの上界
cについて大きくてもどれくらいの大きさに留まりそうかを考えてみます。条件①・②には当てはまりませんが、仮に$a = b = 1$の場合、条件③は$c^2≦N$となります。すると、$c$は大きくても$10^6$までに留まるが分かります。

### aの上界
aについても考えてみます。条件①に当てはまりませんが、仮に$a = b = c$の場合、条件③は$a^5≦N$となります。正確には計算してませんが、$a$は大きくても$10^3$にもならないことが分かります。

### 計算量的に間に合いそうな方針を考える
今までの内容から、$a$は大きくても$10^3$、$c$は大きくても$10^6$までには留まります。もし、$a$と$c$に対して全探索をした場合、計算量は$10^9$程度になります。これでは計算量的に間に合いそうにありません。しかし、$a$と$c$は条件②から素数です。素数であることを考慮すると$a$になり得るのは多くても約170個、$c$は約78000個です。もし、$10^6$ぐらいまでの素数のリストを事前に用意できれば、$a$と$c$に対して全探索をしても間に合いそうです。
$a$と$c$に対して全探索が間に合うのであれば、「$a$と$c$を固定した時、$b$としてあり得る値は何個あるか？」をそれぞれ求め、合計するという方針がとれます。この方針で考えていきましょう。

ここまでを整理します

:::note info
- $a$は大きくても$10^3$までの素数
- $c$は大きくても$10^6$までの素数
- 下記のことができれば、$a$と$c$に対して全探索して答えを求めることができる
    - 事前に素数のリストを用意する
    - 「$a$と$c$を固定した時、$b$としてあり得る値は何個あるか？」を求める
:::

### 事前に素数のリストを用意する
事前に素数のリストを用意しておく必要があります。素数のリストの求め方については調べると様々な記事が見つかります。それらを参考にして用意していきましょう。

以下の記事が実際に参考になります。

https://qiita.com/drken/items/a14e9af0ca2d857dad23

https://qiita.com/drken/items/3beb679e54266f20ab63

### 「aとcを固定した時、bとしてあり得る値は何個あるか？」
$a$と$c$は固定できています。そうすると、条件③から、$b≦\dfrac{N}{a^2×c^2}$を満たします。これを満たす$b$が何個あるかについては素数のリストがあれば二分探索で求めることができます。あとは、条件①もあることにも注意しておきます。具体的には下記の2点も考慮しておきましょう。

- $a$以下の素数は$b$としてあり得る値に含めないようにする
- $c$以上の素数は$b$としてあり得る値に含めないようにする

これで、「aとcを固定した時、bとしてあり得る値は何個あるか？」を求めることができます。

長くなりましたが、これで$a$と$c$を全探索、そしてあり得た$b$の個数をそれぞれを合計することで答えを求めることができます。
計算量的にも十分間に合います。

# 提出コード(コンテスト後)

https://atcoder.jp/contests/abc300/submissions/43330808

ご不明点などがあれば教えていただけると幸いです。

# 参考

https://qiita.com/drken/items/a14e9af0ca2d857dad23

https://qiita.com/drken/items/3beb679e54266f20ab63
デュアルモニター環境でスクリーンショットが誤作動を起こした時の対処法


## 動作環境
- Windows11
- モニター1(1920*1080)
- モニター2(1280*720)

## 問題
上記環境でsnippingtoolを使用してスクリーンショットを撮ろうとした際に、画面の一部しかスクリーンショットできない問題が発生した。

## 解決策
端的に言うと、モニター2のディスプレイ解像度を推奨の1280*720に戻したら解決した。
原因としては、モニター2を導入した際にディスプレイ解像度とモニターサイズが一致していなかったため、解像度を手動で変更していたことだと考えられる。
コンテナエンジン搭載のArmadillo-IoTゲートウェイ A6Eを触る

__IoTあるじゃん　ALGYAN8周年祭2023__ にて __アットマークテクノ__ の __Armadillo-IoTゲートウェイ A6E__ 
 を頂けましたので少しレビューをしてみます。

https://armadillo.atmark-techno.com/armadillo-iot-a6e/AG6271-C03D0
# Armadilloとは？
Armadilloは、国内メーカであるアットマークテクノ社のLinuxボードです。
RaspberryPiと異なり、産業用に特化したのが特徴で、耐久性、信頼性などRaspberryPiとはターゲットが異なります。
特に起動デバイスとしてフラッシュメモリ（eMMC）が使用できることが特徴と言えます。
そのため、価格も一段高いものとなっています。

https://armadillo.atmark-techno.com/about

Interface 2023年2月号Linux開発＆デバッグ術50では、Armadilloの事例が出てきており
詳しくはこちらをご覧いただくといいかと思います。

https://interface.cqpub.co.jp/magazine/202302/

# 全景
製品の全景です。
ACアダプタのほかに、LTEアンテナや、シリアル接続用のUSBケーブル付属しています。
![A6E-1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/bfa2a225-7fee-ae06-5cc7-c4da41351906.jpeg)
# DINレール対応
DINレールに取り付けた例です。
![A6E-2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/56d4ee82-dc6c-2259-b2d5-d35d5a7cc87d.jpeg)
# Armadillo Base OS とは
__Armadillo Base OS__ は、アットマークテクノが提供する専用ディストリビューションです。
__Linux5.10__ をベースに、コンテナ管理機能、ソフトウェアアップデート機能、ネットワークマネージャーなどに対応。機能を限定したコンパクトなOS で、安全性の高い運用を実現しているそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/3faf204a-51de-2be3-669c-92e91a55e94e.png)
引用：armadillo-iotg-a6e_product_manual_ja
# コンテナ技術
__Armadillo Base OS__ により __コンテナ単位__ でのアップデートが可能なだけでなく、セキュアな環境を維持することができるそうです。
# 豊富なインターフェース
また、各種オプションにもよりますが、以下のインターフェースに対応しているようです。
- LAN
- GPIO
- 接点入出力
- Wi-Fi
- LTE-M
- Serial
- RS485
- USB
- MicroSD
# 分解してみる
端子カバーは爪1個で止まっています。
![A6E-3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/e076f464-fcb0-7c07-64e7-cf79376f4d44.jpeg)
microSDカードスロットは、基板の中心部にあり、交換は推奨しにくいです。
そもそもRaspberryPiと異なりフラッシュメモリ（eMMC）により接触部がないことによる堅牢性があります。
このためmicroSDカードスロットが使いにくい位置にあるのは、設計思想なのかもしれません。（単純にCPUボードのためと思いますが）
![A6E-4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6fca8550-d926-be76-960e-e1fcf0d6f742.jpeg)
# 開発環境
VM Wareによる開発環境が用意されています。
このため、開発環境を構築するという必要もありません。
今までのように、全部自分で用意するものとは大きく異なっており、ハードルは格段に下がったといえます。
# 感想
Armdilloは、ハードルが高いイメージでしたが、今回の製品は、それらを払拭したうえで機能をまとめた製品と言えます。
特にGPIO端子が容易にアクセスできることで、単なるゲートウェイとしてだけでなく、様々に活用しやすい製品なのではないでしょうか？
C#のMSTestでPrivateメソッド、Privateフィールドをテストする

# 1. はじめに
* C# .NET6でPrivateObject, PrivateTypeが使用できないため代替する方法を考える
* MicrosoftのGitHubを参考に、あまり独自のテストクラスにならないようにしたい

# 2. 開発環境
* C#
* Visual Stduio 2022
* MSTest
* Windows 11

# 3. PrivateObject、PrivateTypeクラスの代替
* MicrosoftのGitHubより```PrivateObjectPrivateType.cs```を使用する

https://github.com/microsoft/tstfx/files/4132970/PrivateObjectPrivateType.zip

# 4. Privateメソッドのテスト
## 4.1 テスト対象クラス
```C#:
public Class1() { }

private int Sum(int x,int y)
{
    return x + y;
}
```

## 4.2. テストクラス
```C#:Class1Tests.cs
[TestClass()]
public class Class1Tests
{
    [TestMethod()]
    public void Test_Sum()
    {
        var class1 = new Class1();
        var pbObj = new PrivateObject(class1);
        var actual = (int)pbObj.Invoke("Sum", 1, 2);
        Assert.AreEqual(3, actual);
    }
}
```

## 4.3. テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/21a7945e-4d28-586f-c481-1fe0d7bda034.png)

# 5. Private staticメソッドのテスト
## 5.1 テスト対象クラス
```C#:
public Class1() { }

private static int Sum(int x,int y)
{
    return x + y;
}
```

## 5.2. テストクラス
```C#:Class1Tests.cs
[TestMethod()]
public void Test_Sum()
{
    PrivateType privateType = new PrivateType(typeof(Class1));
    int actual = (int)privateType.InvokeStatic("Sum", 1, 2);
    Assert.AreEqual(3, actual);
}
```
## 5.3. テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/b2e441c3-c2a0-4598-2e75-38349d3c99f1.png)

# 6. 基底クラスのPrivateメソッドのテスト
## 6.1 テスト対象クラス
```C#:BseClass.cs
public class BaseClass
{
    private int Sum(int x,int y)
    {
        return x + y;
    }
}
```
```C#:SubClass.cs
public class SubClass: BaseClass
{
    public SubClass()
    {
        
    }
}
```

## 6.2. テストクラス
```C#:Class1Tests.cs
[TestClass()]
public class Class1Tests
{
    [TestMethod()]
    public void Test_Sum()
    {
        var subClass = new SubClass();
        var pbObj = new PrivateObject(subClass, new PrivateType(typeof(BaseClass)));
        var actual = (int)pbObj.Invoke("Sum", 1 ,2);
        Assert.AreEqual(3, actual);
    }
}
```

## 6.3. テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/342f1904-0fed-d8d4-4e05-9e95f50c6b77.png)

# 7. Privateフィールドのテスト
## 7.1. テスト対象クラス
```C#:MyClass.cs
public class MyClass
{
    private string name;
    public MyClass(string name)
    {
        this.name = name;
    }
}
```

## 7.2. テストクラス

```C#:Class1Tests.cs
[TestMethod()]
public void Test_Name()
{
    var myClass = new MyClass("Hello World");
    var pbObj = new PrivateObject(myClass);
    var name = (string)pbObj.GetField("name");
    Assert.AreEqual("Hello World", name);
}
```

## 7.3. テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/d75a60fb-ac92-4bba-f148-e96cb026ec89.png)

# 8. 参考文献

https://github.com/microsoft/testfx/issues/366

https://www.gesource.jp/weblog/?p=7742
元医療言語処理erが医療ドメインのハッカソンに飛び込んでみた話

2023年7月1日（土）・2日（日）の2日間に渡り開催された Qiita × Fast DOCTOR Health Tech Hackathon に、チーム IC として参加させていただきました。

https://corp.qiita.com/releases/2023/04/qiita-fastdoctor-health-tech-hackathon/

## 自己紹介 & 参加の経緯

普段はソフトウェアエンジニアとして、ノーコードAIモデル開発ツール『[Node-AI](https://nodeai.io/)』のプロダクト開発に従事しています（今回のハッカソンへの参加は、所属する会社を代表するものではありません）。

https://nodeai.io

<br>

今年の3月までは大学院の修士課程で、自然言語処理という分野で研究を行っていました。修論のテーマとは別に、医療分野で日本語の言語モデルを作るプロジェクトに関わっており、最終的には [JMedRoBERTa](https://huggingface.co/alabnii/jmedroberta-base-manbyo-wordpiece) というモデルを HuggingFace で公開するまで至りました。
JMedRoBERTa は 2023 年 7 月現在、日本語の医療分野の言語モデルの中で最も簡単に使えるものであると自負しています。ChatGPT のような生成モデルではないのでテキストを生成することはできませんが、埋め込み(Embedding)の作成などには十分に使えるのではないかと思います。実際、下の記事で紹介されているように、OpenAI の text-embedding-ada-002 よりも性能が上回るケースもあるようです。

https://fintan.jp/page/9002/

<br>

今回ハッカソンに参加した経緯として、自然言語処理を研究していた身からしても、ChatGPT 以後この分野が大きく様変わりしたように感じていたからです。
そもそも LLM が登場する前は、「**日本語**の自然言語処理」「**医療ドメイン**の自然言語処理」はそれぞれ「英語の一般ドメインの自然言語処理」よりもかなり難しい、というのが研究界では常識でした。だからこそ私たちの研究では、日本語の医療ドメインの言語モデルを新しく作り、それが従来の日本語の言語モデルよりもタスク性能がうまくいくことを泥臭く示していたのです。
ところが、ChatGPT が登場してからというものの、もはや誰もが手軽に、言語やドメインを問わず自然言語を処理できるようになりました。こうなると、どうやって自然言語処理をやるかというよりも、自然言語処理を使って何をやるかというアイデア出しがより重要になります。

今回のハッカソンに参加したのは、自然言語処理のある種の「民主化」というフェーズを迎えた今、エンジニア達がどのような新しいアイデアをこの分野にもたらすのかにとても関心があったからです。また、LLM 周りの技術トレンドのスピードは凄まじく、自然言語処理で修士号を取ったというだけでは最早太刀打ちできなくなっているのではないかという危機感も同時にありました。

## 制作物

前置きが長くなってしまいましたが、今回私は医療の入り口である「病院の選び方」というフェーズに着目し、ChatGPT を用いた新しい病院検索サイトを開発してみました。

![スクリーンショット 2023-07-08 16.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233069/51d6afd1-28a3-5fe0-6ba4-635dc6f5b314.png)

![スクリーンショット 2023-07-08 16.46.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233069/a9a71c80-669e-99ef-8ca7-7109b96ff4c8.png)

![スクリーンショット 2023-07-08 16.46.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233069/d9e2d9f6-6d4e-c95f-3872-3e5a02491628.png)

これは、Google Places API により取得できる口コミを、ChatGPT を使って様々な観点から要約する Web アプリケーションになります。このアプリが ChatGPT を通じて提供する価値は以下の2点です。

1. **従来のレビューサイトでは、様々な人が様々な観点からレビューを書いているため、自分の知りたいポイントに絞って情報を得るのにに苦労する（=構造化されていない）。一方、今回作成したアプリでは、「医者・スタッフの対応の丁寧さ」等の特定の観点からレビューを要約できる。**
2. **レビューサイトにはサクラのいる可能性もあるので、Pros / Cons 両方から中立的に情報を得たいが、攻撃的なレビューも多いので読破するのはしんどい。一方、今回作成したアプリでは、メリット・デメリット双方を簡潔に提示できる。** 

なお、要約の部分では以下のようなプロンプトを与えています。

```
以下の口コミから、この病院の「医者・スタッフの対応の丁寧さ、相談のしやすさ」を箇条書きで簡潔にまとめてください。

【レビュー1】
...

【レビュー2】
...
```

Google Places API により取得できる口コミが高々 5 件しかないというのが欠点ではありますが、なかなかうまく ChatGPT は要約するものだなぁと作りながら感心していました。

## おわりに

今回私はソロでハッカソンに参加していたのもあり、元から頭の中で温めていたアイデアをゴリゴリ実装する、という形で参加させていただきました。
他のチームを見ると、医療従事者とのディスカッションをもとに、ダイレクトに医療従事者の悩みを解決するようなプロダクトを開発しており、とても刺激を受けました。特に、最優秀賞チームの ANDEVER さんの、[長谷川式認知症スケールの採点を ChatGPT で行う](https://qiita.com/ryusk/items/9abcb81f66f6cc601eb2)というアイデアはすごく面白いと思いました。
LLM を使ったプロダクト開発は多くの可能性を秘めていそうなので、今後も積極的に参加していきたい所存です。
関数の中にある関数と実引数の関係 JavaScript

首題の通り、**関数の中にある関数と実引数の関係**について、
JavasScriptのレキシカルスコープとスコープチェーンの考察にご利用ください。
**外部スコープ、引数要素と関数コンテキスト内の外部変数との兼ね合いと位置付け**についての考察にお使いいただけるかと存じます。

### 実行してみましょう

jsFiddle（https://jsfiddle.net/ ）
JS Bin（https://jsbin.com/?html,js,output ）

### 1.外側の関数の実引数は、内側の関数の仮引数に勝手に渡らない

``` javascript
      function sample1(str) {
        
        console.log(str);
        
        function sample2(str) {
     
            console.log(str);
          
        }
        sample2();
    }
     
    sample1('hello');
```
> 実行結果
```
"hello"
undefined
```
### 2.内側の関数に仮引数を除くと、レキシカルスコープにより、実引数が内側の関数に渡ってくる。
``` javascript
      function sample1(str) {
        
        console.log(str);
        
        function sample2() {
     
            console.log(str);
          
        }
        sample2();
    }
     
    sample1('hello');
```

> 実行結果
```
"hello"
"hello"
```
### 3.外側の関数で実引数をletで受け取るだけで、内側の関数の仮引数に渡ることはない。
``` javascript
      function sample1(str) {
        
        console.log(str);
        let _str = str;
        
        function sample2(_str) {
     
            console.log(_str);
          
        }
        sample2();
    }
     
    sample1('hello');
```

> 実行結果
```
"hello"
undefined
```
### 4.外側の関数で実引数をletで受け取り、内側の関数で初期値として仮引数に渡せば良い。
``` javascript
      function sample1(str) {
        
        console.log(str);
        let _str = str;
        
        function sample2(str = _str) {
     
            console.log(str);
          
        }
        sample2();
    }
     
    sample1('hello');
```

> 実行結果
```
"hello"
"hello"
```
> NOTE:
> ご指摘や考察がありましたら、ご教示ください。
> 宜しくお願い致します

以上、
【TailwindCSS】アニメーションを作成する

## 作成方法
`tailwind.config.js`に以下のように記述することでアニメーションを作成できます。

```js:tailwind.config.js
module.exports = {
 // ...
  theme: {
    extend: {
      animation: {
        'scale-in-center':
          'scale-in-center 0.25s cubic-bezier(0.250, 0.460, 0.450, 0.940) both',
        'scale-out-center':
          'scale-out-center 0.25s cubic-bezier(0.550, 0.085, 0.680, 0.530) both',
      },
      keyframes: {
        'scale-in-center': {
          '0%': {
            transform: 'scale(0)',
            opacity: '1',
          },
          to: {
            transform: 'scale(1)',
            opacity: '1',
          },
        },
        'scale-out-center': {
          '0%': {
            transform: 'scale(1)',
            opacity: '1',
          },
          to: {
            transform: 'scale(0)',
            opacity: '1',
          },
        },
      },
    },
  },
}

```


## 参考

https://tailwindcss.com/docs/animation#customizing-your-theme

https://tail-animista.vercel.app/play/basic/scale-up/scale-up-center
レンダリング/グラフィック関連のメモ

## Depth Textureの描画
* 困ったこと
  * 描画結果が真っ白になっている
* 対処方法
  * Depthの値はプロジェクション行列のNear/Farを基準に計算されるので、Nearを少し遠くした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461609/27abb93f-0477-35a6-4527-39fc2b28d1cd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461609/5e272a79-c538-82cd-5a77-5709972fca13.png)
【Laravel】プロジェクト作成後の初期設定

# はじめに
この記事は、Laravelプロジェクトを作成後に筆者がやっている初期設定を備忘記録的にまとめたものです。
Laravel9を使用しています。

# 動作環境
* PC：Macbook
* CPU：Intel
* OS：MacOS Ventura 13.4
* Laravel：Laravel9.x, Sail

# 日本語化の設定
`config/app.php`の設定を以下のように変更します。

``` php:config/app.php
'timezone' => 'Asia/Tokyo',
'locale' => 'ja',
'faker_locale' => 'ja_JP',
```

設定変更後、一応以下のコマンドを実行しておくと良いでしょう。

``` terminal
$ sail artisan config:clear
```

次に、各メッセージの日本語化を行います。
以下のコマンドを実行します。

``` terminal
$ sail php -r "copy('https://readouble.com/laravel/8.x/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
$ sail php -f install-ja-lang.php
$ sail php -r "unlink('install-ja-lang.php');"
```

`resources/lang/ja`の下に以下のファイルが出来上がります。
* auth.php
* pagination.php
* passwords.php
* validation.php


# Debug Barの設定
以下のコマンドを実行します。

``` terminal
$ sail composer require barryvdh/laravel-debugbar  
```

`.env`で以下の設定がされているとDebug Barが表示されます。(falseだと非表示になります。)

``` .env
APP_DEBUG=true
```

設定が反映されない場合は以下のコマンドを実行します。

``` terminal
sail artisan cache:clear
```


# IDE Helperを導入
以下のコマンドを実行します。

``` terminal
$ sail composer require --dev barryvdh/laravel-ide-helper
$ sail php artisan ide-helper:generate
$ sail php artisan ide-helper:models
```

<br>

以上です。
Health Tech Hackathonで得た学び【Qiita x FastDOCTOR】

はじめまして、ますみです！

[![自己紹介.png](https://www.umi-mori.jp/wp-content/uploads/2023/02/introduction_banner_2-2048x533.png)](https://bit.ly/banner_intro_masumi_creator_qiita)


本記事では、QiitaとFastDOCTOR主催のハッカソンでの学びを、サクッとまとていきたいと思います。

私たちのチームは、Galirage（ガリレージ）というクリエイターコミュニティにいるメンバー4人で参加し、そこに小児科医の先生がメンターとして入ってくださりました。

（そして、なんと私たちのチームは、Air Podsをゲットしましたぁー！笑）

## 1. ハッカソンのテーマと目的
QiitaとFastDOCTORが主催するこのハッカソンのテーマは、ChatGPTで「医療の労働生産性問題を解決すること」でした。

医療現場での課題解決を目指し、私たちはアイデアを出し、2日間でプロトタイプの開発と、プレゼンテーションを行いました。

イベントの詳細は下記をご参照ください。

https://corp.qiita.com/releases/2023/04/qiita-fastdoctor-health-tech-hackathon/

## 2. プロジェクトの成果
私たちのチームは、医療現場においてビジネスインパクトの大きい課題を解決する機能のAPIをFastAPIで開発しました。

この時、チームとして大切にしたこととして、ユーザーにとってクリティカルなニーズ（ペイン）がどこかを徹底的にヒアリングして、その課題を解決するための要件を精緻化しました。

また、ただAPIを構築しただけでなく、その機能をすぐ導入できる状態（Cross-Originの設定を変えるだけですぐ本番運用ができる状態）にする所まで持って行くことができました。

## 3. チームワークとコミュニケーション
私たちのチームの強みだったこととして、チームワークとコミュニケーションが挙げられると思います。

自分たちのチームは、特にお互いのことを「尊重し合う（Respect）雰囲気があるな」と私は感じました。

それぞれが一人一人の個性を認め合った上で、アイデアソンとハッカソンを遂行できた結果、それぞれの強みが活かせたプロダクトになったと思いました。

## 4. ハッカソンでの反省
ハッカソン後に私が感じた反省としては、現実的なプロダクトではなく、より理想的なプロダクトにドライブするべきだったなと思いました。

普段、医療業界に深く関わっていな私たちだからこそ、独創的でビジョナリーなアイデアを出せるポテンシャルがあり、それを期待されていたのかもしれないと後から気づきました。

## 5. ハッカソンで得た経験とその活用
このハッカソンで得た経験は、「医療現場の切実なペインの理解」と「アジャイルなチーム開発経験」が挙げられます。

この経験は、今後、医療業界における課題解決をする際や、アジャイル開発をチームで行っていく際に大いに役に立つでしょう。

改めて、この素晴らしい機会を提供してくれたQiitaおよびFastDOCTORに深く感謝します。

これからもこの経験を活かし、医療の労働生産性向上に貢献していきたいと思います。

# 最後に
最後まで読んでくださり、ありがとうございました！
いかがだったでしょうか？

この記事を通して、少しでもあなたの学びに役立てば幸いです！

:::note info
【仕事の相談はこちら】
お仕事の相談のある方は、下記のフォームよりお気軽にご相談ください。

[問い合わせフォームはこちら](https://forms.gle/G5g1SJ7BBZw7oXYA7)

もしもメールでの問い合わせの方がよろしければ、下記のメールアドレスへご連絡ください。

info*galirage.com（*を@に変えてご送付ください）

🎁 「生成AI活用の無料相談券」もしくは「生成AIの社内ガイドライン（無料PDF）」を『公式LINE』で配布中 🎁
『生成AIを業務に活用したいけど、どうしたらいいかわからない』といった声を多くいただきます。

Galirageでは公式LINEにて、チャットやオンライン会議で「完全個別の生成AI活用無料相談会」を実施しております！
（期間限定で実施しているため、ご興味ある方はお早めに以下のLINE公式アカウントをご登録ください^^）
https://lin.ee/rvz6lMN

※ 予告なく、キャンペーンを終了する可能性がございますが、ご了承ください。

【業務内容】
具体的には、以下のお仕事を中心に受け付けております！（[詳しくはこちら](https://galirage.notion.site/Galirage-AI-c2f3945fafb0433d8d2fd03e56927fd8)）
1. 受託開発（例：生成AIを使った社内システムの開発）
2. コンサルティング（例：技術戦略のアドバイス）
3. 講演（例：社内研修、イベント登壇）

※ 特に「生成AIを使ったシステム開発のご依頼」が多く、ご好評いただいております。

【これまでの相談事例】
以下のようなご相談が多くあります。

🔑 機密情報を漏洩させないための、生成AIのシステム構築をお願いしたい。
🤖 自社データを用いたFAQチャットボットの作り方を知りたい。
💡 ChatGPTを、自分たちの事業にどのように活かせるか、アドバイスやアイデアが欲しい。
:::
# おまけ
エンジニアの仲間（データサイエンティストも含む）を増やしたいため、公式LINEを始めました🎉

「**一緒に仕事をしてくれる方**」「**友だちとして仲良くしてくれる方**」は、友だち追加をしていただけますと嬉しいです！（仲良くなった人たちを集めて、「ボードゲーム会」や「ハッカソン」や「もくもく会」もやりたいなと考えています😆）

とはいえ、みなさんにもメリットがないと申し訳ないので、特典を用意しました！

友だち追加後に、アンケートに回答してくれた方へ「**エンジニア図鑑（職種20選）**」のPDFをお送りします◎

https://lin.ee/hFUN4TL

[![](https://www.umi-mori.jp/wp-content/uploads/2023/10/line_banner_v2.png)](https://lin.ee/hFUN4TL)
SwiftUIの入門に見るべきサイト

※追記
Swiftを学び初めて1年、ついにiOSアプリをリリースしました!!!
LINEヤフー株式会社様主催のHackU2023でも賞をいただくことができました...!!

・毎日の服の上下の組み合わせを、独自に開発したAIが評価してくれるアプリです
・AIはユーザーの好みに合わせて再学習します
・他にもキャラ育成だったり、シェア機能も搭載しています
https://apps.apple.com/jp/app/kikonashi/id6502258139?l=en-US


# はじめに
2023年3月から深層学習の研究を始め、「深層学習を活かして便利なアプリを作りたい」と思ったのがきっかけで、通学中など、研究の合間にSwiftの勉強をしています。

その時に、勉強の参考になったサイトを紹介します。

[【Xcode】超初心者のためのSwiftUIチュートリアル](#【Xcode】超初心者のためのSwiftUIチュートリアル)
[パッケージ導入管理ツール(SPM)](#パッケージ導入管理ツール(SPM))
[CoremML関連](#CoremML関連)
[Xcodeプロジェクト作成後にCoreDataを有効にする。(データベース)](#Xcodeプロジェクト作成後にCoreDataを有効にする。(データベース))
[WidgetKit入門](#WidgetKit入門)
[MVCとMVVMの違いを理解する](#MVCとMVVMの違いを理解する)
[【SwiftUI】Listの行入れ替え](#【SwiftUI】Listの行入れ替え)
[ファイル保存関連](#ファイル保存関連)
[ その他の実装で参考になるサイト](#その他の実装で参考になるサイト)


ただ、DjangoでWebアプリを開発し、デプロイまで行った経験はあるので、APIやデータベースに対しての知識は元々ありました。

## 【Xcode】超初心者のためのSwiftUIチュートリアル
とても参考になりました。SwiftUIを始める上での注意点なども書かれています。
途中から読んでも分かりやすいです。
https://note.com/nyakko/m/m6c036d624ab2


## パッケージ導入管理ツール(SPM)
APIを利用する際にAlamofireというパッケージを使う必要があり、パッケージ導入に苦戦していた所、このサイト通りに行ったら導入することができました。
https://amefure.com/tech/swift-package-manager


## CoremML関連
深層学習(機械学習)を用いたアプリを作るにあたって、SwiftUIで学習モデルを導入するには、CoreMLを使うのが1つの方法です。
1つ目のサイトの理由は、自分はモデル学習にPyTorchを使っているので、ONNX形式に一度変換してから、CoreML形式にする必要がありました。
2つ目は、CoreMLの実装の参考になりました。
https://qiita.com/studio_haneya/items/be9bc7c56af44b7c1e0a

https://developer.apple.com/videos/play/tech-talks/10154/

## Xcodeプロジェクト作成後にCoreDataを有効にする。(データベース)
SwiftUIのようなモバイルアプリでは、端末上のストレージをデータベースとして用いることかできます(もちろん、Web上のデータベースも用いることもあります)。
そこで、Coredataを使って、データ保存を簡単に行うことができます。
https://qiita.com/araiyusuke/items/65794d24563c68741915

## WidgetKit入門
ロック画面やホーム画面に天気とか表示できる機能です。
https://zenn.dev/naoya_maeda/articles/e5c5af8ec567c9

## MVCとMVVMの違いを理解する
アプリ開発における、ファイルの役割の分担形式です。
MVC・・・Model,View,Controllerの3つの約割に分けられ、
Modelがデータに関わる重要で複雑な処理、Viewは使用者とやり取りする処理、ControllerはModelとViewの仲介(Viewが使用者から受け取った情報を、Modelが受け取れるような状態にして渡す)

MVVM・・・Model,Viewは同じだが、VMがViewModelといい、MVCでのControllerのような働きをするが、Controllerの負担を減らした感じ

https://qiita.com/shunta01/items/ed46b904071841957f8a

## 【SwiftUI】Listの行入れ替え
編集モードを使えるようにして、そこからリストの並び替えをできるようにします
https://capibara1969.com/2281/

## ファイル保存関連
1つ目は丁寧な(？)保存手法です
2つ目は試していないですが、簡潔に書かれています
https://tech.amefure.com/swift-file-manager

https://qiita.com/grainrigi/items/901b528b70bac8a881dc

※2023/7/19 追記
このサイトもわかりやすく、保存から削除まで一通り書かれてるので参考に
https://qiita.com/am10/items/3b2eb3d9f6c6955455b6

## その他の実装で参考になるサイト

### SwiftUIでQRスキャンする
https://qiita.com/h-taro/items/087fe156b63e7dce8af7

### Swiftで絵描きができるライブラリ
https://qiita.com/john-rocky/items/f992fb5c2ce8d8b8516b

### 標準搭載のヘルスケアアプリからデータを取得
睡眠記録、体重、心拍数とか取得できるらしいです
しかもライブラリがあるから簡単にできます
https://qiita.com/hamayu/items/5384770d2edcb257e6eb

### SwiftUI　100本ノック
https://qiita.com/takoikatakotako/items/886604570808bb8fc110???

### iOS16の新機能
https://qiita.com/mashunzhe/items/0ed36d8a6de7c56b1d34

### How to build a linear progress bar in SwiftUI(プログレスバーの実装)
https://www.simpleswiftguide.com/how-to-build-linear-progress-bar-in-swiftui/

### iOS17の新機能
https://qiita.com/mashunzhe/items/3c2ee9d6b8a6065fd117


### ObservedObjectの使い方
https://qiita.com/MilanistaDev/items/64dca8c9d5099a19529e
現在使用中のシェル/ディストリビューションを調べる

VirtualBoxで使用している環境を何にも知らないなあと思ってメモしておく。
調べる事項は以下
1.シェル
2.ディストリビューション/OSバージョン

まずは1.シェルから調べていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733928/cf7b17c1-03a6-669a-a702-9583288a4d0c.png)
bashでした。

続いて2.ディストリビューション/OSバージョン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733928/2832546a-ffdb-a253-68c9-43d6088703ed.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733928/573f65e1-b461-1aed-74fc-7613b526c597.png)


結果
1.シェル・・・bash
2.ディストリビューション/OSバージョン・・・centOS7

以上のことがわかりました。
SSHのセットアップ

# SSHのセットアップ
## Open SSH Server のインストール
1. サーバーアプリのインストール
	```bash
	sudo apt -y update
	sudo apt -y install openssh-server
	```
1. 構成ファイルの設定
	```yaml:/etc/ssh/sshd_config
	PermitRootLogin no          # root でのログインの抑止
	PermitEmptyPasswords no     # 空のパスワードの抑止
	MaxAuthTries <Nums>         # 最大試行回数
	Port <Nums>                 # ポート番号
	PasswordAuthentication no   # パスワード認証によるログインを禁止
	```

## 公開カギ認証の設定
### 公開鍵/秘密鍵の生成
1. ディレクトリの移動
	```bash
	mkdir ~/.ssh
	chmod 700 ~./ssh
	cd ~/.ssh
	```
2. 生成
	```bash
	ssh-keygen -t ecdsa -f <file_name>
	```
	画面に従いパスフレーズを登録する．
	- オプション
		-t 暗号化手法 (rsa,ecdsa,...)
3. サーバーに公開鍵を登録
	```bash
	cd ~/.ssh
	cat <file_name>.pub >> authorized_keys
	chmod 600 authorized_keys
	```

## SSHの起動
```bash
sudo systemctl ssh restart
```

# 参考

https://www.kkaneko.jp/tools/server/pubkey.html

https://www.st.itc.keio.ac.jp/ja/faq_security_sshdconfig_st.html
Juliaで自作の型に対して足し算+やインデックスによるアクセスA[i]を実現する方法


# 前提

自作の型に対して足し算とか配列のようなアクセスができると都合が良いことがあります。
今回は、以下のような構造体を型として扱います。

```julia
mutable struct Status_6
    hp::Real
    mp::Real
    atk::Real
    dfs::Real
end
```

この構造体に対して、ステータスの増加を見通し良く行うため、以下のような記述ができると便利そうです。

```julia
st + Δst
```

今回はこれの実装方法を説明します。

# 自作の型に対する演算

ステータスのアクセスに対して、配列のアクセスのようにインデックスでアクセスしたい場合、以下のようにして定義すれば可能になります。これは`Base`の関数`getindex`, `setindex!`に対して多重ディスパッチさせている感じです。

```julia
function Base.getindex(st::Status_6, i::Int)
    if     i == 1  return st.hp
    elseif i == 2  return st.mp
    elseif i == 3  return st.atk
    elseif i == 4  return st.dfs
    else           error("access denied.")
    end
end

function Base.setindex!(st::Status_6, val::Real, i::Int)
    if     i == 1  st.hp  = val
    elseif i == 2  st.mp  = val
    elseif i == 3  st.atk = val
    elseif i == 4  st.dfs = val
    else           error("access denied.")
    end
end
```

これで以下のようなアクセスが可能となります。勿論、文字列やシンボルでアクセスしたり、タプルや配列によるアクセスを可能とすることもできます。自作の配列型みたいなのを作れるってことですね。

```julia
st = Status_6(10, 11, 6, 5)
st[3]
```

`copy`関数も自作で作れます。

```julia
Base.copy(st::Status_6) = Status_6(st.hp, st.mp, st.atk, st.dfs)
```

レベルアップなどでステータス全体に対して変化分のステータスを足し合わせたい場合、以下のようにして定義すれば足し算を定義することも可能です。

```julia
function Base.:+(st::Status_6, Δst::Status_6)
    new_st = copy(st)
    for i = 1:4
        new_st[i] = st[i] + Δst[i]
    end
    return new_st
end
```

これで、ステータスの足し算のようなものが実装できました。
実際に以下のように動作せることができます。

```julia
st = Status_6(10, 11, 6, 5)
Δst = Status_6(2, 2, 1, 1)

st + Δst
```

[自ページ](https://ay-aki.github.io/julia-learning/)
[OutSystems]走り始めたTimerはアプリケーションレベルでは止められないことを確認する

# 確認環境情報
Personal Environment(Version 11.21.0 (Build 39357))
Service Studio(Version 11.54.15)

# 基本として、Timerは停止できるように作りたい
この方法は、以前に[Timerを停止できるように作る](https://qiita.com/jyunji_watanabe/items/27b88d928e8651d77930)で書いた。

開発標準に入れてしまうかは悩むが、実装パターンとしてはそんなに複雑ではないので、検討の余地はあると思う。

# ビルトインのリトライが問題を複雑化する
Timerには、Timeoutの仕組みがあり、一定時間が立つと例外が発生して停止する。
ただし、ビルトインのリトライの仕組みがあり、例外発生時には環境ごとに固定の回数までは自動でリトライされる。

よって、開発中にTimerに無限ループを仕込んでしまったり、運用中に゙データが膨らんで実行時間が想定以上に長くなってしまうと、

1. Timerが長時間動き続ける（その間見ているしかない）
1. Timeout in Minutes (+α) の時間が経過するとタイムアウトになる
1. 一定時間後リトライ
1. 原因が解決していないのでもう一度タイムアウト→リトライ、を上限回数まで繰り返す

ということになる。

Timerがタイムアウトするとどうなるかは、以前[Timer・BPTにおける未処理Exceptionの扱い - Timer](https://qiita.com/jyunji_watanabe/items/24ea3622a8202b8e9306#timer)で確認した。

# 実行中のTimeoutをService Centerで短くしてみる
## 動作確認用Timerの実装
以下の通り、開始時・ループ毎・終了時にログを出力し、ループ毎に1分間スリープさせる（合計約10分間実行）Timer。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/c70f20e8-06ad-e1af-3221-c25b5b9e42b8.png)

TimerのTimeout in Minutes Propertyの設定値はデフォルトの20分。

## Timer実行中にTimeoutを短く設定
Service Centerで問題のTimerを起動し、実行が始まったのを確認してから、Timeoutの設定を3分にしてみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d22c634d-aff6-6841-2e61-3bb3a044f13e.png)

以下はService Centerで対象のTimerのページを開き、右下に表示される現在の実行状況。
Timeoutに設定した時間が近くなると表示される警告は出た。つまりこの表示には実行中に行ったTimeoutの変更が反映されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/6252a0eb-cdac-1887-f923-80585442fda3.png)

ところが、実際のTimer Actionは設定した3分が立っても実行が継続する。つまりTimer起動時のTimeout設定のほうが有効になっているようだ。

以下が、上で見たのと同じUIを実行開始後約8分の段階で再度確認したときのもの。
実行は継続しているのが確認できる。実行中には表示されたままのはずのIs running since項目が空になっているが、実行開始からの時間を示すCurrent durationには想定通りの経過時間が表示されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/135940f5-af9e-013a-15de-07d7d49dc115.png)

ログで確認したところ、10分経過後終了ログが出力されて無事に終了した（タイム・アウトされなかった）。

## 結論：実行中にTimeoutを短くしても、今実行しているTimerのタイムアウト時間は変わらない
ただし、実行中には常に値が設定されているはずのIs running sinceがUI上で見られなくなるという不思議な点はあった。

# 実行中のTimerロジックを修正してPublishしてみる
## Timerを実行中にループの先頭で強制的にTimerを終了させる分岐を入れてPublish
「実行中のTimeoutをService Centerで短くしてみる」と同じロジックを使い

1. まずTimeoutは3分のままにしておく（放っておくとタイムアウト→リトライを3回繰り返すて止まるはず）
1. Service CenterからTimerを開始
1. Timerが終わる前に以下の修正を行いPublish

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/1150c0ac-b2d0-3f87-5bda-1a0a0c6e9fc7.png)

して結果をログで確認する。

ログは以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/82f7f57f-0c30-6f42-51fd-fdae2f050569.png)

- 実行中のTimerにはロジックの変更が反映されずにループの先頭での分岐が適用されない
    - loop1, loop2, loop3, loop4と4回目まで表示され、タイムアウトにかかって次のTimer実行が行われている（2つ目のstartのログ）
    - 1分ごとに1ログのはずなのに、最初のTimer実行で4つのループ内ログが出力されているが、これはTimerのTimeout適用には少しゆとりがあるため（3分の設定にすると3分+αくらいの時間でタイムアウトになる）
- Timeout後のリトライではstartのログ出力後、ループの先頭で、新しいロジックである分岐（常にActionを終了させる分岐）にかかって処理を終えている

## 結論：実行中のTimerにはPublish結果は反映されない。ただしリトライされたときには新しいロジックで動作する
よって、開発環境ならこっちの方法で止めるのもありかと思う。
フロントエンドエンジニアの面接で聞かれた質問まとめ

以前、フロントエンドエンジニアとして転職活動している中、
何社か面接の時間をいただくことができましたので、その中でされた質問をまとめました。
フロントエンドエンジニアの転職面接の解説記事ってあまりないので、実体験が参考になったらうれしいです。

※質問の文言や内容については多少ぼかしてます。また、フランクな感じに書いてますが、どの面接官も敬語で丁寧に話されていましたからご安心ください。

企業が求めている経験・技術・人物像、自身が求めるキャリアプランなどでも聞かれることは変わると思いますので、「こういう視点もあるんだな～」程度で見てください。
ベーシックなものはまとめて書いちゃいます。

転職理由について
-

>__・転職のきっかけってなに？__
>__・志望動機を教えて__
>__・転職する上で重要視していること・転職軸ってなに？__

転職の理由・きっかけ・転職してまでやりたいことは何かを問う質問ですね。
ここが固まっていないとほかの質問もぐだぐだ回答になるので、しっかり固めて挑みましょう。

働き方について
-
>__・普段の仕事進め方を教えて__
>__・普段どういう役割を担っている？__
>__・失敗したなって思うこと、うまくやれたなって思うことはなに？__
>__・今までで失敗したことは？__
>__・現職の仕事ってどう？__
>__・得意な言語ってなに？__
>__・業務で使っているツールはなに？__
>__・CSSの命名規則はどれを使っている？__
>__・弱みはどうやって克服する？__

実際に開発を行う上で、どのような環境なのか、現職と転職先での仕事の進め方に大きなギャップがないか、その人がどういう経験を積んできたのか、といったことを知りたいんですね。

将来像について
-
>__・今後どんな仕事をしたい（どういうものを作りたい）？__
>__・エンジニアとしてどういう人になりたい？__
>__・この業界（エンジニア/web）に入ろうと思ったきっかけはなに？__

将来像や進む方向性、個人の考え方についての質問ですね。
手を動かす仕事ですので、今後作りたいものだったり、どういったキャリア（ディレクター・マネージャー・リード・スペシャリストなど）を積みたいのか聞かれます。

番外編
-

###### ・フレームワークを使わないけど大丈夫？
フレームワークは導入・選定コストが高いというデメリットがありますが、
複数人でプロジェクトにあたる場合、ソースコードが均一化をされている方が効率が良いです。
提供したい機能・業務効率化を図るうえで、大体の企業は積極的に取り入れている印象だったので、この言葉を聞いたときは驚きました。私はフレームワークは必要に応じて取り入れたい派なので、知れて良かったです。
<br>
###### ・面接通ったから来たの？うちに興味があって来たの？
当時担当してくれた転職エージェントさんにも「珍しい質問ですね。」とお墨付き（？）頂いた一つ。私も人生で初めてされた中々パンチのある質問でした。
あえて揺さぶりをかける質問をして反応を見る為なのか、マジで何にも考えず面接の場に来た奴が多くて辟易していたのか、私の志望度が低そうに見えたからかは定かではありませんが、「こういう質問もあるんだな～！」と衝撃を受けました。
リモート面接でしたが、面接官の顔が見切れていたり、他の面接官からの問いかけに返事しないときがあったり、といった様子だったので、もしかしたら私に興味がなかったのかもしれないですね！！！（やけくそ）
<br>
###### ・スキルを上げたいなら●●って言語の方が良くない？
面接官の質問というよりは先輩エンジニアとしての意見っぽかったですね。
当時、スキルアップのために業務経験がない▲▲をメインで勉強しています～という話をした際に出た言葉。
こういった言葉が出たときに、改めてなんでその言語を選択しているのか説明できるといいかもしれませんね。



### 最後に
以上、過去にあった質問まとめでした。「本番に弱い」「変化球が来ると狼狽えてしまう」という、私のような人の参考になればうれしいです。
企業・職種・面接官によって質問は変わりますが、
「__自分がどうありたいのか__」「__転職してまで実現したいこと__」を固めておくと回答の応用が利くと思います。

ただ、一人でそういった根幹の部分を固めるのは難しいと思いますので、
複数の転職エージェントで話をすることをおすすめします。
質問を投げかけてもらうことで、見えてくる自分の考えがあると思います。

:::note info
エージェントと面談して、その日のうちに「ひとまず20社応募してみましょう」などと言われたら __日を置いて考えるか、別のエージェントで相談することをお勧めします。__
:::

大量に応募したは良いものの、そのすべてからお祈りメール来たら心折れますし、仮に選考通っても面接日程調整が大変になります。働きながらの転職は使える時間が限られると思いますので、3～5社くらいずつをおすすめします。

__・自分の過去の経歴、どうして転職しようと思ったのかをしっかり聞いてくれる__
__・疑問点、不安な気持ちへの回答が納得できる、わかりやすい__

私は上記のような担当さんがついてくれたので、転職や面接への不安がかなり解消できました。
自分の意見を尊重してくれる、信頼できる人を見つけることができれば転職エージェントは心強い味方になります。


使えるものは賢く使っていきましょう。
では、良い転職ができることを祈ってます！
【( ..)φメモメモ】基盤地図情報数値標高モデルのファイル名について

# 数値標高モデル

数値標高モデルは、標高のメッシュデータです。
5mメッシュ及び10mメッシュの2種類のデータがあります。

https://fgd.gsi.go.jp/download/ref_dem.html


# ファイル分割と命名規約

数値標高モデルのメッシュデータは、3次メッシュ単位（5mメッシュ）及び2次メッシュ単位（10mメッシュ）で分割されています。

ファイル名の命名規約は次の通りです。

- 5mメッシュファイル名  
FG-GML-[1次番号]-[2次番号]-[3次番号]-[名称]-[yyyymmdd].xml
- 10mメッシュファイル名  
FG-GML-[1次番号]-[2次番号]-[名称]-[yyyymmdd].xml

|項目|説明|備考|
|----|----|----|
|1次番号|緯度を2/3°ずつに分割した2桁の番号に、経度の下２桁を結合した番号|4桁の数字|
|2次番号|1次メッシュを緯度経度をそれぞれ8分割した2桁の番号|8進数表記|
|3次番号|2次メッシュを緯度経度をそれぞれ10分割した2桁の番号|10進数表記|
|名称|DEM5A,DEM5B,DEM5C,DEM10A,DEM10Bの順に精度が高い|大文字小文字を区別しない|

# 計算式（１次番号、２次番号、３次番号）

Excel関数を例に、緯度・経度から１次番号、２次番号、３次番号を求める計算式を次に示します。

```
緯度メッシュ番号=INT(緯度*120)
経度メッシュ番号=INT((経度-100)*80)

緯度3次番号=MOD(緯度メッシュ番号,10)
経度3次番号=MOD(経度メッシュ番号,10)

緯度2次番号=MOD(INT(緯度メッシュ番号/10),8)
経度2次番号=MOD(INT(経度メッシュ番号/10),8)

緯度1次番号=INT(緯度メッシュ番号/80)
経度1次番号=INT(経度メッシュ番号/80)
```

```
1次番号 = TEXT(緯度1次番号, "00") & TEXT(経度1次番号, "00")
2次番号 = TEXT(緯度2次番号, "0") & TEXT(経度2次番号, "0")
3次番号 = TEXT(緯度3次番号, "0") & TEXT(経度3次番号, "0")
```

# まとめ

経度・緯度からメッシュ番号を計算し、ファイル名を求めることができます。
データ取得の優先順は、DEM5A,DEM5B,DEM5C,DEM10A,DEM10Bの順にするとよいでしょう。
尚、**名称**は、大文字小文字を区別せずに検索する必要があります。
エンジニア2年目の転職ドラフト体験談

この度転職ドラフトを通しての転職が決まったので体験談を書きます。
新しく登録される方は紹介コード`TLZI`を使っていただくと、レジュメ審査通過後にプレゼントがもらえるらしいです。

＊[こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています](https://job-draft.jp/articles/251)

# 筆者のバックグラウンド

1998年生まれの現在25歳
GMARCHの文系学部出身
新卒で1年間Webマーケティングの会社で働いた後、2021年にエンジニアに転身
前職ではGo言語をメインにフィンテックアプリのサーバーサイド開発に従事


# 転職ドラフトに登録したきっかけ

エンジニアになってからしばらくの間Youtubeで[KENTA / 雑食系エンジニアTV](https://www.youtube.com/@kentatv2710)というチャンネルの動画を見ていた時期があり、その中で転職ドラフトが紹介されていたため、存在はずっと知っていました。

これまでの転職では応募したい会社が明確に決まっていたため自己応募で進めることがほとんどだったのですが、前職では複雑なドメイン知識の理解が求められるフィンテック周りの開発経験を積んでいたこともあり、自分自身の市場価値を知るというのも兼ねて、今回転職ドラフトを使ってみました。


# 指名結果

前職がフィンテックだったのもあり、同じようなフィンテックの企業からの指名を中心に __4社__ からオファーをいただきました。

どの企業も私の書いたレジュメを元に、私に求める役割や、魅力に感じた点を熱くメッセージにまとめてくださっていたのでとても嬉しかったです。

また、年収のオファー額に関しても私が想定していた額を大きく上回っていたことにも驚きました。
具体的な金額は書けないのですが、私がこれから何年かかけて達成したいと考えていたような金額でのオファーがほとんどで面食らってしまったほどです。

# 選考の流れや結果について

選考の流れ自体は他の媒体や自己応募した場合と大差はありませんでしたが、
転職ドラフトの場合、企業からのオファーが届いても提示された年収が低ければ再オファーのお願いを企業に出すことも出来るのが珍しい点だと思います。

私の場合は初手で想定以上のオファー額をいただいていたので使うことはなかったのですが、
転職ドラフトというサービスのエンジニアファーストな面を強く感じれる仕様の一つだなと感じます。

また、私自身の選考結果としては下記の通りでした。

A社：内定
B社：A社内定獲得により最終面接辞退
C社：2次面接落ち
D社：指名辞退


最終的には、今後の自分のキャリアプランに最も沿っていて、カルチャーマッチ度が高いと感じたフィンテック系の企業A社の内定を承諾して転職活動を終了しました。

# 転職ドラフトを使って良かったこと

## レベルの高いレジュメを準備することが出来た

転職ドラフトに参加するにあたっては、運営による審査を通過できるだけのレジュメ（職務経歴書）の作成が必要になります。

自分は審査に通過するまでに3回くらい書き直ししなければならず、大変ではあったのですが、
レジュメを書き直すプロセスを通して、自分自身の職歴の棚卸を深いレベルで行うことが出来たので、結果的にその後の面接で話す材料の整理に大きく貢献していたと考えています。

また、転職ドラフト経由以外の企業の選考においても、ここで整理した内容はもちろん活かすことができるので、仮に転職ドラフトで転職が叶わずとも、審査を通過できるだけのレジュメが作成できた時点で自分自身のキャリアの見直しなどに取り組むことが出来るのではないかと思います。

## フラットな評価を元に想定以上のオファーをもらえた
転職ドラフトのルールとして、内定時には最初のオファー金額に対しての90%の金額を保証することが企業に求められています。

逆に言えば、年収1000万円をオファーされても、内定時には900万円を提示されることがあり得るということなのですが、今回内定を承諾させていただいた企業に関しては、当初のオファー額の100%の金額を内定時に提示いただきました。

転職ドラフトを使ってもオファー額の90%になることがほとんどだよ、みたいなことを元々聞いていたのでいい意味で驚かされました。

また、そもそもの目的の一つでもある「自分自身の市場価値を知る」という点においても、自分のこれまでの経験や今後のポテンシャルをフラットに評価いただいた時に、これだけの金額でオファーをいただけるというのが知れたことで自信にも繋がりました。

## それまで知らなかった企業とマッチングできた
ここに関しては他の媒体とも似た部分はあると思いますが、
転職ドラフトでは自分から企業にアプローチすることもできますが、企業からのスカウトが基本となっており、それまで自分が知らなかったような会社との接点ができるのは良いと思いました。

他の媒体を使っている時は、知らない企業からのスカウトが届いても「知らない会社さんだな。メッセージもテンプレっぽいし反応しなくていいや...」となってしまうことがほとんどでした。

ところが転職ドラフトでは（たまにテンプレ臭がする企業さんもいますが）、求職者のレジュメを元にしっかりとスカウトの文章を書いてくださる企業がほとんどなので、
知らない企業だったとしても入社後にどんな貢献や成長ができるかの解像度が最初から高い状態で選考に臨めるのは魅力的だと感じました。

実際に今回の転職先の企業は指名されるまで知らない企業でしたが、選考が進む中で「この会社で働きたい！」と強く感じるようになったので良かったと思っています。
Remixでフォームの内容をクリップボードにコピーする

**remix**ではコードが動作するのが**サーバー側かブラウザ側か**意識する必要があります（[参考](https://remix.run/docs/en/main/guides/constraints#browser-only-code-on-the-server)）

クリップボードで使う**navigator**はブラウザ側でしか動作しないので、
`if (typeof document === "undefined")`条件文でサーバー側での動作の際には`undefined`を返すようにしました

```tsx
import { useRef } from "react";

export default function CopyAbleForm() {
  const textAreaRef = useRef<HTMLTextAreaElement>(null);

  const copyText = () => {
    if (typeof document === "undefined") {
      console.error("It's not a browser");
      return;
    }
    const textArea = textAreaRef.current;
    if (textArea === null) {
      console.error("Unable to copy text to clipboard");
      return;
    }
    textArea.focus();
    textArea.select();
    navigator.clipboard
      .writeText(textArea.value)
      .then(() => {
        console.log("Copying text was successful");
        return;
      })
      .catch((err) => {
        console.error("Oops, unable to copy text " + err);
      });
  };

  return (
    <form className="mb-5">
      <label htmlFor="textarea" className="sr-only">
        CopyAbleTextarea
      </label>
      <div className="flex items-center px-3 py-2 rounded-lg bg-gray-50 dark:bg-gray-700">
        <textarea
          id="textarea"
          ref={textAreaRef}
          value={"Some text"}
          rows={1}
        ></textarea>
        <button onClick={copyText}>Copy Text</button>
      </div>
    </form>
  );
}

```

このテクニックはremix同様に**サーバーサイドレンダリング**（**SSR**）を提供する**Next.js**でも使えるかもしれません（未検証）
VSCodeでMarpの自作CSSが全く読み込まれなかった件


VSCode + Marp でMarkdown 形式でスライド作成した際に、自作CSSスタイルシートがよみこめなかったのでその際に実施したアプローチをまとめました。


## 前提 
ワークスペース`/path/to/work/`下にtest_marpフォルダを作成して、.mdファイルやスタイルシートを保存しました。
階層は以下の構成になっております。
```bash
test_marp/
├── .styles/
│   └── test.css
└── test.md
```

```css:test.css
/* @theme test */

@import "gaia";
```

```md:test.md
---
marp: true
theme: test
```
<br>
カスタムCSSのファイルを指定できるようにするため、`markdown.marp.themes`でカスタムCSSの絶対PATHを指定しました。

```json
"markdown.marp.themes": [
  "/path/to/work/test_marp/.styles/test.css",
]
```

## エラー内容
Markdownで `theme: test` と自作のCSSを定義したのですが、以下のエラーのように「test」テンプレートが読み込めない事象が発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872532/59e7524c-455c-a3f3-6f57-ef5d61078154.png)

```
The specified theme "test" is not recognized by Marp for VS Code.marp-vscode(unknown-theme)
theme Global directive

Set a theme name of the slide deck.

You can choose from Marp Core built-in themes or registered custom themes.

Provided by Marpit framework (See more details...)
```

## エラーの原因
エラーの原因究明のため<font color="OrangeRed">**ターミナルを開き「出力」 タブを開きプルダウン「ウィンドウ」を選択**</font>することで、ウィンドウ上でmdファイルを開いた際の拡張機能の読み取りなどをデバッグすることができます。
今回はこれを活用してMarp拡張機能の挙動についてみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872532/1690cf91-040b-8dba-93c6-fccd590443c5.png)


上記のやり方でデバッグしてみた結果、以下のように.cssのパスが`/path/to/work/path/to/work/test_marp/.styles/test.css`となっていたことでNotFoundにより参照できないことがわかりました。。

```bash
2023-07-08 10:52:09.401 [error] [Extension Host] EntryNotFound (FileSystemError): Error: ENOENT: no such file or directory, open '/path/to/work/path/to/work/test_marp/.styles/test.css'
```

原因としては、他拡張機能によるものでした。私は拡張機能[Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager)も導入しているので、
**「Project Managerのワークスペースフォルダ」 \+ 「markdown.marp.themesの値」** がPATHとして参照されるといったことでカスタムCSSが読み込めなかったかと考えられます。。。

今回の例で言うと、[Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager)のフォルダを`/path/to/work/`として定義し、workフォルダ下にtest_marpフォルダを作成していました。また、`markdown.marp.themes`を絶対PATHとして定義していたことで、上のErrorのように`/path/to/work/`が2回も出力することになってました。


試しに、Project Managerを無効にしたら、今度は、絶対PATHでの書き方が良くなかったことが挙げられます。
`markdown.marp.themes`は`markdown.styles`の設定に基づくため、CSSのスタイルシートは開いているエクスプローラー上からの相対PATHとしてとエクスプローラーとして解釈されてしまうからです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/872532/2225c369-ecc7-872f-c134-fc70626f27ab.png)

その結果、**「エクスプローラー上のファイルのPATH」 \+ 「markdown.marp.themesの値」** となるので、`markdown.marp.themes` の値は相対PATHにした方が良いです。

```json
"markdown.marp.themes": [
  "./.styles/test.css",
]
```

<br>
したがって、① <font color="OrangeRed">相対PATHで記述する</font>  ② <font color="OrangeRed">その他拡張機能によってPATHなどが変わっているか</font> を切り分けて考える必要があります。

## 結論

MarpでカスタムCSSを使用する際は、以下の点に気を付けていただければエラーが起きないかと。。

- `markdown.marp.themes`には**相対PATH**を指定する。
- Project Managerを使用していない場合) Marpスライドフォルダ下にcssテンプレートを配置。
- Project Managerを使用している場合)  各ワークスペース下の所定のフォルダにcssテンプレートを配置。 or Marp用のワークスペースを別途作成。 (その他、良い案ありましたら。。)

また、拡張機能が機能しない、テンプレートが読み込めない等の場合は、VSCodeの「出力」コンソールを確認した方が良いと思います。
Powershellダウンロードしたファイルのセキュリティを一括解除

# 検索すると出てこない
探し方が悪いのか？
ダウンロードしたときにセキュリティがかかっているので、通常はプロパティから許可(K)するけど、大量にあるときは無理。
そこでPowershellを使う。

# Script

```Powershell
sl $env:USERPROFILE\downloads
Get-ChildItem | Unblock-File
```

こんな感じ。

# 意味
ユーザーのダウンロードフォルダに行く。（Set-Location）
Get-Childitemですべてのファイルを回してパイプ送りに、
Unblock-Fileでセキュリティを解除
これ、Offじゃない。

```Powershell
# 嘘コード
Get-ChildItem | Block-Off
Get-ChildItem | Get-Lock -off
```
こんなのではない。
検索してもあるはずないな。

# Version3.0以降のはず
`Unblock-File`はたしかVersion 3.0からしか使えないはず。Windows 10なら5.1以降なので、今（2023年）は問題が起きづらいと思う。
一回7かVistaでPowershellが2.0だったので、悔しい思いをしたことがある。
VM VirtualBoxの画面設定について

virtualboxで画面を適度な大きさに変更したい時、たびたび変更できずに諦めて実施してたのだがどうしても気になって、挑戦しようにもいまいちわからなかったが、調べてみた結果を自分用にメモしておく。
1.VirtualBoxのツールから変更する方法
①下記の画面から設定タブを押下する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733928/4b994f7b-fde7-41aa-543f-96a6158f2f94.png)
②ディスプライタブのスクリーンでスケールのパーセンテージを任意の値に変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733928/d57da674-8cf4-376e-fcf2-48cad574d473.png)
dockerとdocker composeでwebアプリをdocker化する方法


Railsアプリをdocker化する方法をまとめてます。

# 環境
* docker: 20.10.12
* Ruby: 3.2.2
* Rails: 7.0.6
* DB: PostgreSQL 12

# Docker化の手順

1. Dockerfileの作成
   `Dockerfile`を作成し、以下を記述する。

    ```Dockerfile:Dockerfile
    FROM ruby:3.2.2
    RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
    WORKDIR /myapp
    ADD Gemfile Gemfile.lock /myapp/
    RUN bundle install
    ```

1. docker-compose.ymlの作成
   `docker-compose.yml`を作成し、以下を記述する。

    ```yml:docker-compose.yml
    version: '3'
    
    volumes:
      db-data:
    
    services:
      web:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        environment:
          - 'DATABASE_PASSWORD=${POSTGRES_PASSWORD}'
        volumes:
          - .:/myapp
        ports:
          - "3000:3000"
        depends_on:
          - db
      db:
        image: postgres:12
        environment:
          - 'POSTGRES_PASSWORD=${POSTGRES_PASSWORD}'
        volumes:
          - 'db-data:/var/lib/postgresql/data'
    ```

1. DBの設定
    `config/database.yml` を以下のように書き換える。

    ```yml:config/database.yml
    default: &default
      adapter: postgresql
      encoding: unicode
      host: db
      user: postgres
      port: 5432
      password: <%= ENV.fetch("DATABASE_PASSWORD") %>
      pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>  

    development:
      <<: *default
      database: myapp_development

    test:
      <<: *default
      database: myapp_test  
    ```

1. DBパスワードの設定
    `.env`を作成し、以下を記述する。

    ```text:.env
    POSTGRES_PASSWORD=任意のパスワードを記述
    ```

# 動作確認

1. イメージの作成
    以下コマンドを実行し、イメージを作成する。

    ```bash
    $ docker-compose build
    ```

1. DB 作成
    以下コマンドを実行し、DB を作成する。

    ```bash
    $ docker-compose run web rake db:create
    $ docker-compose run web rails db:migrate
    ```

1. コンテナの作成・起動
    以下コマンドを実行し、コンテナを作成・起動する。

    ```bash
    $ docker-compose up
    ```

1. 動作確認
    http://localhost:3000/ にアクセスする
Raspberry Pi 4 64BitにGoをインストールする

# はじめに
ラズパイでGoを動かしたくていろいろググったのですが、つまづきまくったので記事にしました

# コマンド
~~~ bash
$ wget https://golang.org/dl/go1.20.5.linux-arm64.tar.gz
$ sudo tar -C /usr/local -xzf go1.20.5.linux-arm64.tar.gz
$ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
$ echo 'export PATH=$HOME/go/bin:$PATH' >> ~/.bashrc
$ source ~/.bashrc
$ go version
go version go1.20.5 linux/arm
~~~

arm64にするのがポイントです