OmniAICreator/Qiita-1.07M huggingface dataset:
Tableauで可視化する、あなたの町はかに？まぐろ？それとも・・・塩〇〇

# 肉魚だけじゃない、全国なんの魚介類で年越ししてるの？を調べてみた。

結論から、どん！

かにさん、つおい！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/3fc69ae5-063a-83a6-d6b4-dad6a3f50af5.png)

全国だとブッチぎりでかにさんですね。


んじゃ、ちょっと特徴的な市区を探してみましょ。

さいたま、東京はまぐろがかにを抑えてますね。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/89d97448-5048-9aee-d118-6d97b66b1eee.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/5e375ea7-b0b0-d233-2747-f1108bff21fb.png)

では、カニ産地の境港が近い鳥取市は・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/081c6554-c3f7-f656-be7a-135d989fd46b.png)

かに、えびっぃい！！

まぐろどこ行ったよ？？？
なんと塩さけ、たらこ以下！！！

衝撃は福岡県・・・。
エ？マジ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/49b019ae-e108-5d1d-720a-995de4c5810f.png)

んまぁ、家計調査は買って帰ってきた品目の金額なので、贈答用も含まれる。。。とはいえ、凄いね福岡のたらこストロングスタイル！

でも北九州はカニが1位。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/10995107-5292-b37b-777f-dde7531ae31b.png)

てな感じで、オラが町の年越し準備、魚介類ランキング編でした。
リンク張っとくので遊んでみてね。

小学生の冬の宿題に使えるかも？？？？

https://public.tableau.com/views/12_17023522909990/12?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link


広島はやっぱ　かき　なのね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/a1990711-57d6-16b3-d84b-4e907c5b7325.png)
2023 年の IT エンジニア、小学生と保育園児との Work from home

## ふりかえり
https://qiita.com/e99h2121/items/c8878d027603745a6426


> 在宅する日(月、金):
6:00- 起きる、朝飯、洗濯、ごみ捨て、着替える
8:00- 娘を保育園に送りながら息子と外の空気を吸う
8:30-11:00 帰宅してお仕事
11:00-12:00 息子/自分の昼飯
12:00-14:00 息子昼寝/自分お仕事
14:00-16:00 息子を放牧しながらお仕事(デイリーmtg含)
16:00-17:00 Eテレ夕方のゴールデンタイムを見せながらお仕事
17:00-18:00 買い物
18:00 夕飯、風呂掃除
19:00 軽めにお仕事
20:00 風呂、寝かしつけ
21:30- 自由時間

> 通勤する日(火、水、木):
6:00- 起きる、朝飯、洗濯、ごみ捨て、着替えるなど
8:00- 娘を保育園に送
8:30-9:30 通勤
9:30-11:30 お仕事
11:30- 息子の保湿とか
12:00- お仕事
15:15- 息子の保湿とか
15:30 お仕事(デイリーmtg含)
17:00-19:00 帰宅、夕飯、風呂掃除
19:00 軽めにお仕事
20:00 風呂、寝かしつけ
21:30- 自由時間


https://qiita.com/e99h2121/items/f5e9ddef0141fe00259b


## 2023 年

### 最近の時間割

4:00- 起きる、今日の TODO 確認
5:00- 運動
6:30- ごみ捨て、朝飯、洗濯、着替えるなど
8:00- 娘小学校、弟を保育園に送る
9:00 お仕事開始
12:00 お昼
13:00 お仕事
16:30 保育園お迎えに行く日はお迎え
17:00-19:00 小学生帰宅、風呂掃除、夕飯
20:00 風呂、寝かしつけ
20:30- ほぼ寝落ち


### 出社

月 1 ペース。チームでお昼を食べるとか、飲むとか、ゲームで商品もらえるとか、インセンティブに釣られてまんまと出社する。出社いいね。

### 最近のお気持ち
転職したけど、変わらないか、勤務時間が皆とそろってむしろ働きやすくなった。

### 最近の失敗
睡眠時間は本当に大事。持続可能な仕事をするなら 6 時間は寝ることを意識していきたい。

### 改善したい点・これからこうしたい

ぼんやり考えていること。

- こどもも大事
	- 意識してやっていること
		- 有休をとる
		- 学校行事に参加する
		- 保護者会に参加する
		- PTA の「パソコンできる人枠」の役割を楽しむ
	- 一緒に楽しもうとしていること
		- 子供と運動する
		- 子供と工作する
		- マイクラをやる
	- 楽しむために、自分のためにやっていること
		- 仕事
		- 運動

結局はタイム マネジメントなんだが、別に子供を持つことが特別なわけではない。ペットを飼う人、離れた家族に会いに行く人、自分のための趣味を楽しむ人、すべてひっくるめて「やらなきゃいけないこと」「やりたいこと」をどうコントロールするか。あいかわらず難しい。


## 参考

https://qiita.com/e99h2121/items/db7e54c111ffcd3c3957

つづく。
12月の年越し準備は肉?魚介類？をマップで表示したら日本の食文化の変遷が良くわかった話

# 先日思いっきりデータの前処理間違えて死にかけたおっさんです。

気を取り直して、こんどこそ都道府県を代表する市区の12月消費金額を可視化して行くよ！

Tableauに取り込んだデータに対して、以下のような計算フィールドで12月、市区ごとの最大消費金額を作ります。

12月市区ごと最大金額という名前にしときます
```
{FIXED [市区町村名],YEAR([月次]):MAX(IF MONTH([月次]) = 12 THEN [消費金額(円)] END)}
```

次に、この#12月市区ごと最大金額#をつかって、真偽を出す計算フィールドを作ります。


1位フラグという名前にしときます。
```
[12月市区ごと最大金額]=[消費金額(円)]
```

あとは、この１位フラグをフィルターにいれて、真だけをチェックしておくと良いです。

品目を色分けすると、実質肉類と魚介類のどちらかが1位なのできれいに2色に分かれます。

横棒グラフだとこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/6262d46a-fc1c-e76f-df68-849d3be95a24.png)


次に地図を作ります。
市区名では「東京都区部」のように、Tableauが地理データとして認識しない区分があるので、緯度と経度に地理的役割を与えて、緯度を行、経度を列に入れてやります。

そして、列に日付データから作った不連続の年をいれてやると、地図を使った肉と魚介類の消費金額1位争いが南から進行していく様子が良くわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167883/21055413-1ae6-5c8d-9486-17052c3f1696.png)

最後に、これをダッシュボードにしてハイライトアクションをつけると出来上がり。

データ量が多いので、デスクトップじゃないと表示は崩れますが見てみてください。

https://public.tableau.com/views/121_17024111328720/12?:language=ja-JP&publish=yes&:display_count=n&:origin=viz_share_link
【PHP】文字列連結 「結合演算子 vs 変数展開」

この記事は [PHP Advent Calendar 2023](https://qiita.com/advent-calendar/2023/php) 7日目の記事です。

:::note info
**更新 2024/01/19**
構文のミスがあったため記事内容を修正しています。
:::

## はじめに
PHPで文字列連結をすることって頻繁にありますよね。
あなたは意図した使い分けが出来ていますか？

### 1. 結合演算子
```php
  $lang = 'PHP';
  $job = 'エンジニア';

  echo $lang . $job;

  // 出力結果
  // PHPエンジニア
```
いわゆる「ドットつなぎ」ですね。
### 2. 変数展開
```php
  $lang = 'PHP';
  $job = 'エンジニア';

  echo "{$lang}{$job}";

  // 出力結果
  // PHPエンジニア
```
詳しくは[公式ページ](https://www.php.net/manual/ja/language.operators.string.php)へ。

## それでは本題に入ります
今回は、文字列連結のパフォーマンスについて実験を行います。
噂によると、「結合演算子」と「変数展開」ではメモリの使用量に違いが出てくると聞きました。
名前の通り「変数展開」っていうくらいなのでなんとなく処理がかかるイメージはありますが果たして真相はどうなのか...

:::note info
**調査しようと思った経緯**
可読性が高いと感じて、変数展開を乱用していた時期がありました。
ただ、先輩エンジニアから「実装の統一性・パフォーマンスの観点から多用は好ましくない」とのご指摘をもらいました。
そこで、どの程度パフォーマンスに違いがあるのか試してみたくなったっていうのが本記事のパーパスです。
:::

## 検証始めます
### シナリオ
1. 10000回文字列連結をします。
2. 「結合演算子」と「変数展開」で処理開始時刻・終了時刻の差を計測します。
3. 計測結果を評価します。

### テストコード
```php
  // テスト回数
  $loop = 10000;
  // 結合演算子を使用する場合
  $start_dot = microtime(TRUE);
  for ($i = 0; $i < $loop; $i++) {
    $a = 'あ';
    $i = 'い';
    $result_dot = $a . $i;
  }
  $end_dot = microtime(TRUE);
  $dot = ($end_dot - $start_dot);

  // 変数展開を使用する場合
  $start_var = microtime(TRUE);
  for ($i = 0; $i < $loop; $i++) {
    $u = 'う';
    $e = 'え';
    $result_var = "{$u}{$e}";
  }
  $end_var = microtime(TRUE);
  $var = ($end_var - $start_var);

  var_dump($dot);
  var_dump($var);
```

### 分析
```php
  // 出力結果
  $dot float(2.09808349609375E-5) 
  $var float(2.1219253540039062E-5)
```
`10^-5`ですので、想像よりは大差はないですね。（わかんない人は関数電卓で計算してください）

いちおう、その後も10回ほど計測をしましたが**わずかに変数展開を利用したほうが遅い...**程度ですね。

## まとめ
少しモヤモヤしていたので、今回の調査で「あまりパフォーマンスへの影響がない」ということがわかったのは今回の収穫です。
どっちがいいかというよりかは、「実装の統一性・可読性」を考慮した実装に注力したほうがよさそうですね。
データパックに潜むバグとの戦い方

この記事は [Minecraft Command Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mccmd) 13 日目の記事です。[^1]

[^1]: いつも通りアドカレを眺めていたら 12/13 のシリーズ 3 が空いてることに気づき、急に登録してなかった記事が書きたくなったので当日 (12/13) に参加登録をしました。これが [パニックモンスター](https://www.youtube.com/watch?v=arj7oStGLkU) 駆動生活です。ちなみに、当然まともに校閲をする時間がありませんでした。こういうことはやめたほうが良いです。っていうかまだ後に控えてる 4 記事に手すらつけていないのに何やってるんだ......

## はじめに
- ｢あれ～？？？？｣ 
- ｢なんかおかしいぞ｣
- ｢なにもしてないのにこわれた｣
- ｢バグった！｣

この記事を読んでる方はこの言葉にとても心当たりがあるのでは無いでしょうか？
つらいですよね、バグ。
特に一般のプログラミング言語に比べ、データパックは色々々々と複雑に書かなければいけないことが多いためバグをとても引き起こしやすいと私は考えています。
この記事ではそんなバグとの戦い方をいくつかのシチュエーションを例にして解説したいと思います。

## scoreboard や storage に絡むバグと戦う
`scoreboard` や `storage` が関係する処理は非常にバグを引き起こしやすい箇所の一つです。
そのようなコマンドが動かないことに気づいたときは、｢問題の直前で `scoreboard` や `storage` の値がどうなっているか｣ を調べることで原因の推測に役立つことが多くあります。

例えば
```mcfunction
execute if score %holder ObjectiveX matches 2 run function advent_calendar:meow

execute if data storage advent_calendar:piyo abc{def: 3} run function advent_calendar:meow
```
のようなコマンドが動かないことに気づいたときは、こうしてしまいましょう。
```mcfunction
tellraw @a [{"text": "%holder: "}, {"score": {"objective": "ObjectiveX", "name": "%holder"}}]
execute if score %holder ObjectiveX matches 2 run function advent_calendar:meow

tellraw @a [{"text": "abc.def: "}, {"storage": "advent_calendar:piyo", "nbt": "abc.def"}]
execute if data storage advent_calendar:piyo abc{def: 3} run function advent_calendar:meow
```
これでどんな値が入っているか一目でわかるようになりました。やったね。


## 長文 execute に潜むバグと戦う
複数のサブコマンドで構成される `execute` もまた非常にバグを引き起こしやすい箇所の一つです。
そのようなコマンドが動かないことに気づいたときは、｢`execute` コマンドがどこまで動いているか｣ を調べることでどこに問題があるかを特定することが出来ます。

例えば
```mcfunction
execute if data storage advent_calendar:hoge {nya: true} as @a[distance=..1, scores={ObjectiveY=1..}] if score %holder ObjectiveZ matches ..5 at @p facing entity @e[tag=pointP] eyes run function advent_calendar:meow2
```
のような `execute` コマンドが動かないことに気づいたときは、こうしてしまいましょう。
```mcfunction
execute run say 1
execute if data storage advent_calendar:hoge {nya: true} run say 2
execute if data storage advent_calendar:hoge {nya: true} as @a[distance=..1, scores={ObjectiveY=1..}] run say 3
execute if data storage advent_calendar:hoge {nya: true} as @a[distance=..1, scores={ObjectiveY=1..}] if score %score ObjectiveZ matches ..5 run say 4
execute if data storage advent_calendar:hoge {nya: true} as @a[distance=..1, scores={ObjectiveY=1..}] if score %score ObjectiveZ matches ..5 at @p run say 5
execute if data storage advent_calendar:hoge {nya: true} as @a[distance=..1, scores={ObjectiveY=1..}] if score %score ObjectiveZ matches ..5 at @p facing entity @e[tag=pointP] eyes run say 6
```
これでどこまで動いているかが一目でわかるようになりました。やったー！

## この記事で本当に伝えたかったこと
要はバグの原因がわからないときは状態を目に見えるようにしよう！！
WebGL で色々な表現に挑戦する - 2 色以上のグラデーション表現

## この記事の概要

前回の記事で、ようやく表現の幅が広がる気配を感じられたと思います。

https://qiita.com/xrxoxcxox/items/146d744bf7f124924eff

今回は更に踏み込んで、2 色以上のグラデーション表現を模索します。

## おさらい: 単純な 1 色のグラデーション

前回の複雑なグラデーションは一度リセットして、単純な状態に戻します。

```diff_glsl
  #version 300 es

  precision mediump float;

  in vec2 vTextureCoord;
  out vec4 outColor;

  void main() {
    float pi = acos(-1.0);
    float r = vTextureCoord.x;
    outColor = vec4(r, 0.0, 0.0, 1.0);
  }
```

見た目はこうなっています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/9ba6b09c-bf2d-7888-2e65-24cb418ee92b.png)

これを基準に手を加えていきましょう。

## 単純な 2 色のグラデーション

最も簡単にグラデーションの表情を増やすなら、次のようにコードを変えます。

```diff_glsl
  void main() {
    float pi = acos(-1.0);
    float r = vTextureCoord.x;
+   float g = vTextureCoord.y;
-   outColor = vec4(r, 0.0, 0.0, 1.0);
+   outColor = vec4(r, g, 0.0, 1.0);
  }
```

これにより、x 座標と y 座標それぞれのグラデーションが合成されたような結果が得られます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/b160f158-dc89-cffb-0273-5c56fd010751.png)

もちろん斜め方向に指定をすることもできます。

```diff_glsl
  void main() {
    float pi = acos(-1.0);
-   float r = vTextureCoord.x;
-   float g = vTextureCoord.y;
+   float r = (vTextureCoord.x + vTextureCoord.y) / 2.0;
+   float g = (vTextureCoord.x - vTextureCoord.y) / 2.0 + 0.5;
    outColor = vec4(r, g, 0.0, 1.0);
  }
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/b8953e19-69f5-1d01-3e36-a3aa04eede64.png)

また、放射状に広がるグラデーションを設定することもできるので、

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/26e063a0-8b9e-0adf-c029-b34ca2c80a53.png)

```diff_glsl
  void main() {
    float pi = acos(-1.0);
    float r = (vTextureCoord.x + vTextureCoord.y) / 2.0;
    float g = (vTextureCoord.x - vTextureCoord.y) / 2.0 + 0.5;
+   float b = 1.0 - length(vTextureCoord - vec2(0.5, 0.5));
-   outColor = vec4(r, g, 0.0, 1.0);
+   outColor = vec4(r, g, b, 1.0);
  }
```

このような、なんと形容すると良いのか分からないグラデーションも作成することができます。

![localhost_5173_ (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/56a646e6-45a6-3120-afeb-b84d24043b6d.png)

そして組み合わせ方次第で色々な柄を作ることができます。

```diff_glsl
  void main() {
    float pi = acos(-1.0);
    float r = (vTextureCoord.x + vTextureCoord.y) / 2.0;
    float g = (vTextureCoord.x - vTextureCoord.y) / 2.0 + 0.5;
-   float b = 1.0 - length(vTextureCoord - vec2(0.5, 0.5));
+   float b = 1.0 - sin((vTextureCoord.x - vTextureCoord.y) * pi * 50.0);
    outColor = vec4(r, g, b, 1.0);
  }
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/26ed2269-ada6-5d6d-f97f-70c490e735fd.png)

## 最後に

さすがにここまで来ると CSS ではできないような表現になってきたと思います。
現段階ではまだ模様を動かしていませんが、今後これらを時間にあわせて変化させてもいけるので、そうなったら尚更です。

一旦グラデーションは終わりにして、次はノイズ関連を記事にしたいと思います。
frameBufferFetchとCoLoRという謎のセマンティクス

# 前書き

この記事は、2023のUnityアドカレの12/13の記事です。
今年は、完走賞に挑戦してみたいと思います。Qiita君ぬい欲しい！

https://qiita.com/advent-calendar/2023/present-calendar#qiita_award

# はじめに

GPUによっては、FrameBufferFetchという機能をサポートしています。FrameBufferFetchは、その名の通りRenderTarget側のピクセルカラーを取得することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280975/ae3a593f-8cba-db97-a53f-7e770a87913c.png)

https://docs.unity3d.com/ja/2023.1/Manual/SL-ShaderCompileTargets.html#:~:text=framebufferfetch%20%E3%81%BE%E3%81%9F%E3%81%AF%20fbfetch

# HLSLでのFrameBufferFetchの使い方

```hlsl
void frag(v2f data, inout color : CoLoR)
{
    half4 c = color;
    c += data.mulValue;
    color = c;
}
```

このように、謎のセマンティクス`CoLoR`の引数にinoutをつけます。これで読み書きができます。最終的に入っていた値がRenderTargetにBlendされます。また、MRTの場合には、`CoLoR0`、`CoLoR1`...というように数字を付けます。

# `CoLoR`って！？

何だこの気持ち悪いの。

普段なら、PixelShaderの出力には、`SV_Target`または`COLOR`を使います。しかし、これらのセマンティクスはinoutと一緒に使うとコンパイルエラーになってしまいます。（本来outをつけて使う）

なので、HLSLcc（UnityのHLSLコンバーター）が`CoLoR`というケースパターンのセマンティクスを特殊処理するような実装となっております。

https://github.com/Unity-Technologies/HLSLcc/blob/3ea1fcd6bd/src/decode.cpp#L532-L551

# FrameBufferFetchは使えるのか

ここまで書いておいて何ですが、FrameBufferFetchの利用はお勧めできません。

私も網羅的に調査したわけではないですが、手元の端末では、Adreno（Snapdragon）系もMali系も動作しませんでした。PowerVRはできるとか噂を聞いたことがありますが、PowerVRのGPUなんて今どきほぼありません。（しかし本当に稀にあって盛大にバグる）

まぁなので、この記事の価値はないんですけど、`CoLoR`という気持ち悪い表記を見つけたら、「そういうことなんだなぁ（苦笑）」と思っていただければと思います。
SQLBuilderの仕様を考える　目標設定編

# 目的
GolangのSQLBuilerを作ってみたくて、仕様を考える。
最終系をみつつ、Version1にするゴールを考える

# なんでやってみたいのか
GolangにもSQLBuilderはあるが、unionに対応していないことが多い。（もしかしたらやり方を知らないだけかも）
現在業務では、unionを使うことが非常に多いのでどうするべきかに困っていた。
With句を使うことも多いのでこちらも対応したい。
それならやってみようと思ったことと、OSS活動にもならないかと思ってやってみようと思い立った。

# 目標
主要な手段である
- Select
- insert
- Update
- Delete(truncateを含める)
に対応できるようにしたい。
最初は特定のコマンドを実行することでSQL文が取得できる形を目指す。
他のORMなどの連携に関しては形ができたときに検討することとして一旦は保留とする。
最初はMySQL対応をベースにする。
Postgreseに関しては別途対応を考えるものとする。

## Modelとの関係性
Version1では基本見送る。
方針としては
- 設定ファイルを使ったTable定義設定
- sqlxなどの設定モデルからの呼び出し
といったことを考えている。

## Select
Select文では主要な機能をあげると
- Where句
- Order By
- Limit
- Offset
- Distinct
- Group By
- Having
- Join
- Union(Union ALLも含む)
  - 実装幅が広くなりすぎると思うのでVersion1では見送り
- With句
  - 実装幅が広くなりすぎると思うのでVersion1では見送り

の対応を目指す。

## Insert
InsertはBuik Insertまでできることを目指す。

## Update
UpdateはWhere句による絞り込みまでできることを目指す。

## Delete
DeleteはWhere句による対象絞り込みまでできることを目指す
TruncateはTable指定でできるようにする。

## Function
SQL関数に関しては、今回実装しない。
これは風呂敷を広げすぎないための対応でVersion1では見送る。
CS1012 "Too many characters in character literal" で何故かビルドが通らなかった話

## 概要

一応北大ITサークル(HUIT)のアドカレ2023の13日目の記事です。
記事にするような大した話ではないです(当社比)

### 状況
- ローカル(Windows,VS2022)で開発したちょっとしたコード
  - 単体テストまで書いて動作検証済み
- 動作したので Github に Push
  - Github Actions でCI(単体テスト)を設定
- CIで `Too many characters in character literal` でコンパイルエラー発生    

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510423/50bb602f-fbb6-4ca0-5d16-23151a910352.png)

### 構成

- InputUtil(ソリューション)
  - InputUtil(プロジェクト、本体)
  - TestInputUtil(プロジェクト、xUnit単体テスト)
  - InputUtilBenchmark(プロジェクト、パフォーマンス測定) 

バージョンは .NET7 / C#11 。

### 結論
- 単体テストのコードだけ文字コードが Shift_JIS
- 日本語が文字化けして文字リテラルが2byteに収まらない
- テンプレートが Shift_JIS だった

## 経緯

オンラインジャッジ特有の標準入力をサクっと受け取るためのライブラリを書いていた。
ジャッジ用ということで、細かいケース含め単体テストを記述。
動作やパフォーマンスの検証が完了しリリースしようかなぁとリポジトリ作成作業をしていた時に事件発生。

ローカルでバリバリ動作してたコードで突然に「普通の」コンパイルエラー。
パッと思いついた原因候補はなし。
内容で検索かけても「JSのつもりで文字列リテラルをシングルクォーテーションで括ってたわ」程度しか見つけられず。
とはいえそういう「普通の」ミスではない、構文は合っているようにみえる。

CIの構成に問題があるのかと、CIに設定してるコマンドと同じコマンド ( `dotnet build` とか `dotnet test ...` ) をローカルで実行すると普通に通る。
トータルで検討に1時間くらい溶かした。

で、最終的に「OS依存かなぁ」と疑って、WSL環境でcloneしてビルドしたところでエラー再現。
(WSLだったので)VSCodeで状況確認したところ日本語の文字化けを確認した。
エディタの文字コードをUTF8からShift-JISに変更すると解消したため、ここですべてを察してゲームクリア。

## 解説

Windows環境ではShift_JISでも自動的に正しく扱ってくれるようだが、CIを含めた今回のLinux環境でShift_JISをUTF-8と解釈してしまっていたようだ。

だがしかし、Shift_JISのソースコードをUTF-8として解釈しても、asciiな部分に関しては正しく読める。通常、ソースコードの大部分はasciiに収まるので大体正しく読める。

正しく読めない筆頭は日本語だが、日本語が出るのはコメントとか文字列くらい。
しかし、コメントも文字列も `//` とか `"` のようなasciiなトークンが正しく読めていれば(日本語が文字化けしていても)コンパイラ的には一応OK。

化け方の運もあるが、コメントは無視され、文字列リテラルも文字化けした文字列リテラルができるだけで済む可能性がそれなりに高い。

ただ、文字リテラルだけ中身が文字化けすることで(C#はUTF-16なので)2byteに収まらなくなりコンパイルエラー。ゆえにエラー内容は文字リテラルに文字が多すぎる、である。
文字以外はコンパイラ的には無事なので、ここだけピンポイントでエラーになっていた。

根本的になぜShift_JISになったか、という点だが、VS上で新規にファイルを作成する場合、何かのプロジェクトかアイテムのテンプレートを選択するのが一般的だと思うが、このテンプレート自体の文字コードに影響されたようだ。

コンソールアプリケーションのプロジェクトテンプレートで作成したライブラリ本体は(MS特有のBOMつきの)UTF-8になっていたが、xUnit単体テストのテンプレートで作成したテストコードだけShift_JISになってしまった。

その後だが、気づいてしまえば単純で、全部UTF-8に統一してあっさり解決した。めでたし。

## 感想

「文字リテラルだけ」「テストコードだけ」というのが結構ニッチできつかった。
いい加減Shift_JISは滅んでもいい気がする。
中途入社者向け共通オンボーディングの感想

:::note info
この記事はLITALICO Advent Calendar 2023のカレンダー2の13日目の記事です。
https://qiita.com/advent-calendar/2023/litalico
:::
# はじめに
はじめまして！今年の9月に[株式会社LITALICO](https://litalico.co.jp/)に入社しました、@s_ykです。
現在は就労移行・定着支援事業所向け業務システムのQAエンジニアのお仕事をしています。

転職してから3か月、たくさんのサポートをいただきながらキャッチアップを進めてきました。
HRチームの方が主導してくださっている**中途入社者向けの共通オンボーディング** のうち、
**入社初日のオリエンテーション**と**ななメンター制度**についての感想を書いていきたいと思います。

:::note info
HRチーム目線でのお話は
@sayaka_hashiさんが昨年のアドベントカレンダーで書いてくださっています！
[エンジニア・デザイナー組織の中途入社オンボーディングの考え方と作り方](https://note.com/rai527/n/na408efd33d62)
:::

# 入社前の私
前職では、自社内で働く障害を持つ社員の就労支援を担当していました。
それぞれの特性に合わせた成長支援を行い、活躍の場を広げていくサポートをするような
とてもやりがいのある仕事をさせていただいていました。

その仕事と並行して福祉について学んでいく中で
就労サポート以外のアプローチで障害福祉をより良くしていくことにも興味を持ち、
以前から[ビジョン](https://litalico.co.jp/about/vision/)に共感していたLITALICOへの転職を決め、今に至ります。

そんな経緯で、入社前からやる気はいっぱいでした。
ですが、就労支援の前にQAエンジニアの経験があるといってもブランクが約7年あり、
もともとそんなにITに強くない私はついていけるのだろうか…と不安もいっぱいでした。

# 入社初日のオリエンテーション

>服装：自由 ※スーツである必要はございません。普段通りの服装でお越しください

と、事前にとても丁寧な連絡をもらっていたにもかかわらず、
不安でいっぱいすぎてスーツを着て会社に向かいました。
会社に到着してみるとスーツなのは私だけ。
まだ9月だったので、ジャケットが暑くて汗だくになりました。

:::note info
未来に中途入社される皆様、服装自由と言われたら本当に自由で大丈夫です！
（もちろんスーツでもOK！）
:::

入社初日はPCセットアップや事業説明、オフィスツアー、
同期・配属先の方々とのご挨拶など、当然ながらたくさんやることがありました。
この状態で明日以降の説明を聞いても頭がパンクしてしまいそう。
しかも明日からはほぼ毎日在宅勤務、
困っても聞ける人が横にいるわけではない…と心配になるところでしたが、
この日に共有していただいた **セルフオンボーディングシート** が役に立ちました。
入社後にやるべきことがチェックリストになっており、それぞれにリンクが貼ってあり、
実施時期の目安が書いてあり、このおかげで直近やらなくてはいけないことの見通しが立ちます。
不安な私にとっては見通しが立つことがとてもありがたく感じました。

また入社同期の方との自己紹介の時間があり、
**入社同期の方との横のつながり作り** もサポートしていただけていると感じました。
当たり前のことではありますが、入社者それぞれにいろいろなバックグラウンドがあること、
配属先によってこれからそれぞれが多様な仕事をしていくことを実感し、
「こういう方もいるのか」「そういう仕事もあるのか」と自然と視野が広がりました。

初日の緊張でへとへとになりつつ、なんとなく頑張れそうな気がする！と感じられたのは
迎え入れてくれた皆さんの**温かい雰囲気**と
HRチームの方々のオリエンテーションのおかげだなあと思います。感謝！

# ななメンター制度
入社して1か月が経ち、セルフオンボーディングシートに沿ってのキャッチアップや
配属先での研修課題が終わり、担当するプロダクトでの業務に少しずつ入り始めた頃に
**ななメンター制度** について連絡がありました。

> 部署外のつながりづくりとLITALICOのカルチャー理解促進を目的に3ヶ月間
>「ななメンター」が月に1回1on1を実施してみなさんのオンボーディングのサポートをします。

楽しみに思いつつ、業務上での関わりの薄い方がわざわざ自分のために時間を取ってくれる…
なんだか申し訳ないような気もしていましたが、小さな困りごとを聞いてもらったり
担当プロダクトについて教えていただいたり、普段と違う角度でのお話に気づきがありました。

その1か月後にも2回目の時間を取っていただいたことで、
聞きたいことや相談したいことの変化に自分で気が付く良いきっかけになったように思います。
また、日常業務の中で関わりの少ない方に聞いたり相談したりする過程で
頭の中が整理されたり、うまく言語化できないことや理解できていないことが
明確になったりしてとてもありがたかったです。


# おわりに
今回は初日のオリエンテーションとななメンター制度の感想を書かせていただきましたが
LITALICOでは他にも中途入社者向けにたくさんの取り組みが行われていて、
中途入社でもこんなにしっかり受け入れしてもらえるのか！と正直驚きました。
冒頭でご紹介した@sayaka_hashiさんの[記事](https://note.com/rai527/n/na408efd33d62)に書かれているように
しっかり制度設計をし運用を考えられている方がいて
それに部署全体で協力する文化があるからだなあと、率直に素敵なことだと感じています。

色々な方の協力のおかげで3か月間たくさん学んでこれたことに感謝しつつ、
これからは自分も貢献していけるように頑張りたいと思います！
3年ぶりにElixirのAtCoder用Mixタスクライブラリを更新しました

この記事は「Elixir Advent Calendar 2023 シリーズ 1」15日目の記事です。

---

ElixirのAtCoder用Mixタスクライブラリ[Kyopuro](https://hex.pm/packages/kyopuro)を更新したのでそのことを書きます。

:::note warn
知見の共有ではなくただの振り返りです。
:::

Kyopuroを最初に公開したのは2020年11月でそのときもアドベントカレンダーで書きました。

当時はElixirで競技プログラミングをやっていました。そんな中TwitterのTLで見かけた[QWYNG/green_day](https://github.com/QWYNG/green_day)に触発されて自分も作ろうと思い立ち作成したのがKyopuroになります。
しかし作ったはいいもののそこで競技プログラミングに対するモチベーションが消えてしまい、最後にKyopuroを更新したのは2020年12月と3年経ってしまいました。

そんな中TwitterでElixirのアドベントカレンダーの話題を目にしたときに、ふと昔書いたな～なんてKyopuroのことを思い出し、手元で動かしてみたらAtCoderのログイン処理に変更が入っていて動かなくなっていました。
さすがに動かないものを公開しておくことは気が引けますし、社内ではなく外部向けに何かを発信することをもう長い間していなかったのでこれをネタにアドベントカレンダーを書くか！という気持ちでライブラリを更新することに決めました。

## どうやって更新していくか

時間をあまり割くことができないのはあらかじめわかっていたので

1. YukiCoderのサポートを落とす
2. 既存のコードを理解してつじつまを合わせるのではなくスクラップ&ビルドで1から書き直す
3. うまくやろうという気持ちは捨てて愚直な実装

を方針に更新をしました。

1については自己満足で実装しただけで自分自身使わなかったし多分誰も使っていないだろうと思ったので決めました。

2についてはコードにコメントがほぼなかったのと、IFを変えることにしたので決めました。

3についてはあまり時間がとれないというのに加えて初心に帰ろうというのもありました。

作業内容としては

1. 本筋と関係ないもの系の修正
    1. 当時IntelliJ IDEAを使用していたが現在はVSCodeなのでIDEA用のファイルを削除
    2. [jdx/rtx](https://github.com/jdx/rtx)を使用するように変更
2. 使用しているライブラリのバージョンアップおよび変更
    1. 使用しているライブラリのバージョンが古くなっていたので最新のものに変更
    2. 当時HTTPクライアントに使用していた[finch](https://hex.pm/packages/finch)だとCookie関連で不都合があったので他ライブラリの選定
    今新しくHTTPクライアントを使用するなら[req](https://hex.pm/packages/req)だろうと思い調査していたがこちらも結局不都合があったので結局安定の[HTTPoison](https://hex.pm/packages/httpoison)を採用
3. 内部処理の修正
とりあえずfinchで書かれていた個所をHTTPoisonに置き換えて動くようにすることから始めました。その中で[Netscape cookie file format](https://docs.cyotek.com/cyowcopy/current/netscapecookieformat.html)というものを知ったのでCookieの保存方法としてこれに準拠したフォーマットを採用してみました。
後はMixタスクのIFをこれまでは引数として受け取っていたのをプロンプトから選択・入力できるようにしたりすることにしたのでそれに合わせて全体的につじつまを合わせていきました。

結果として冗長な実装やもうちょっとどうにかならんのかみたいな実装がポツポツありますが、今回はコメントを多めにしたので今度はうまくライブラリを更新しろよ？と未来の自分に託します。もちろんIssue・PR歓迎です！アクションをもらえるとモチベーションにもなります。

と、周囲に共有するような知見が得られたわけでもなく自己満足の振り返りだけですが、本記事の結びといたします。

## 最後にKyopuroの紹介を…

Kyopuroの提供する機能は

- ログイン
- モジュール・テストコードの生成
- 提出

です。

#### ログイン

ログインは`mix kyopuro.login`を実行してください。認証情報はプロンプトから入力、もしくはConfigから取得させることができます。

[詳細はこちら](https://hexdocs.pm/kyopuro/Mix.Tasks.Kyopuro.Login.html)


#### モジュール・テストコードの生成

モジュール・テストコードの生成には`mix kyopuro.new`を実行してください。モジュールとテストコードが生成されます。デフォルトで生成されるモジュールはmain関数が定義されただけなので、お好みに合わせてモジュールテンプレートを作成しConfigで設定してください。

[詳細はこちら](https://hexdocs.pm/kyopuro/Mix.Tasks.Kyopuro.New.html)

#### 提出

提出には`mix kyppuro.submit <提出したいファイルのパス>`を実行してください。

[詳細はこちら](https://hexdocs.pm/kyopuro/Mix.Tasks.Kyopuro.Submit.html)

各コマンドの詳細は`mix help kyopuro.~~`で確認していただくか、hexdocを見ていただければと思います。

---

明日の「Elixir Advent Calendar 2023 シリーズ 1」16日目は @kikuyuta さんです。乞うご期待ください！
PukiWikiローカルサーバ環境構築(php/XAMPP導入手順 )

# PukiWikiとは？

公式サイトより
> A. 通称「Wiki」(正しくは:WikiWikiWeb)と呼ばれているツールの一つです。

自前サーバーやレンタルサーバー等でも運用可能なツールです。
xサーバーは簡単にインストール出来る様な仕組みもあります。

今回は開発環境を整えたいので、ローカル環境にPukuWikiをインストールしてみました。


# 開発環境

Windows10 Home
XAMPP(v3.3.0)
PukiWiki(v1.5.4)
PHP version 8.1.20

### XAMPPを導入

https://www.apachefriends.org/jp/index.html

上記サイトからWindows向けのインストーラーをダウンロードしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/7d7338ab-2716-bc4b-94b9-896f3cebf51a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/13c55898-c53b-5c4b-f004-aa337099471d.png)
Nextを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/94aaba02-d057-3ca4-a3af-7e64c531c0b7.png)
必要なコンポーネントを選択してNextを押下します。
不要なコンポーネントはチェックを外して大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/c3660194-28a0-ed0d-4a3f-c4592a0f9671.png)
インストールするディレクトリを指定してNextを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/0cf75566-017c-22cf-6180-aa69e14021cb.png)
言語を選択してNextを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/6409449e-56d0-e459-db77-b92630e130bd.png)
Nextを押下するとインストールが始まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/792f0759-6fac-8067-8879-0fb46ce99f54.png)
インストール中の画面です。
コンポーネント全部チェックを入れたら約5分くらい待ちました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/79b59ddd-4476-f5e8-2df7-193ceb6d4bd8.png)
チェックマークをつけるとXAMPPのコントロールパネルが起動します。 
インストールが完了したらFinishを押下します。 


# Apacheを起動してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/cd375669-d331-6de3-8df6-3ef9ec4edfcf.png)

Apacheのスタートを押下するとApacheが起動します。


## ポート・ローカルホスト変更

PortとListenが他のサービスが使用されていてApacheが起動出来ないエラーが発生しました。対処法として使用しているポートを停止するかXAMPPのポートを変更します。 

XAMPPのport変更は下記の方法で行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/7bea7e1a-64b6-3267-530b-99448b7a1ff5.png)
Config>Apache(httpd.conf)を変更します。

又は下記のディレクトリを直接変更しても大丈夫です。
c:\xampp2\mysql\bin\my.ini

60行目辺りにある Listen 80　をお好みの数値に変更します。
228行目辺りにある　ServerName localhost:80 をお好みの数値で変更します。

変更後再度Apacheは再起動してください。

# ローカルサーバー起動確認(XAMPP)

http://localhost:80/ 
または変更したサーバーネームにアクセスしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/247e0461-c72f-de5c-9dab-d58f879391d1.png)

# PukiWikiダウンロード

下記サイトよりPukiWiki本体のダウンロードを行います。

https://pukiwiki.sourceforge.io/?PukiWiki/Download

C:\xampp\htdocs\直下にダウンロードしたファイルを置きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/4176900c-f9af-287f-cff3-173db47077ff.png)

# ローカルホスト確認(PukiWiki)

起動確認を行います。サーバーネーム以降のURLは基本的にファイル名と同様で大丈夫です。 

例: http://localhost:80/pukiwiki-1.5.4_utf8/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3028739/8f0da3a6-49c9-b240-70a2-38834b370aec.png)

無事起動できました！お疲れ様でした。
この方法は他のPHPサイトの環境構築にも使える（かも）しれないので、是非参考にしてみてください。XAMPP簡単に使えるので良いですね。
dockerでrails7(API)を構築

# はじめに
この記事は2023年度の振り返りです。

今回、electronアプリ構築に伴いのバックエンドをrails(API)で新規で構築したので、それを備忘録です。

# ディレクトリ構成
```
compose.yml
api(ディレクトリ)
 ├ Dockerfile
 ├ Gemfile
 └ Gemfile.lock
```

# 準備
```js:ファイル生成
touch compose.yml
mkdir api/
touch api/Dockerfile.dev
touch api/Gemfile
touch api/Gemfile.lock
```

```bash:compose.yml
services:
  api:
    build:
      context: ./api
      dockerfile: Dockerfile.dev
    container_name: api
    ports:
      - 3000:3000
    environment:
      RAILS_ENV: development
      DB_HOST: mysql
      DB_NAME: root
      DB_PASSWORD: password
    depends_on:
      - mysql
    volumes:
      - ./api:/api

  mysql:
    image: public.ecr.aws/docker/library/mysql:8.1
    container_name: mysql
    volumes:
      - mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
      TZ: "Asia/Tokyo"

volumes:
  mysql_data:
```

```bash:Dockerfile.dev
FROM public.ecr.aws/docker/library/ruby:3.2.2-slim as base

WORKDIR /api
ENV LANG=C.UTF-8 \
  TZ=Asia/Tokyo


#################
# build
#################
FROM base as build

RUN apt-get update -qq && \
  apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev git libvips pkg-config && \
  apt-get clean && \
  rm -rf /var/cache/apt/archives/* && \
  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY Gemfile Gemfile.lock /api/

RUN gem update --system \
  && gem install bundler
RUN bundle install

COPY . /api

#################
# development
#################
FROM base as development

RUN apt-get update -qq && \
  apt-get install --no-install-recommends -y build-essential default-libmysqlclient-dev git libvips pkg-config && \
  apt-get clean && \
  rm -rf /var/cache/apt/archives/* && \
  rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

COPY Gemfile Gemfile.lock /api/

COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /api /api

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```
```js:Gemfile
source 'https://rubygems.org'
gem 'rails'
```

# プロジェクト構築
```bash:コマンド
docker compose build
```


```bash:rails newのコマンド
docker compose run --rm api rails new . --force --database=mysql --api \
--skip-action-mailer \
--skip-action-mailbox \
--skip-action-text \
--no-skip-active-job \
--skip-action-cable
```


```bash:database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV.fetch("DB_NAME") %>       # ←この行を修正
  password: <%= ENV.fetch("DB_PASSWORD") %>   # ←この行を修正
  host: <%= ENV.fetch("DB_HOST") %>           # ←この行を修正
```


以下のコマンドでrailsのトップページが表示されるか確認(一部過剰ですが)
```bash:コマンド
docker compose build
docker compose run --rm api bundle exec rails db:drop db:create db:migrate db:seed
docker compose up
```
http://localhost:3000/

# さいごに
dockerに関しては、railsで自動生成されるので開発環境については、さらっとした感じに作成しました。
今後の記事はrails多めになります。
Cloud Functions for Firebaseで毎回使うちょっとした細かいこと

## 背景

Cloud Functionsで細々と開発をしているのですが、秘伝のタレ化してきたので、細かいことをまとめてみます。


### index.js以外のファイルで関数を増やしたい場合

複数のAPIを生やしたり、pubsubを走らせたい場合に、`index.js`以外のファイルで関数を増やしたくなる場合があります。
そのような場合は、下記のようにします。


index.jsで別のファイルをrequireしexportsする形にします。
また、`admin.initializeApp()`はindex.jsのみに記述します。そうすることで他の関数ファイルでの記述は不要になります。（記述してしまうとエラーになります。）

```js:index.js
import * as admin from "firebase-admin";
const firebase = admin.initializeApp();

const OtherFunc = require("./OtherFunc");
exports.OtherFunc = OtherFunc;
```

```js:OtherFunc.js
exports.OtherFunc = functions
  .https.onRequest(async (request, response) => {
  console.log('hello')
}
```

#### 参考

https://firebase.google.com/docs/functions/organize-functions?hl=ja&gen=2nd#write_functions_in_multiple_files


### TypeScriptで開発時に、変更をすぐにFunctionsに適応したい。

`firebase init`時にTypeScript環境を設定して、エミュレーターで開発しだしても、TypeScriptをFunctions用のJSにリアルタイムで変更を適応してくれません。

なので、package.jsonでtscのwatchスクリプトを追加します。

```json:package.json
"scripts": {
  "watch": "tsc --watch"
}
```

### 参考

https://firebase.google.com/docs/functions/typescript?hl=ja


##　pubsubで設定した実行頻度をブラウザで変更する

deployを通さずに、pubsubの頻度を上げ下げできると外出中に便利だったことがあったので、メモ。

Google Cloud コンソールからCloudSchedulerへアクセス。
変更したいFunctionにチェックボックスを入れて、上部の編集をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/3aec768e-a9b2-7644-d611-f0367f30d7a1.png)


下記の画面に移動するので、頻度の部分を変更し、更新します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/aeaf97b5-1173-2e2d-8c73-3e72308262ef.png)

ここで変更した値は、コードをdeployすると上書きされるので注意が必要です。


## 関数のタイムアウト時間をブラウザで変更する

Google Cloud コンソールからCloudFunctionsへアクセス。

変更したい関数を選択し、関数の管理画面にアクセスします。
上の方に`編集`があるので、編集をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/e4994adf-af20-8a1b-5e4f-878d5f8b643b.png)

ランタイム、ビルド、接続、セキュリティの設定をクリックすると、下記のようなメモリやタイムアウトを編集できる画面が出てくるので、こちらを編集し、更新します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3589058/5bba7cfa-4c1e-0691-4dc6-c5c1dd0d96c2.png)


### 参考
https://firebase.google.com/docs/functions/manage-functions?hl=ja&gen=2nd#set_timeout_and_memory_allocation
適度な運動のすゝめ

# はじめに
この記事は[Life is Tech ! Advent Calendar 2023](https://qiita.com/advent-calendar/2023/life-is-tech) シリーズ2 14日目の記事です。

みなさんごきげんよう。うめちゃんと言います。本業は大学生ですが、Life is Tech!のMinecraftプログラミングコースでメンターもしております。
今日は最近始めてみたらとても調子が良くなってきたことについて書きます。マイクラについては後日ちゃんと真面目に書く予定です。

# 健康体でいたい
ITエンジニアやプログラマー、そして我々大学生はディスプレイを直視して座っている時間がどうしても長くなる。するとどうしても姿勢が悪くなる。姿勢を維持するにも筋肉が必要だ。
古のエンジニアたちは言う。「椅子には金を掛けろ」と。昇降デスクに手を出す者もいる。立って仕事ができるのはいいが、一週間ほどで飽きて結局座って使うようになることが多いと聞く。
どうすれば真の健康体を得られるのだろうか。道具に頼るのでは無く、自ら身体を動かせば良いのではないかと考えた。

# 習慣化の難しさ
運動はした方がいい。そんなことはずっと前から分かってはいた。しかしどうしても長続きしない。高校生の頃から筋トレをしてみたり、ランニングをしてみたりということはあったが、いつも三日坊主にすらなれなかった。
二度の大学受験と過酷な実験レポート漬け生活を経て身体は限界であった。「健康体になりたい。」そう願う日々が続いた。
どうすれば習慣化できるだろうか。一人でやっているとどうしても意思が弱くなるのではないかと考えた。そこで、一緒に運動をする仲間を作り共同監視の仕組みを整えてみることにした。

# 仲間を作ろう
大学というのは素晴らしい場所で、色んな人がいるから何かを始めたいとき仲間を探すにはもってこいの場所だ。
入学以来仲良くさせてもらっている留学生の友人で、自分と同じように実験レポートに苦しめられてきた者がいた。彼は強い意志の持ち主で、日頃から筋トレとランニングを行っていた。そこで、彼が運動をするときに一緒にやっても良いかと頼んだ。彼は快く了承してくれた。
彼と毎週月曜の夕方に学内を2,3周する約束をした。そのために研究室の自分の机にはランニングシューズと動きやすい服装が常備されている。最初は頻度は高くなくて良いし、走る速さもゆっくりで良い。とにかく習慣化することが大切だ。
週1回のランニング以外にも、毎日家で腕立てや腹筋、スクワットなどの筋トレをしている。筋トレの後は忘れずに柔軟体操も取り入れている。運動をした後はたんぱく質の多い食事を心掛けたい。

# 記録を取ろう
運動したら記録を取りたい。その友人から教えてもらったおすすめのアプリがある。[Strava](https://www.strava.com/?hl=ja-JP)というアプリなのだが、スマートフォンのGPSを使って様々な運動を記録できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370590/742def2b-2ee6-684c-e2b5-fa4fdd83c6e4.png" width=400px>

下のように標高やペースも記録される。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370590/253e6942-2bd9-fefc-4889-1e80d5c60a01.png" width=300px> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/370590/ddc2ffae-0379-3443-4606-8eb9a6c8dc1a.png" width=300px>

有料のサブスクリプションもあるが、現状無料版の機能で十分満足している。スマートウォッチ等のデバイスとの連携機能もある。

# 目標を設定しよう
友人は駅伝に出場するなど目標を定め、それに向かってランニングをしていた。自分もそれに倣いたいと思っていたところに、ちょうど良いお誘いが来た。高校生の頃お世話になっていた市の中高生向けの施設でときどきボランティア活動をしているのだが、そこのスタッフさんから「市民駅伝のランナーを募集している」との連絡があった。これはまたとないチャンスだと思い、手を挙げた。
本番は1月で、5kmを走らなければならない。チームに迷惑は掛けられないので、ペースも上げていかなければならない。

# 運動の習慣を身に付けてみて
運動をするようになってから何だか身体の調子が良い気がする。よく眠れるし、休みの日は外に出ようという気にもなるし、研究のインスピレーションも湧いてくる。
大学にフルマラソンを3時間強で完走する先生がいる（全盛期は3時間切りだったらしい）。その先生の講義を受けていただけの頃は「すごいなぁ」としか感じていなかったが、走るようになってからは「どうやったらあの先生に近づけるだろうか」と考えるようになってしまった。
Crystalでクリップボードを扱う安直なShardを書いた話

## はじめに

アドベントカレンダーのネタがいよいよありません。
3週間ぐらい前に、小さなCrystalのShardを作ったことを思い出しました。これの紹介をまだQiitaに書いてなかったと思うので書きます。

# easyclip

マルチプラットフォーム（Linux, Mac, Win) でクリップボードをCrystalから扱うライブラリです。といっても、難しいことは一切しておらず、極めて安直な実装になっています。

https://github.com/kojix2/easyclip

使うときは `shard.yml` を書いて

```yaml:shard.yml
dependencies:
  easyclip:
    github: kojix2/easyclip
```

`shards install` を実行してください。すると、こんな感じで動きます。

```cr
require "easyclip"

# テキストをクリップボードにコピーする
EasyClip.copy("たぬき")

# クリップボードのテキストを取り出す
str = EasyClip.paste
puts str
# => たぬき
```

## 実装は…

こんな感じで、OSごとに指定のコマンドを用意して、標準入出力を使ってコピーまたはペーストしているだけです。

```cr
  private def copy_command
    {% if flag?(:darwin) %}
      "pbcopy"
    {% elsif flag?(:unix) %}
      "xsel -ib"
    {% elsif flag?(:win32) %}
      "clip"
    {% end %}
  end

  private def paste_command
    {% if flag?(:darwin) %}
      "pbpaste"
    {% elsif flag?(:unix) %}
      "xsel -ob"
    {% elsif flag?(:win32) %}
      "powershell.exe -command Get-Clipboard"
    {% end %}
  end
```

予想通りでしたか？

さらに細かいコードはこちらから見てください。

https://github.com/kojix2/easyclip/blob/main/src/easyclip.cr

なお、Windows は `clip.exe` の仕様のため、どうしてもコピーした文字列に改行コードが入ります。

## 安直な実装はよくないか

上記の実装をみて、「なんだよー。こんなことかよ…。」って思ったかもしれません。

しかし、自分で言うのもなんですが、こういった安直な実装は意外とバカにならないと思うんですよね。OSのAPIなどを使って、きちんとしたライブラリを作る人はすごいと思いますが、今回のような安直な実装であれば、少ない行数で実装できる上に、当分はメンテナンスフリーで動き続けるはずです。Crystal言語のようなマイナー言語を使う場合は、メンテナンスのコストは特に減らす必要があり、こういった格好悪いけど、壊れにくいタイプの実装もありではないかと思います。

## Process がやや使いづらい

あと、こんな簡単な実装でもわりと罠にはまると完成には時間がかかったりします。Crystalの標準ライブラリの `Process` の仕様が使いにくいところがあり、ドキュメントを見てもわからずソースコードを当たったりしました。マイナー言語のつらいところです。

## Crystalのライブラリは壊れやすいか？

これは少し物議を呼ぶ発言かもしれませんが、Crystalは自作のツールに他人が作ったライブラリを導入するハードルがRubyよりも高いと感じます。その理由として、Shardは不具合を起こすことが多いように感じます。RubyのGemと比較すると、CrystalのShardは寿命が短いのではないでしょうか。

もちろんその理由として、Crystalが若い言語であり、1.0以前は仕様の変更が多かったこと、ユーザーが少ないためバグに目が届かないこと、結果的にメンテナンスが継続的ではないことが大きいと思います。

しかし、静的型付け言語の型の許容性の低さも、Shardの寿命の短さと無関係ではないでしょう。Rubyの場合は、10年前に放置されたライブラリであってもそれなりに動作することは少なくありません。しかし数年前に作成されて放置されたCrystalのライブラリが動く確率はかなり低いと思います。型がずれるとすぐ動かなくなるのはバグの発見を容易にしますが、一方で過去の放置資産を使うことを難しくしており、エコシステムの拡大を阻害している一つの要素であると僕は思っています。

こういったことがあるので、私は「Crystalは静的型なのでRubyよりも優れている」という立場を私は採用していません。Crystalの動的な性質が好きです。

この記事は以上です。
ポータルについて


業務の中でMUIの`Autocomplete`を触る中で、ポータルという概念を知ったので、メモです。

:::note ポータルとは何か？
ウェブ開発において、「ポータル」とは、あるコンポーネントを、通常のDOMツリー（HTMLの階層構造）から切り離して、別の場所にレンダリングする技術のこと。これは主に、オーバーレイ（画面の上に表示される要素）やポップアップなど、他の要素の上に表示させたいUI部品に使われる。
:::

### なぜポータルを使うのか？
ポータルを使う主な理由は、「スタッキングコンテキスト」の問題を回避するため。ウェブページの要素は通常、そのHTMLの構造に基づいて画面に表示される。しかし、この方法だと、親要素のスタイルやサイズに影響され、意図しない位置に表示されたり、他の要素に隠れてしまうことがある。特に、ドロップダウンメニューやモーダルウィンドウなど、画面全体に表示したい要素にとっては問題になる。

ポータルを使用することで、これらの要素をHTMLの階層構造から独立させ、親要素のスタイルや制約から解放され、画面上の任意の位置に自由に表示させることができる。
フォルダー内のファイルの更新日をサブフォルダ含めて一括で変更する方法

### フォルダー内のファイルの更新日を変更する

何かの制約でフォルダー内のファイル更新日を変更したいとします。手で開いて保存を繰り返すのはどうかと思います。
そこで自動化しますが、開いて閉じてを繰り返すのではなく、windowsの機能を使い、ファイルを開かずに更新できます。

### 以下がそのスクリプトです。

```powershell
$folderPath = 'C:\path\to\your\folder' # 変更したいフォルダのパス
Get-ChildItem -Path $folderPath -Recurse | ForEach-Object {
    if ($_.IsReadOnly) {
        $_.IsReadOnly = $false
    }
    $_.LastWriteTime = Get-Date
}
```

読み取り専用の場合はエラーになるので、それを解除しながら更新していきます。

以上です。
GitHubにSSH接続で認証してみる

# 環境
Ubuntu 23.04
# はじめに
VScodeではそのままPushできるのにCursorでは毎回アクセストークンの入力が必要になっておかしいので、SSHでログインできるようにした。
# 手順
## 公開鍵の作成
`.ssh`に移動して作成する
```bash
$ cd ~/.ssh
$ ssh-gen -t rsa
```
上記の`rsa`の部分を好きな名前に変えてください
コマンドを入力すると下記のように聞かれますが、全部エンターでOK
```bash
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):id_git_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```
## 公開鍵の登録
下記URLからGitHubに公開鍵を登録する

https://github.com/settings/ssh

`Key`の部分に作成した、`id_rsa.pub`の内容を貼り付ける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/a6846a9d-659b-6ff3-7419-2820ab8ae945.png)

## 接続の確認
```bash
$ ssh -T git@github.com
```
で、

```
Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
```
と出たら成功

# sshを通してpushまでする
```bash
$ git remote -v
```
でリモートリポジトリがHTTPSで接続されてることを確認したら、
```bash
$ git remote set-url origin git@github.com:<ユーザ名>/<レポジトリ名>.git
```
これで行ける
# おわりに
疲れた
# 道中で得た知見
## コマンドでターミナルを起動する
`alt+F2` > `gnome-terminal`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3531484/38d372c0-48a8-a00c-2812-6698e624e9be.png)

## ターミナルからクリップボードにコピーする
linuxには標準でクリップボードにコピーするコマンドがないので、新たにインストールする
```bash
$ sudo apt install xsel
$ cat id_rsa.pub | xsel -b
```

## エイリアスの作り方
```bash
$ sudo vim ~/bashrc
$ alias clip='xsel -b'
```
# 参考文献
https://qiita.com/shizuma/items/2b2f873a0034839e47ce

https://zenn.dev/naoki_mochizuki/articles/ce381be617cd312ffe7f

https://yoshiyoshifujii.hatenablog.com/entry/2014/08/12/230144
git pull origin developができない

## git pull origin developができない

### 解決コマンド例
以下のように2段階に分けて実行すると上手くいく場合がある。

```git
$ git fetch origin develop
```
```git
$ git merge origin develop
```

上記を理解する補足説明

- pullはfetchとmergeを1度で実行するコマンド
- fetchはリモートリポジトリの最新情報をローカルリポジトリに取ってくること。
    - fetchという単語自体、「取ってくる、呼んでくる」という意味。
- mergeでその最新情報を反映させる。
社用PCでのネットワーク接続に必須！プロキシ設定とは

# 1. はじめに
社用PCでアプリケーションをネットワークに接続するためにプロキシの設定を求められます。そこで、プロキシ設定について調べた内容を記事にします。

# 2. プロキシ設定とは
プロキシ設定は、コンピュータネットワークにおいて通信を仲介するためのプロキシサーバーを指定することです。プロキシサーバーは、クライアントとサーバーの間に位置し、クライアントのリクエストを代理で受け取り、それをサーバーに中継します。同様に、サーバーからのレスポンスもプロキシサーバーを通じてクライアントに返されます。

# 3. プロキシ設定のメリット・デメリット
## メリット
- 匿名性を確保できる
- プロキシ上にアクセスログを残せる
- アクセスの制限ができる
- サイトの画面表示の高速化が期待できる
- プロキシ上でウイルスチェックができる
## デメリット
- サイトの画面表示の遅延

# 4. 終わりに
プロキシ設定について理解が深まれば幸いです。
ホロリーをVRで見れるようにしてみた

# 概要
ホロライブのVTuberをARで撮影できる神アプリ「[ホロリー](https://hololive.hololivepro.com/special/1937/)」ですが、没入感あるVRで見られたら楽しそうと思い、機材を組み合わせてやってみました。

# 構成
次の機材を組み合わせて使います。
* WiFi
* スマートフォン
  * アプリ：ホロリー
  * アプリ：PCと画面共有できるソフト★
* PC
  * アプリ：スマートフォンの画面を表示できるソフト☆
  * アプリ：VRヘッドセットと画面共有できるソフト■
* VRヘッドセット
  * アプリ：PCの画面を表示できるソフト□

★☆どうし、■□どうしは画面共有するソフトの組になっています。

私が具体的に使った機材は次のものです。
* 自宅のWiFi
* iPhone12 mini
  * ホロリー version 2.4.5
  * LetsView version 1.4.8 ( 3 ) Basic plan
* ASUS TUF Dash F15 (Windows 11)
  * LetsView version 1.3.3.2 Basic plan
  * Virtual Desktop Streamer version 1.29.10
* Oculus Quest 2
  * Virtual Desktop 1.29.10

# やりかた
順にアプリを立ち上げていきます。
1. スマートフォンでPCと画面共有できるソフト★を起動し、PCでスマートフォンの画面を表示できるソフト☆を起動して、スマートフォンの画面がPCで表示されている状態にします。この時点で横向きの全画面表示にしておくとよいです。
![LetsView_PC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854691/ed3b3b7b-1207-38d4-518f-e51ec149bf20.png)
1. ホロリーを立ち上げ、ARモードを立ち上げます。好きな表情・好きなポーズに変更し、消失ボタンを押してUIを非表示にします。スマートフォンを横向きに持ち替えます。これでPC側で、横向きのホロリーが全画面表示になっているはずです。
![LetsView_hololy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854691/7e76102e-779a-40e5-2060-ff77ed8669c4.png)
1. PCでVRヘッドセットと画面共有できるソフト■を起動し、VRヘッドセットでPCの画面を表示できるソフト□を起動して、PCのデスクトップ画面がVRヘッドセットで表示されている状態にします。このとき、アプリ□の設定で、VRヘッドセットに合わせてPC画面が目の前に移動しつづけるようにします（Virtual Desktop では Head Lock モードを有効にします）。また、その移動の際のディレイを0秒にします（Virtual Desktop では SETTINGS の Remove head lock delay にチェックを入れます）。これで、VRヘッドセットを動かしたときにもPC画面が目の前に表示され続けます。
![virtualdesktop_setting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854691/ef8730db-ea6b-a7c8-e68c-2048cf5572c2.jpeg)
1. スマートフォンをVRヘッドセットの目の前に設置します。VRヘッドセットと一緒にスマートフォンを手で保持してもいいですし、輪ゴム等で固定するのも可能でしょう。ただし、落としてスマートフォンの画面をヒビだらけにしないようにご注意（そうなっても責任はとれません）。
![Grasp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854691/b0401773-cc25-4b61-fdd0-f6038116e3fb.png)
1. ホロリーをVRヘッドセットで見て楽しみます。

# 課題
* __他のデバイスへの対応__
  * Android系、別のVR機器でも、同種の機能のアプリがあれば原理的にできるはずです。私は持っていないので、有志の方は探してみてください。
* __出先でWiFiをどう確保するか__
  * 散歩しているときや旅行先に撮影するのがホロリーの醍醐味と言えますが、上記のやり方は全ての機材を WiFi で繋いでいることが前提なので、WiFiが使えない状況だと難しいです。スマートフォンでテザリング（インターネット共有）して、そこにPCとVRヘッドセットを接続すればできるかもしれませんが、通信遅延が重すぎるかも。Bluetoothで通信できる画面共有アプリもあるようなので、そういう手も検討してもいいかもしれません。
* __PCがまどろっこしい__
  * 理想を言えば、スマートフォンの画面をVRヘッドセットで直接表示できれば、PCが不要になります。そのようなアプリを見つけられず、自力で開発するノウハウもないので、上記のやりかたにしました。自力で開発できる凄腕の方がいらっしゃったら、開発するという手もあるのではと思います。

# おわりに
_Have a happy hololy life !!_
関数と変数を使い分けて読みやすいコードを目指そう

## はじめに
実務では日々プルリクエストを作って、先輩からレビューをいただいています。
入社して1ヶ月ごろ、関数で書いたものを変数で書いた方がいいと言われ、修正したことがありました。
初心者でなければ、そんなの当たり前と言うような簡単な話かもしれませんが…
私と同じようなプログラミング初心者の方が、関数と変数を使い分けることで読みやすいコードを書けるように、共有したいと思います。

## 具体例で説明
### 背景
- ファイルをドラック&ドロップで別のフォルダに移動する機能が実装されている。
- 移動したときに、どのフォルダに移動したのかわかりにくいという意見が出た。
- そこで、移動先のフォルダ名を移動前にアラートで表示させることになった。

### 目的
- フォルダの名前を取得する

### 設計
- フォルダーの配列`folders`から、移動先の`folderId`に合致する`folder`を取得する
- その`folder`の`name`を参照する

### 実装
配列のfindメソッドを使って、`folders`から移動先の`folderId`に合致する`folder`を取得しました。
そして、取得できた`folder`の`name`を参照します。
findメソッドは**要素が存在しない場合はundefindを返す仕様**なので、`?.`(**Optional chaining**)と`??`（**Nullish coalescing**）で`undefind`の場合は`空文字`を返すように書きました。
```react
const getFolderName = (toFolderId: number): string => {
  return folders.find((folder) => folder.id === toFolderId)?.name ?? '';
};
```
一見良さそうですね。
結構自信満々でプルリクエストを出したのですが…
メンターさんからレビューで「ここは関数にしなくてもいいのではないか。その場で値を取って、変数に代入すればいい。」と言われました。

特に何も考えずに関数で書いていましたが、変数に入れればいいというのです。どういうことでしょうか？🤔

## 関数の結果を変数で書いた方がいい例
:::note warn
- 原則、関数の中に関数を書かない方がいい
- コードが短い（処理が簡単）なとき
- 使い回す必要がないとき
:::

### 関数の中に関数を書かない方がいい
理由は、ネストが深くなってコードが読みにくくなるのを防ぐためです。
実は今回書いた`getFolderName`関数は、`moveFile`という関数の中に書いていました。
まさに関数の中に関数を書いてネストしてしまっている状態です。
できる限り、関数の中に関数を書くのは避けましょう。

### コードが短い（処理が簡単）なとき
処理が簡単なら、わざわざ関数にして長ったらしく書く必要はないということです。

### 使い回す必要がないとき
1回しか使わないものをわざわざ関数に書く必要はないということです。
しかし、将来的に同じ処理が他の場所で必要になることもあるため、関数にまとめておくと後で使い回しやすいというメリットもあるようなので、判断が難しいですね😲


## レビュー修正
上記を踏まえて検討すると、今回は処理も一行で短く、１回しか使わないので変数として定義した方が良さそうです。
ついでに変数名も直します。
```react
const folderName = folders.find((folder) => folder.id === nextFolderId)?.name ?? '';
```
確かにこっちの方がスッキリして見やすくなりました。

## 私なりのまとめ
学んだことを備忘録として、私なりに噛み砕いて自分の言葉でまとめてみます。
- 無駄なものはできる限り書かないって意識が良さそう！
- 関数と変数を使い分けるというよりは、変数で定義するとわかりにくいものを関数で定義するって考えた方がいいかな？
- 将来的に使い回すかもしれないものは関数に切り出しておくのもあり

## 終わりに
特に意識しないで書くと、読みにくい無駄なコードを書いてしまうことがあります。
傾向はあるかもしれませんが、確実にこうした方がいいと言う基準ではないようなので、都度根拠を考えながらコードを書いていきたいです。
JointJSのViewとは何なのか

今回の記事ではJointJSのViewについて書きます。

## JointJSのView

JointJSで描画されるすべてのCellには、Cellに対するViewがそれぞれ存在します。
このViewは[Backbone.jsのView](https://backbonejs.org/#View)を継承しています。

JointJSの[`dia.CellView`のドキュメント](https://resources.jointjs.com/docs/jointjs/v3.7/joint.html#dia.CellView.intro)によると、Viewは以下の役割を担っていると記載があります

- Paper内の要素のレンダリング
- Cellのポインタイベント処理
- Cell操作のための方法を提供する

つまり、JointJSでのSVGの描画やユーザー操作への対応の実装のためにBackbone.jsのViewを利用している、というだと思います。

## Viewの使い方

JointJSのViewは様々な使い方ができます。ここでは個人的に使用頻度が高いと感じるものを紹介します。

### Paperからの検索

PaperからCellを探すとき、直接Cellを探すことができないためViewを経由して検索を行います。

例えば以下のコード例では、座標を元にCellを探すことができますが、`findViewsFromPoint`から直接取得できるのはViewになります。

```js
const views = paper.findViewsFromPoint({x: 110, y: 50});
```

### イベントの引数

各種イベントにロジックを組むとき、イベントで呼び出すメソッド内でViewを参照することができます。

```js
paper.on("cell:pointerdown", function(cellView) {
  // cellViewからアクセスしてCellを利用した処理を行う
})
```

### 要素のオブジェクトへのアクセス

Viewに含まれる`model`プロパティにはGraphへ登録されているCellの参照が登録されています。そのため、Viewさえ見つけられれば`model`経由で要素の情報の取得や、編集を行うことができます。

```js
// Cellをクリックしたらテキストを変更するサンプル
paper.on("cell:pointerdown", function(cellView) {
  cellView.model.attr('label/text', 'view経由で変更');
})
```

## まとめ

今回はJointJSのViewについて簡単に紹介しました。View自体は描画されているわけではなく掴みどころが難しい概念ですが、実際の処理の中で扱っていくうちに便利さを感じることができます。

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

https://qiita.com/advent-calendar/2023/jointjs
【rust】crontabで動くコマンドの管理を楽にするラッパーをrustで作ってみた

# はじめに

Linux環境で定期的に実行したい処理は、cronを使うことが多いと思います。
しかし、cronでは下記の点でシェルスクリプトの作りが悩ましくなります。

* ログがきちんと取れないので、問題があった時に対処が大変
* 同時実行を抑止したい場合に作り込みが必要
* 終了した場合の通知をスクリプトに書き込む必要がある

こんなケースを解決するために、上記悩みを解決するラッパーをrustで作成しました。

> cronを使わずにsystemdのtimer使えば悩みは解決しますが…
> 定期処理を一元管理するにはcrontabで指定するのが使い勝手がいいんですよね…

# 機能紹介

crontabで下記の様に書き込むだけです。

```
* * * * * ezcron -r /path/to/report.sh job01 -- /path/to/yourscript1
```

この指定で、

* ログの実行毎に```/var/log/ezcron/%Y%m%d-%H%M%S-job01.log```にstdout,stderrの内容が記録されます。
* ```job01```は任意に設定可能です。```job01```と設定されたスクリプトは、同時実行を抑止します。
* ```-r```で指定したスクリプトが、スクリプト終了時に実行されます。

毎分動く指定をすれば、ログファイルが大量になってしまうので、ログの削除をcronで実行すれば良いかと…

```
0 0 * * * ezcron -r /path/to/report.sh job02 -- find /var/log/ezcron/ -type f -mtime +30 -exec rm {} \;
```

同時実行を許可したければ、```ezcron```のオプションで```-m```を指定すれば同時実行されます。

# インストール

とりあえず、[ここ](https://github.com/abtoc/ezcron)にに公開してあります。
バイナリは、

* x86_64-linux
* armv7-linux

を準備してあります。

# rustを使ってみた感想

C、C++を嗜んで来ましたが…依存ライブラリについての苦労は全く無くなったので、大分と楽になりました。
エラーもヒントを出してくれるので、　C、C++に比べると大分と親切ですね。
でも、借用兼については大分と悩まされましたが、堅牢なバイナリが出来上がると思えば、その苦労はしなきゃいけないんだろうな…と思っております。

# バイナリ配布につて

ビルド＆リリースについては、"github actions"に丸投げです。
制限はありますが、便利な時代になったものです。

# 最後に

ソースを公開するのって恥ずかしいですね。
初めてのrustで作ったので、rustの書き方として間違ってる！とかの指摘もあるかと思います。
issueでもQiitaのコメントでも指摘頂けると助かります。

また、こんな機能も欲しい！というのがありましたらコメ頂けると幸いです。
STM32F303Kの書き込み問題が発生した時に読むTips

## STM32F303Kで書き込めない

PlatformIOでの書き込みエラーが発生した時にどうすればいいか？とりあえず手順書を書きます。

## まず試すべきこと

いつからかはわからないが何らかのアップデートの拍子でPlatformIOでF303Kに書き込めなくなったって人はこれを試そう。

`platformio.ini`の`upload_protocol`を`mbed`に設定するだけです。

```
upload_protocol = mbed
```

これで大半は治ります。

## これでも治らない時

とりあえず状況を整理します。

- 今まで書き込めていたけど書き込めない
- パソコンを変えたら書き込めない
- 初めての基板に書き込めない

## 今まで書き込めていたけど書き込めない

ST-LINKのファームウェアが何かの拍子に飛んだ可能性があります。一旦ファームウェアアップローダーを利用して焼き直してみると解決することがあります。

https://www.stmcu.jp/design/sw_dev/pc_soft/53401/

## パソコンを変えたら書き込めない

ドライバーのインストールを忘れていませんか？インストールしないとうまく動かない場合がほとんどなのでWindows勢の人はインストールを忘れないようにしましょう。

https://www.st.com/ja/development-tools/stsw-link009.html

また、PlatformIO自体の再インストールも効果があることがあります。これはVSCodeの拡張機能からのアンインストールだけでなく、ホームディレクトリにある`.platformio`を確実に消した方が安全です。

## 初めての基板に書き込めない

まずST-LINKを正しく認識しているかを確認します。Windowsだったらデバイスマネージャーを見るだけです。Macだったらこのコメント叩くだけです。

```zsh:
% ls -l /dev/tty.*
```

これがだめだったらそもそもハードウェアが死んでる可能性大です。自作基板の場合、

- BOOT0の処理は正しいですか？
- NRSTの処理は正しいですか？
- 電源は供給されていますか？

だいたいこの三つが原因です。

## 他にも

僕が他にハマったことがある原因一覧です。

- MicroUSBケーブルが充電専用
- パソコンの許容電流量を超えてしまい、保護カイロが働いてしまって動かない
- 書き込めてはいるが、プログラムがフリーズしてるだけ

特に配列の要素外を参照して止まるのはあるあるなので一回メモリを安全に扱えているかチェックしてみてください。

## 終わりに

終わりです。
Gmailなどのフリーメール容量の削除-何を残して何を削除する-

# はじめに
フリーメールの容量が増えてきたので無駄なメールを削除し容量を確保したいと考えた。

容量のアップデートに課金してもいいが無駄なものが残っている状態で課金するのもなぁと。

しかし、何を削除して何を削除するとまずいのか判断がつきづらい。
重要なメールとはなんぞや、どれなら削除していいのか。
その際の判断基準を自分なりに残しておく。

# 結論
未読メールを基準に削除する。
→重要なメールはおそらく確認しているだろうから。
また、ログイン情報などは近年メールアドレスで再発行できるので最悪捨てても問題ないかと。

またバックアップをとっておくと安心
バックアップの取り方↓（UI少し違うが）
https://atmarkit.itmedia.co.jp/ait/articles/1612/05/news023.html

# ステップ
未読メールを全て削除。
と言いたいところだが、未読だが重要なメールがあるかもしれない。
その際にいくつか目視で判断を行う。

## 目視対象
・件名に「会員登録」が含まれるもの
件名に"会員登録"とはいったものを検索し目視で確認する。
重要なメールがあれば開いておく。
以下同じ作業。

・「登録完了」が含まれるもの

・件名に「重要」が含まれるもの
→~~多くが重要ではない~~

・明細がメールにしか残っていないもの（必要であれば）

・金銭絡みのメール
証券や銀行口座、FX口座など

・「License」が含まれるもの
何らかのライセンスコードが含まれる可能性

# 未読メールの削除
なんでもいいが以下の記事など参考に一括削除（全削除と間違えないように）
https://office-hack.com/gmail/batch-delete/

# 最後に
本記事で不利益を被った場合保証はしません。
自分なりにやってみて、消さなければよかったメールあった。。
などあればここに追記していきます。
なければ一応不自由ないんだと思います、多分。
バックアップ大事なのでバックアップとってからがおすすめです。本当に。
NSSのAlertログをSIEMに送信する設定をしてみた

# はじめに
本記事はゼットスケーラー株式会社としては初の[Advent Calender 2023](https://qiita.com/advent-calendar/2023/zscaler)の一つとして投稿しています。以下の免責事項をご理解の上、記事を読んで頂けると幸いです。
# 免責事項
本記事のコンテンツや情報において、可能な限り正確な情報を掲載するよう努めておりますが、 誤情報が入り込んだり、情報が古くなったりすることもあり、必ずしもその内容の正確性および完全性を保証するものではございません。そのため、本記事をエビデンスとしたゼットスケーラーへの問い合わせなどはご対応致しかねることをご理解頂けると幸いです。掲載内容はあくまで個人の意見であり、ゼットスケーラーの立場、戦略、意見を代表するものではありません。当該情報に基づいて被ったいかなる損害について、一切責任を負うものではございませんのであらかじめご了承ください。
# NSSとは
Nanologストリーミングサービス(NSS)は、仮想マシン(VM)を使用して、Zscaler NanologからSplunkやArcSightなどのセキュリティ情報およびイベント管理(SIEM)システムにトラフィックログをリアルタイムでストリームし、リアルタイムのアラートや他のデバイスのログとの相関、ローカルの長期ログアーカイブを可能にします。

次の図に示すように、Webとファイアウォールのログは、ZscalerクラウドのNanologに保存されます。組織は、ESX仮想マシン上のオンプレミス、AWS上のEC2インスタンス、またはAzure上の仮想マシンとして、NSSインスタンスを展開できます。組織が1つのNSSをWeb用に展開し、もう1つのNSSをファイアウォール ログ用に展開すると、各NSSはZscalerクラウド内のNanologへの安全なトンネルを開きます。Nanologは、帯域幅のフットプリントを削減するために、ログのコピーを高度に圧縮された形式で各NSSにストリーミングします。元のログはナノログに保持されます。

NSSはNanologからログを受信すると、それを解凍してトークンを解除し、設定したフィルターを適用して不要なログを除外し、フィルターを適用したログを設定した出力形式に変換してSIEMで消費および解析できるようにし、生のTCP接続を介してSIEMにログをストリーミングします。
![スクリーンショット 2023-12-12 23.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/af378d6f-4c82-e9d7-d7e9-1eafe7ed25a8.png)

また、次の図に示すように、NSSの監視のために、NSSのAlert用の別のフィードを設定することが可能です。この設定により、NSSとWebLogを受信するSIEM間の接続問題などを検知して監視用SIEMにAlertを送信することが可能です。
![スクリーンショット 2023-12-13 0.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/5e04760a-ddea-2402-daa2-3b4406a11d3c.png)

このAlertサービスは、RFC 3164 BSD syslogプロトコル形式のアラートを、指定されたIPアドレスとポートに送信します。次の表に、各レベルに対して送信されるアラートを示します。
![スクリーンショット 2023-12-12 23.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/6f0e6de1-cc6a-6e6f-939e-c0a2a74c1b75.png)


# Alert用NSSフィードの追加
本記事では、Alert用NSSフィードの追加手順を紹介します。

<b>Step1.Alert用NSSフィードの作成</b>
Log Typeで[Alert]を設定します。
![スクリーンショット 2023-12-12 23.36.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/69e43d29-bf75-fa0e-1d1c-d42be8ec1355.png)

<b>Step2.Splunk側で受信設定を追加する</b>
ここでは、SIEMサーバとしてSplunkを使用します。Setting > Data Input > TCP において、受信ポート番号をNSSFeedで追加したパラメータと同一の値に設定します。
![スクリーンショット 2023-12-12 23.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/9aaa5d0a-f9c3-d7d8-61ad-18beb8db71b4.png)

<b>Step3.確認</b>
NSSとWebLog用のSIEMとのネットワーク断を発生させると、以下のようにAlertが確認できます。
![スクリーンショット 2023-12-12 23.56.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3638225/be441e6e-0569-19e6-dfe3-cbe079237a66.png)

# まとめ
NSSのAlertログをSIEMに送信させる設定を紹介しました。Zscaler側の設定は簡単なのですが、Splunkの設定の方で少し悩みました。NSSの導入時に参考にしてください。