OmniAICreator/Qiita-1.07M huggingface dataset:
スタンバイ社は「面白い」か？

私は2023年10月にスタンバイ社入社、試用期間中。
プロダクトマネージャー（PdM/Planner）である。

入社した理由は簡単で、「面白そう」だったから。
何が？という話と、実際どうだったかの話をしたいと思う。

## 比較的、想像どおりだったこと

### 役割について
エンジニアとPdM/Plannerの立ち位置、強みをざっくり言語化するなら、

**エンジニア　→ 「具体」**
**PdM/Planner　→ 「抽象」と「具体」をいったりきたり**

だと思っている。
<br>

**「抽象」=未来、戦略**
**「具体」=足元、戦術**

としたときに、スタンバイ社は「具体」が強い。
「抽象」に弱いということではなく、「具体」がとても強い。

だから「抽象」をもっと強くして「具体」と接続すれば、最強である。
そこに私の役割もあると想像していたし、今のところその通りだと思う。

### 人について
「なぜあなたはこの会社で働いていますか？」

入社面接などで、必ず面接官に聞くようにしている質問だ。
悩まれる面接官も多いが、スタンバイ社COOの山本は、こう答えた。

「自分の証明のため」
「自分はこの事業を成功させると表明したので、それを証明するため」

いい意味でのプライド×事業への思いがひと言で表現されていると思った。
この人と働くことは面白そうだと思ったし、今のところその通りだと思う。

## 比較的、思っていたのと違うこと
### 役割について
冒頭に「プロダクトマネージャーである。」と書いたが、実は人事も兼務している。

ミッションは、
「直近のエンジニア採用成功と、継続的なエンジニア採用のベースを作ること」。

**事業を作るのは戦略
戦略を作るのは戦術
戦術を実行するのは組織・人**

領域こだわらず課題を出して提示したら、
解決実行していいよとなったのでPJT化してPMになった。

前職で、専門職の評価制度を変えたくて人事異動をぼやいていたこともあり、
この流れは嬉しい想定外だった。

### 人について
入社前に、「スタンバイ社はとにかくいい人が多いです」と伺った。
ちなみに前職の入社前にも、「弊社はとにかくいい人が多いです」と伺った。

前職から想像していた「いい人」は、こんな人たち。
* 困っていることがないか気にかけてくれる人
* 気さくに話しかけてくれる人
* その場が和やかになるコミュニケーションを大事にする人

入社してみて、想像していた「いい人」はそんなにいなかった。
ただ、こんな人たちがいた。

* こちらの知識不足や準備不足に嫌な顔をせず時間を割いてくれる人
* 自分の基準（キャリア、技術）をしっかり持って業務に向かっている人
* 常に物事を前に進めようと意志を持って行動する人

「いい人」で括ってしまうのはもったいない想定外だった。

##  つまり何が言いたいかというと
前職に大きな不満はなく、環境ポジションにも恵まれていたと思う。
そして当然、新しい会社、別のビジネスモデルへのコミットは必要カロリーも大きい。
<br>
それでも「面白そう」ととびこんでみたスタンバイ社が、本当に「面白い」か？

本当の答えは半年後、一年後により明瞭になると思う。
が、今のところは「面白い」し、まだまだ「面白そう」である。

## 最後に

スタンバイでは、事業とサービスを一緒に作っていただけるエンジニアを募集しています。
スタンバイ <a href=https://qiita.com/advent-calendar/2023/stanby>Advent Calendar 2023</a>や、<a href=https://techblog.stanby.co.jp/>Stanby Tech Blog</a>の記事を読んで、弊社に興味をもっていただけたら嬉しいです。
カジュアルな面談で、情報交換も含めぜひ一度お話してみませんか？
ぜひお気軽にお声がけください！

* <a href=https://hrmos.co/pages/stanby-inc/jobs/100100463>カジュアル面談はこちらから</a>
* <a href=https://hrmos.co/pages/stanby-inc/jobs?category=1445664202436182016>株式会社スタンバイ エンジニア の求人一覧</a>
zshで詰まったメモ

# 再現方法
こんなコードを書いたとする
```zsh
dest="~/Documents/hello"
echo 'hoge' > $dest
```
一見良さそうだけど、`zsh: no such file or directory: ~/Documents/hello`というエラーに叱られる
# 解決策1
```zsh
dest="/Users/payashi/Documents/hello" # 絶対パスにする
echo 'hoge' > $dest
cat $dest # `hoge`と出力される
```
# 解決策2
```zsh
dest=~/Documents/hello # クオーテーションで囲まない
echo 'hoge' > $dest
cat $dest # `hoge`と出力される
```

# 原因
クオーテーションで囲ってしまうと相対パスから絶対パスに変換できなくなる
Metaversal deploymentを使ったスマホとQuest3のマルチプレイ

# はじめに
本記事は[Iwaken Lab.](https://iwakenlab.jp/Iwaken-Lab-95875f8ad38f434b9bc473b7ecf14983)アドベントカレンダーの12日目の記事になります。 

https://qiita.com/advent-calendar/2023/iwakenlab

[だーらさん](https://x.com/3tdara?s=20)による前日の記事「CTO/エンジニアリングマネージャー 1年目の軌跡」についてもぜひ一読して頂けると幸いです！

https://zenn.dev/flamers/articles/924e3eb0c4d464?redirected=1

# サンプル
以下はスマホとQuest3でマルチプレイを行い、オブジェクトを動かしている様子です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/ybQG48iVs2o?si=To1s0AXumplOiqu_&amp;start=21" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

これは8thwall社のMetaversal deploymentという仕組みと、Shared ARという機能を組み合わせることで実装できます。以下でそれぞれについて説明していきます。

# Metaversal deploymentとは
Metaversal deploymentとは[8thwall](https://www.8thwall.com/)社が提供している仕組みで、これにより8thwallを使って作ったARアプリは**PCやMeta Questなど様々なデバイスで動かすことが出来ます。** 
これはデフォルトの仕組みなので何か設定をしたり、コーディングをする必要はありません。

https://www.8thwall.com/blog/post/59297774102/introducing-reality-engine-8th-wall-webar-moves-beyond-the-smartphone
 
以下はその例で、一番左のスマホのARアプリがPCやMeta Quest2でも体験できるようになっています。

<img width="32%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/5548531d-f64a-72e1-1707-716d11747f9d.gif">

<img width="32%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/fcfa9b1b-8f5e-3803-4aae-e7f2f9e6afdc.gif">

<img width="32%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/491303eb-d8a7-7c3e-dc5a-b9f0aa181d04.gif">

また、ARアプリをMeta Quest3などで動かすとカラーパススルーを使うことが出来るので、スマホでのARと同じような体験ができます。

<img width="70%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExM3E1eHozanB5N2FuOW5yOGtqajczMnc4NXdtbXlkeGFyOWM2MTZwMyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/u7CILMsfboV7JdaPoW/giphy-downsized-large.gif">

# Shared ARとは
Shared ARとは8thwallが提供している機能で、ARオブジェクトを複数のプレイヤーで共有できる機能です。これによりマルチプレイ可能なARアプリを作ることが出来ます。

https://www.8thwall.com/8thwall/modules/shared-ar

また、Metaversal deploymentの仕組みにより、Shared ARの機能があるARアプリもPCやMeta Questで体験できるようになります。

そのため、**スマホとスマホ間のマルチプレイだけではなく、スマホとPC間、PCとMeta Quest間など様々なデバイス間でマルチプレイのARができるようになります。**

# つまり
Shared ARによってARアプリでマルチプレイ機能を実装し、Metaversal deploymentによってそのアプリがスマホだけでなくPCやMeta Questなどでもできるようになったため、スマホとQuest3のマルチプレイ出来るようになったということです。

# 注意点
Shared ARでは**各々が座標系を持ってしまい、全体で共通なオブジェクトを置けない**ので注意しましょう。（相対座標しか使えず、絶対座標が使えない。）
![Metaversal deployment_v2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2700137/574a7635-6db6-ef7e-2670-65da6d8d8116.jpeg)

# おわりに
次は、@wappaboyさんの記事になります。ぜひご期待ください！
(2023/12/13 追記)
以下の記事です！

https://zenn.dev/moze_ai/articles/unity-gpt-api-sample
TsukuCTF23 writeup

# はじめに
TsukuCTF 2023にWani Hackaseとして参加して1位を取ることができました。（完全にチームメイトのおかげですが）ということで折角なので参加記を残そうと思います。Qiita初投稿なのでところどころ読みづらかったり、説明不足だったりするかもしれませんが、大目に見てもらえたら助かります。
# new cipher sceme[cry]
基本的にはRSAですが以下のmagic関数を用いてp+qを処理した値sが追加で得られます。
```python:magic
def magic2(a):
    sum = 0
    for i in range(a):
        sum += i * 2 + 1
    return sum


def magic(p, q, r):
    x = p + q
    for i in range(3):
        x = magic2(x)
    return x % r
```
ここからp+qを求めることができればn=p*qと合わせてp, qが得られるので嬉しい。
ということでぐっと睨んだり手を動かしたりすると、magic2は引数の二乗を返す関数だとわかります。

例１）$magic2(4) = 1+3+5+7 = 16$
例２）$magic2(6) = 1+3+5+7+9+11 = 36$

ここで、以下の処理
```py
for i in range(3):
    x = magic2(x)
```
は2乗を3回行っており、$x := x^{2^3} = x^8$と等しいです。

よって、magic関数は$x^8\ (mod\ r)$を返すのですが、奇素数rを法としたときの平方根はTonelli-Shanksのアルゴリズムを使うと求まるので、3回適用すれば$x\ (mod\ r)$が得られます。

ここで、
- $p+q \simeq 2^{512}$

- $r \simeq 2^{1024}$

であることから、$x\ (mod\ r) = x$です。
以上より、
- $x = p+q$
- $n = pq$

を解くことでp, qが得られるので、あとは$\phi$を計算して$d$を求めたらOKです。（実家のような安心感）

一見よくわからないmagic関数がp+qの8乗を返していたり、Tonelli-Shanksを3回使うことで8乗根が求められたりとcryptらしさが強くて面白い問題でした。

# what_os[misc]
ざっと配布されたtty.txtを見ているとetc/gettyが目に入りました。調べてみるとUnix/Linux系統のOSにあるファイルのようです。

また、calコマンドで1971年と出力されているので「相当古いんだろうな～」と思いながら当てはまるものを調べていくとUnix Version1, Unix Version2などが条件を満たしそうです。

他のOS分からないし、ひとまず入れてみるかとUnixを試したらFlagが取れました。適当の極み

# build_error[misc]
main.oとone.oをghidraでデコンパイルしていい感じに整形したらなんとかなるだろ！と頑張っていたら良さげなコードを作ることができました。
```c
#include <bits/stdc++.h>
using namespace std;

long a, b, c;

void one_init();

int main(){
    int i;
    long local_30;
    long loopLimit;
    long local_20;
    
    local_30 = 12;
    loopLimit = 11;
    local_20 = 75;
    one_init();
    for (i = 0; i < loopLimit; i = i + 1) {
        if (i < local_30) {
        local_20 = local_20 + 1;
        }
        if (local_20 < i) {
        loopLimit = loopLimit + 1;
        }
        local_30 = local_30 + 1;
    }
    local_20 = local_20 + local_30 + loopLimit;
    if (local_20 == c + a + b) {
        printf("flag is %ld\n",local_20);
    }
    else {
        puts("please retry");
    }
    return 0;
}

void one_init(void){
  int local_c;
  
  a = 0xc;
  b = 0xb;
  c = 0x4b;
  for (local_c = 0; (ulong)(long)local_c < b; local_c = local_c + 1) {
    if ((ulong)(long)local_c < a) {
      c = c + 1;
    }
    if (c < (ulong)(long)local_c) {
      b = b + 1;
    }
    a = a + 1;
  }
  return;
}
```
これを改めてコンパイルして実行することでFlagをGETしました。適当の極み２
変数名を色々付け直したり、ライブラリまで調べたりとghidraの練習に丁度いい問題でした。

# 最後に
TsukuCTFに参加するのは初めてでしたが様々なOSINT問題があって面白かったです。（解けたとは言っていない）
来年はOSINTも得点源にしていきたいですね。
運営の皆さん、楽しいCTFをありがとうございました。
レビュー依頼をNotionにまとめるSlackワークフローを作ってみた

## 概要
みなさんはこんな経験ありませんでしょうか・・？

- Slack上で「レビューお願いします！」と投げたはいいものの、他の投稿で埋もれてしまい忘れ去られてしまう
- GitHubのPRやリリース手順書など、「レビューが必要なモノ」の状況が今どうなっているかわからない

私の所属するチームでは、上記のような課題を抱えていたため、それらを解決するためのワークフローを作成しました。

## 使用技術

- AWS API Gateway
- AWS Lambda
- Slack ワークフロー
- Slack bot (Slack App)
- Notion API

## 仕組み
![review-qiita2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/5d68fc4a-2ebd-83ac-83ce-9a8a209f86d0.png)

① 依頼者がSlackワークフローからレビュー依頼を投稿
② ワークフローがSlack botをメンションで呼び出す
③ メンションをトリガーとして呼び出されたSlack botがAPI Gatewayにリクエストを送信
④ API Gatewayにリクエストが送信されたことをトリガーにLambda関数を呼び出す
⑤ Lambda関数がリクエスト内容をもとにレビュー内容・依頼者の情報を読み込み、Notionにレビュー依頼内容をエクスポートする

※　詳しい実装方法は今回割愛します

## 実際に使ってみる

レビュー依頼投稿用のワークフローは以下のような形式になっております。

<img width="530" alt="ワークフロー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/158a5069-4d5b-f148-c85b-370f3b5b3b6e.png">

※　`slack-app-for-mention`はメンションをトリガーにAPI gatewayへリクエストを送るSlack botです。


チャンネルのショートカットからワークフローを起動し、レビュー内容を入力します
![スクリーンショット 2023-12-12 8.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/52f0fc09-e44e-7438-9d27-2016416d4fee.png)

Submitボタンを押すと、レビュー依頼がグループに投稿されます。
![スクリーンショット 2023-12-12 7.22.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/6bae60c5-9f57-acf5-51ce-571676a4c5a1.png)

あらかじめ作成しておいたNotionの「レビュー依頼一覧ページ」を確認してみると...

![スクリーンショット 2023-12-12 8.23.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/689205/43db594a-c25d-2688-d055-c60017267326.png)

Notionでレビュー依頼一覧が見られるようになっていました！

## 導入した結果

今回作成したワークフローをチームに導入した結果、以下の効果が得られました。

- リリース手順書やGitHubのPRなどレビューが必要なモノの一覧・ステータスが一目でわかるようになった
- Slackに投稿したレビュー依頼が他のメッセージで埋もれ、忘れ去られることが減った
- レビュー依頼一覧ページを確認し、こまめにレビューをする習慣を作ることができた

## おわりに
SlackワークフローやNotion APIなど、普段使用しているコミュニケーションツールが提供する拡張機能を活用することによって、業務改善をすることができました。
みなさんもこうした拡張機能を活用して、業務改善にトライしてみてはいかがでしょうか。

## 実装にあたって参考にした資料

### Notion API関連 

https://developers.notion.com/

https://zenn.dev/kou_pg_0131/articles/notion-api-usage


### Slack bot 関連

https://www.beex-inc.com/blog/slackbot-aws-lambda

https://qiita.com/landwarrior/items/dfac36a1aadac9ab0cd5
小さなバスルームを広く見せるための 7 つのハック

バスルームは家の中で最も重要なスペースの1つです。一日の始まりの準備をしているときも、夜に向けてくつろぐときも、私たちは皆、この居心地の良い聖域を楽しんでいます。しかし、小さなバスルームや専用バスルームがある場合、窮屈で不快で、乱雑に感じられることがよくあります。
幸いなことに、小さなバスルームをより広く見せて、より多くの部屋を確保するための省スペースハックがいくつかあります。実際、これらの賢いトリックを使えば、新たなバスルームの改修にお金をかけずに、スペースを最大限に活用することができます。さらに、20 ドル未満でバスルームを改装して、小さなスペースに大きな変化をもたらすこともできます。
そこで、広々としたスパのような隠れ家を作りたいなら、小さなバスルームを広く見せるための 7 つのハックをご紹介します。
1.超大型ミラー
おそらく、この本の中で最も古いトリックは、大きな鏡の使用です。これは光を反射し、部屋が広く見えるようにするのに効果的です。実際、特に自然光や窓があまりない場合、鏡を使用すると、小さな空間がすぐに開放的で風通しの良い雰囲気になります。
専門家は、シンクの上に小さな鏡を吊るすのではなく、壁全体、または少なくとも広い範囲を鏡で映すことを推奨しています。より現代的な雰囲気をお望みの場合は、丸い形のデザインがバスルームに適しています。
あるいは、この 4 個セットの FÄRGEK 装飾ミラー ( $11、IKEA )のように、鏡をいくつか吊るして装飾として使うこともできます。鏡は基本的に窓のように機能し、より多くの光を部屋に取り込み、視覚的により広いスペースを与えます。
2. 照明器具の明るさ向上
バスルームに窓がない場合、または自然光が足りない場合は、より明るい照明器具を取り付けてください。これは十分な光を提供すると同時に、暗い部屋を明るくするのにも役立ちます。
天井の照明を変更できない場合は、化粧台エリア、キャビネットの下のストリップ照明、または壁に取り付けられた燭台を照らすために、この FOMAYKO LED バスルームミラー ( $129、Amazon ) のような LED ミラーの薬棚を検討してください。これらの照明オプションはすべて、小さなバスルームをより広く見せるのに最適です。
通常、バスルームの LED 照明には、温白色、昼光色、冷白色の 3 つの異なる色調があります。専門家は、自然光を増やすよりも昼光照明に投資する方が望ましいと示唆しています。
3. 重いカーテンやブラインドを取り除く
同様に、窓辺の装飾によって自然光がかき消され、小さな空間がより窮屈に感じられることがあります。このため、できるだけ多くの光を取り入れるために、重い/暗いブラインドや薄手のカーテンを取り除きます。
プライバシーの要素を維持し、まぶしさを軽減するには、ウィンドウ プライバシー フィルムまたはガラス ウィンドウ デカールを購入できます。これらはガラスを傷つけることなく簡単に貼り付けられます（また剥がすこともできます）。さらに、これらは手頃な価格で、この LEMON CLOUD ウィンドウ フィルム ( $9、Amazon ) のように、ほとんどのホームセンターやオンラインで入手できます。
覗き見を防ぐだけでなく、コンパクトなバスルームの魅力的な装飾機能としても機能します。
4. 壁掛けタオル/アクセサリー
バスルームアクセサリーを置くカウンタートップのスペースが限られている場合は、代わりに壁に取り付けてみてはいかがでしょうか? タオル、バスアメニティ、さらにはソープディスペンサー用のラックであっても、壁に取り付けられたラックやバーは貴重なスペースを有効に活用できます。
さらに、透明な痕跡のない接着剤でタイルに貼り付けるだけの、「穴あけ不要」のバスルーム収納オーガナイザーに投資することもできます。繰り返しになりますが、これは化粧台を乱雑にせずに商品を展示するための良い方法です。
必需品を保管するために、フック付きのラックやフローティングシェルフを選択することもできます。これらのシャリオ ホワイト フローティング シェルフ ( $27、Amazon )はスリムで、コンパクトなバスルームに最適です。
5. バラバラのアイテムは見えないところに保管してください
同様に、スペースが散らかったり整理整頓されていないと、小さなバスルームがさらに狭く感じることがあります。バラバラのアイテムを保管するために、魅力的な編まれたバスケットや透明な容器に投資し、可能であれば保管してください。小さなスペースでは、少ないほど良いので、すべてを整理整頓し、できるだけ最小限に保ちます。
さらに、中身を対応するキャニスターまたは透明なディスペンサー ボトルに移して、見苦しいペットボトルを隠します。これにより、スパのような隠れ家全体の美しさがさらに高まります。
さらに一歩進んで、エッセンシャルオイルディフューザーや香り付きキャンドルなどのフレグランスを追加して、新鮮な香りを保つこともできます。実際、バスルームを良い香りにし、ゲストに好印象を与える 5 つの簡単なハックをご覧ください。
6. 反射器具を使用する
古き良き鏡のトリックと同じように、光沢のあるタイルやクロムのバスルーム設備などの反射面は、より広い空間のような錯覚を生み出します。
既存のシャワーヘッドとバスの蛇口を真鍮またはクロムのバス器具に交換するだけです。光沢のある表面は自然光を反射するだけでなく、バ​​スルームに洗練されたモダンな外観を与えます。
スパのような隠れ家を作りたい場合は、さまざまな設定を備えた豪華なレインフォール シャワーに投資するか、モダンな雰囲気を演出する LED 照明付きのものを選択してください。さらに、クロム仕上げの この GURIN シャワーヘッド 高圧レイン、高級バスルーム シャワーヘッド ( $20、Amazon )のように、大金を費やす必要さえありません。
朝と夜どちらにシャワーを浴びるべきか知りたい場合は、専門家の意見を調べてください。
7. ナチュラルな装飾アクセントを追加する
石、木、リネン、籐などの自然な装飾のアクセントは、部屋に圧迫感を与えることなく、風通しの良い雰囲気を作り出す傾向があります。リネンや籐の収納バスケット、または石造りのバスルームアクセサリーを選んで、バスルームに視覚的な魅力を与えることができます。
さらに、青々と茂ったヤシの木やミニチュアの多肉植物は、バスルームを大幅に改装し、リラックスできる雰囲気を作り出すことができます。植物は、床、浮き棚、窓辺、座っている場所、さらには浴槽の上に置いても素敵に見えます。
ジャングルを作らないように、スペースに適したサイズの適切な植物を常に選択してください。

source: https://officetips.wiki/ja/%E6%96%B9%E6%B3%95/%E5%B0%8F%E3%81%95%E3%81%AA%E3%83%8F%E3%82%99%E3%82%B9%E3%83%AB%E3%83%BC%E3%83%A0%E3%82%92%E5%BA%83%E3%81%8F%E8%A6%8B%E3%81%9B%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE-7-%E3%81%A4%E3%81%AE%E3%83%8F%E3%83%83%E3%82%AF/11101064
車検証の分割QRコード（連結QRコード）を読み取る

# そもそもQRコードとは


:::note warn
QRコードは株式会社デンソーウェーブの登録商標です
:::

***Q***uick ***R***esponse  --- 素早く読み取る・反応する　という意味のようです。

1994年に株式会社デンソーウェーブにより開発された。2006年には国際規格に制定され、QRコードの仕様がオープン化されています。

## 「QRコード」という文言は商標登録
※結構重要なのですが「QRコード」という文言を使用する場合は登録商標文記載が必要です。↑記載してます。

一般名称は  ***「２次元バーコード」*** とのこと。
２次元バーコードは、QRコード以外にAztec,Code49,DataMatrix,MicroPDF417,PDF471など

## 誤り訂正機能
QRコードが汚れてたり一部認識できなかったりしても認識できるような仕様で、誤り訂正機能といいます。誤り訂正の割合が高ければ高いほど、１つのQRコード内に収めるデータ量が少なくなりますが、過酷な環境下であってもQRコードが利用できるとおもえば素晴らしい機能ですね。

 ___車検証で使われているQRコードについてはMまたはQとの記載があり、およそ１５％〜２５％の誤り訂正機能があります。___

# 分割QRコードについて
「分割QRコード」や「連結QRコード」という文言で記載されているようです。１つのQRコードに入り切らないデータ量の場合、分割することができます。分割したQRコードを連結して１つの文字列にして利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84965/c1975e3d-12fd-2187-3ee5-8bd4e0893498.png)


 - QRコードのヘッダーの0バイト目左4bitが「3」であれば分割QRコード
 - バイナリデータを取得してヘッダ（最初の部分）を取得する必要がある
 - Nが分割QRコード内の位置（0開始の連番）
 - Tは分割QRコードの総数（4bitのため分割QRコードは最大16までとなる）
 - パリティ1+パリティ2はQRコードのIDとなるため、パリティ1+パリティ2が同一となる分割QRコードを取得して連結する必要がある。(最大２５６）

基本的な分割QRコードの読み取り手順としては、以下です。
　1.　QRコードのヘッダ部分を読み込む
　1.　最初の4Bitを取得し３かどうかを判定する
　1.　パリティ１＋パリティ２、分割数を読み込んで同一かどうか判定する
　1.　同一であることがわかればデータを貯めておき、結合する



## Androidで分割QRコードリーダー実装
Androidでは、QRコード実装といえば、MLKitが有名です。通常のQRコードを読み込むにはMLKitで十分ですが、ヘッダー情報を読み取ることができません。
そこでAndroid以外でも有名なQRコードライブラリでもあるZXing（zebra crossing）ライブラリを利用します。
https://github.com/zxing/zxing

QRコードをバイト配列として取得し、最初の１バイトを取得します。
１バイトを１６進数に変換すると２つの配列になるので、１つ目に３が入っていれば分割QRコードであることがわかります。

```xzing.kt
rawQrcode = result.getRawBytes(); // ByteArray
startByte = rawQrcode[0]; // 最初の１Byte 
hexDec = startByte.toString(radix:16); // １６進数に変換する。1Byteなので１６進数２つ（配列）で取得
hexDec[0] // 最初の　4bit
hexDec[1] // 次の4bit
```

## iOSで分割QRコードリーダー実装
iOSでは、Vision.frameworkを利用します。AndroidのMLKitと似ています。Vision.frameworkではヘッダー情報が取得できます。errorCorrectedPayloadにて取得できます。


 - errorCorrectedPayloadでbyte codeを取得
 - payloadStringValueは、ヘッダーは取得できない。中身のデータを取得する


``` qr.swift
       var qrcodeInfo = QRCodeInfo()

        let dataByteArray: [Byte] = [Byte](qrcodeData)
        if dataByteArray.count >= 2 {
            let dataByte1 = dataByteArray[0].toHexString()
            let splitCode = dataByte1.first // ここが最初の4bit
```
自分のMacの環境（2023年末編）


# はじめに

この記事は、Qiita Advent Calendar 12日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9

# 筆者について

- 現在高校２年生
- 水泳部マネージャー
- 生徒会長
- とある団体の代表

# 本編

本日は僕が普段から利用している環境を紹介したいと思います。（ちなみに、言語は英語に設定しています。）

## まずスクショ

![Screenshot 2023-12-12 at 17.01.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/db6c65ff-f3b2-70e3-2658-5c68e9d79844.png)

## Browser編

### （一番使う）Arc Browser

数日前にも紹介したArc Browserですね！ぜひみんさん記事も含めてご覧ください。

![Screenshot 2023-12-12 at 17.09.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/3b74bda8-40e8-9d43-4e34-8733a60fd2cb.png)

https://qiita.com/0_terarin_0/items/261f5c8df9b7e50ad19d

### （まあまあ使う）Firefox

僕自身がLinuxのArm版をまあまあ使うのですが、それでいてChromeは対応してない（Chromiumのみ）なので、FIrefoxを利用しています。（個人的にMozillaにも頑張って欲しい）

（Macの画面）

![Screenshot 2023-12-12 at 17.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/77203e7e-9797-9bfb-6c10-f720c16b07b3.png)

（Debianの画面）

![Screenshot 2023-12-12 at 17.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/9bfc1e76-114b-fa8d-89c1-2c732e36dae7.png)

### （Dartの検証用に使う）Chromium

Dartの検証にはChromiumを利用します。

（Macの画面）

![Screenshot 2023-12-12 at 17.22.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/d2c0c921-1e71-6179-2828-5a6c1d9405b6.png)

（Linuxの画面）

![Screenshot 2023-12-12 at 17.21.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/8a79710a-3bd5-1fcd-1057-4af6e6f7277a.png)

## オフィス系

### Microsoft Office ファミリー

![Screenshot 2023-12-12 at 17.30.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/fd1a7829-3350-4471-37e0-d454e4525f5d.png)

### Google Workspace

![Screenshot 2023-12-12 at 17.31.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/e49b1392-76a8-755f-9320-0d134ccfeca8.png)

## その他

##  Thunrderbird (メーラー)

メールが載せれないのでリンクを掲載します。

https://www.thunderbird.net/ja/

（これは完全にMozillaに頑張って欲しいという思いから利用していました。）

### Visual Studio Code

もちろん利用しています。

https://code.visualstudio.com/

### Aractiroty

![Screenshot 2023-12-12 at 17.33.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/176c9c0e-4b0a-b0cd-c427-f02d3c7c58ee.png)

以下、```~/.zshrc```の記述設定

```zsh

PROMPT="%F{green}%n%f%F{cyan}($(arch))%f:%F{blue}%c"$"%# "%f

```

# 最後に

今回は軽く自分の周りの環境を整理してみました。来年にはどれぐらいに変わっているのでしょうか、楽しみです。それでは、引き続き今後のアドカレ 23 の記事をお楽しみにしてください。

https://qiita.com/0_terarin_0/items/0f367210e2465f7772c9
Gameのパラメータ管理（ScriptableObjectを使用する)

UnityにはComponentsという概念があるが、そこにパラメーターを書いていくとデバッグや難易度調整する時に不便なことがある。ゲームオブジェクトが少ない場合は対応できるが、数が増えてくるとどこになんのパラメータの設定があるのかわからなくなる。

難易度調整する時は数値を一覧で管理して、それを調整しながら遊んでいく方が効率的だ。

## ScriptableObjectを使ってパラメータを管理とは。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/b2a50cf5-720f-7ba3-55a4-3af2fdd92a8f.png)
やりたいことはGameを動かしながらこんなかんじでパラメータをいじることができるようになること。

また、通常Unityは実行中のComponentsの値変更は停止した時に元に戻るが、このScriptableObjectでは値を保持するので便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/93128511-b8c9-82b4-ea81-7769222dc5c8.png)
また値もテキストデータとして管理されているのでさらに便利。

## 元になるCSファイルを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/ff9c90d3-3bdf-6646-5e33-eb98d6bcac3f.png)
場所はどこでも良いが、適当なスクリプトを作成する。

```
    [CreateAssetMenu(fileName = "TitleScene_PM", menuName = "TitleScene_PM")]
    public class TitleScene_PM : ScriptableObject
    {
        public int test; //好きなパラメータを設定する。
    }
```
CreateAssetMenuでUnityの右クリックメニューに追加し、ScriptableObjectの継承するのがきも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/176cea8e-5f5e-6389-e488-d55bf916bab0.png)
そうするとUnityの右クリック＞Create＞設定した名前（TitleScene_PM)が追加される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/e817caf8-81ca-5259-2ffc-5efa6ea14ac1.png)
Resourcesフォルダに追加する。

```
        private TitleScene_PM titleScene_PM;
        private void Start()
        {
            //パラメータクラスを読み込む
            TitleScene_PM = Resources.Load<GameSceneParameter>("TitleScene_PM");
            //パラメータを使用する
            TitleScene_PM.test
        }
```
これで準備は完了。
あとはResoucesからクラスを読み込み使用する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/67bb8fe7-3620-6dae-5771-4e8fcd20d6e2.png)
パラメータクラスはクラスや構造体でまとめるとわかりやすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/04742a79-a59d-fdf2-c2ac-00c0916042f1.png)
```
        [Range(0, 5)]
        public int Sampcount;
```
Unityではincpector情報を数字以外でコントロールする方法もある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/ddac9ac6-3b7c-2e46-05d6-62522e2f276d.png)
こんな感じで線形でコントロールもできる。
OpenSiv3D for ゲーム以外のいろいろ！（ファイル操作編）

# Siv3Dをもっと身近に！？

最近、ゲームやアプリ開発のためのオープンソースフレームワークとして名をはせているOpenSiv3Dですが、このフレームワークに含まれている機能で非常に便利なものがいくつもあるのでその中からファイル操作関連の機能をピックアップしました！

ゲームに関する機能やコードの紹介はしないので、そちらを探している方は、私以外の方々の素晴らしい記事をご覧ください

# ファイル操作


## テキストファイル

C++のファイル操作がわからない人はいませんか？
それならSiv3Dを使ってやってみましょう！

```c++
#include <Siv3D.hpp>

void Main()
{
  TextReader tr {U"example/txt/en.txt"};

  if (not tr)
  {
    throw Error {U"en.txtを開くことに失敗しました"};
  }

  const String txt = tr.readAll();

  TextWriter tw {U"example/txt/w_en.txt"};

  if (not tw)
  {
    throw Error {U"w_en.txtを作ることに失敗しました"};
  }

  tw << txt << U"こうやって追加できる";
}
```

このようにしてファイルを操作することができます。直感的に書くことができるのは非常にありがたいことですね。

## 設定ファイル

個人的に最もありがたい機能の一つです。
C++でCSVファイルやJSONファイル、INIファイルを読み書きしたり、tomlファイルやXMLファイルを読み出したいことあります。

例として次のようなCSVファイルの読み書きをしてみましょう。

```fruits.csv
fruit, price
apple, 100
orange, 70
strawberry, 200
banana, 80
```

ではこれを値段が安い順に並べ替えてみましょう。

Siv3Dを使うと次のように書けます。

```cpp
#include <tuple>     // いらないかもしれない
#include <algorithm> // いらないかもしれない
#include <Siv3D.hpp>

void Main()
{
// CSVファイルを開く
  const CSV scv_reader {U"fruits.csv"};

  if (not csv_reader)
  {
    throw Error {U"fruits.csvを開けませんでした"};
  }

// CSVファイルの中身の取り出し
  Array<std::pair<int, String>> fruits;

  for(size_t i = 1; i < csv_reader.size(); i++)
  {
    fruits[i].second = csv_reader[i][0];
    fruits[i].first = Parse<int>(csv_reader[i][1]);
  }

// ソート
  std::sort(fruits.begin(), fruits.end());

// CSVファイルの書き込み
  CSV csv_writer;

  csv_writer.writeRow(U"fruit". U"price");

  for(const auto& fruit : fruits)
  {
    csv_writer.writeRow(fruit.second, fruit.first);
  }

  csv_writer.save(U"sorted_fruits.csv");
}
```

結果は次のようになります。

```sorted_fruits.csv
fruit, price
srawberry, 200
apple, 100
banana, 80
orange, 70
```

こんな簡単にデータが扱えます。
似たような感じでJSONファイルやINIファイルも扱えるので公式のリファレンスをぜひともチェックしてみてください。

公式リファレンス：

https://zenn.dev/reputeless/books/siv3d-documentation/viewer/tutorial-configfile

>ちなみにこれをSiv3Dを使わずに書くと`ifstream`でファイル読み込んで、自分でCSVファイルをパースして、`oftream`書き出してという手順となります。圧倒的に楽になっていることがこれで伝わるでしょうか？

## バイナリファイル

こちらも便利に扱えるようにはなっています。今回こちらでは紹介しませんが、こちらもぜひ活用してみてください！
大体リファレンスに書いてあります。

https://zenn.dev/reputeless/books/siv3d-documentation/viewer/tutorial-binaryfile
【Unity初歩】~Physicsを使った当たり判定~

# はじめに
前回、敵を増殖できたので、この敵への当たり判定とゴールオブジェクトの当たり判定をPhysicsを使って実装してみたいと思います。

前回の記事

https://qiita.com/usomaru/items/5b933fa5f6e3c608472c

# Physicsの当たり判定の種類
2種類あります。

Collisionモード…衝突モード。オブジェクトが当たった場合と、跳ね返りの衝突も検知される。ので、オブジェクト同士が当たると跳ね返る。

|状態|メソッド|
|--|--|
|当たった瞬間|OnCollisionEnter2D|
|当たってる間|OnCollisionStay2D|
|当たり終わった瞬間|OnCollisionExit2D|

Triggerモード…すり抜けモード。オブジェクトが当たった場合のみ検知される。跳ね返りは検知されないのでオブジェクト同士が当たってもすり抜ける感じになる。

|状態|メソッド|
|--|--|
|当たった瞬間|OnTriggerEnter2D|
|当たってる間|OnTriggerStay2D|
|当たり終わった瞬間|OnTriggerExit2D|

# 敵に当たり判定をつける
Physicsを使うため、敵(🦐)のPrefabにCircle Collider 2Dコンポーネントをアタッチします。
重力もつけたいので、Rigidbodyもアタッチします。
※本当は増殖させる前に原本で当たり判定作っておくのが良かったかも。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/8d3a59dc-a63c-f2e8-793f-30b53941e33c.png)




敵(🦐)のPrefabを以下のように書き換えます。

```C#
public class EnemyController : MonoBehaviour
{
    Rigidbody2D rigidbody2;
    float walkForce = 30.0f;
    float maxWalkSpeed = 2.0f;
    bool isTouch = false;

    void Start()
    {
        this.rigidbody2 = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        // 画面外まで下に落ちたら消える
        if (transform.position.y < -5)
        {
            Destroy(gameObject);
        }

        // 地面に落ちたら左移動
        if (this.isTouch)
        {
            // 速度
            float speed = Mathf.Abs(this.rigidbody2.velocity.x);
            // 左横移動
            if (speed < this.maxWalkSpeed)
            {
                this.rigidbody2.AddForce(transform.right * -1 * this.walkForce);
            }
        }
    }

    // 
    void OnCollisionEnter2D(Collision2D collision)
    {    
        if (collision.gameObject.name == "Kani")
        {
            Debug.Log("ゲームオーバー");
        } else
        {
            this.isTouch = true;
        }
    }
```

🦀に当たるとゲームオーバーに(ここでは一旦コンソール表示)、地面に着地した場合はそのまま左に移動して落ちていくようにしました。
左横に移動する処理は以前Physicsを使った横移動で🦀にかいたスクリプトと同じ内容です。

# ゴールを追加して当たり判定をつける

ゴールオブジェクトを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/8a13f6c1-399c-2731-93ad-2f224727122d.png)

追加したゴールオブジェクトにBox Collider 2Dコンポーネントをアタッチします。
追加したら、Box Collier 2Dの「Is Trigger」にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/78bf3ffe-4187-6208-e012-b0a7af983da0.png)

チェックをいれると、すり抜けモードとなり、下のスクリプトで登場するOnTriggerEnter2Dメソッドが使えるようになります。

```c#
private void OnTriggerEnter2D(Collider2D collision)
{
    Debug.Log("ゴール");
}
```

# おわりに
このゲームの完成も近づいてきた感じがします。
次回、ゴールをするとクリアシーンに遷移するようにしたいと思います。
1on1から得た学び



今回のテーマは定期的に行われるけどルーティン化されがちな1on1について、自分のアクションや意識をどう変えたかについて執筆しました！

自分の経験が、誰かの役に立つかはわかりませんが、きっかけ作りの一端を担えればと思いますので、興味がある方はぜひご一読お願いします🙇‍♀️


## 1on1について今までどのように考えていたか

皆さんは1on1を上司とするにあたり、どんなことを意識してますか？

僕は、今まで1on1を以下のような場だと思い、望んできました。

- **分かんないこと/困っていることを相談する場**

普段のデイリーは、全体会議のため時間の都合上細かすぎる内容については聞くことができないため、1on1という場で詳細なことを聞くことで情報の補完を行うものだと思っていました。

また、自分がその際困ったことなどを共有することで、上長はそれに対して何かしらのアドバイスをくれるという認識で、**受け身の姿勢**であったと思います。

これは1on1に限った話ではなく通常の会議にも言えることですが、ファシリがいるとどうしてもその人任せで主導してもらうことが多くなり、受け身でいる事が多い気がします…（もしかすると、日本人特有のものかも？）

招待された参加者気分であったのが今までの僕です。

## 1on1を意識するようになったきっかけ

1on1を4~5回こなしたくらいから、ふと振り返ったときあることに気づきました。それは相手に題材を用意してもらってそれをもとに、質問をされることで回答をしていくという**一方通行のコミュニケーションがなされている**という事。つまり、受け身の姿勢であるという事実をここで初めて理解しました。

きっかけは些細な事で、過去の1on1の内容をまとめた議事録を読み返したから得られた気づきでした。内容を見ていると、質問された内容についてただ回答しているだけで、学校の授業となんら変わらない受動的なスタイルが1on1では起きていました。

このままの状態では、自己成長できるはずがないと思い、改めて1on1について考える事にしました。

## そもそも1on1って

自分にとっての1on1とは何かを考えた時、「**成長機会を得る場であると同時に自分にない視野・視点・視座からの気づきを得る場**」であると思いました。

上長だからこそ見える視点、自分だからこそ見える視点、それぞれの視点を共有する事で、自分にはない視点に気づく事ができる。その視点を得ることで、別のアプローチを試せるようになったり、問題解決への糸口を掴む事ができるのかなと思います。

また、成長機会を得る場であるという意識は結果として、自発性を促進する効果もあると考え、これらの気づきを得る事が自分にとっての1on1の定義かなと思いました。

これらを念頭に、具体的に1on1をする際にどんなことを意識するようになったのかについてお話ししていきます。

## 1on1で意識するようになったこと

1on1の意義を再確認し、以下のようなアクションを試すようになりました。

### 1.自分が気付かない視点からのアドバイスをもらう

自分からの視点だと、物事の一部しか見る事ができず、その部分以外を見る事ができません。

![スクリーンショット 2023-11-29 12.58.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2597943/645343e6-0bdf-ae31-6e3d-2eb5ed6d41e0.png)


そのため、1on1では2週間の振り返りとして以下のような形でフィードバックを取りに行くようにしています。

下記は実際に使っているテンプレートです。

```
💡 <先週の振り返り>

- 先週、先々週で、行動で何かまずいところや要改善ポイントはあった(見つかった)か

[自分視点]

- 〇〇について、〇〇のようなアクションをとれば、工数を削減できた。

[リーダー視点]

- 〇〇のタスクについては、こういうアクションをとることもできたのではないか。
```

### 2.成長機会の場という意識

認識を改めたことで、1on1は**自己の成長機会の場**であると考えられるようになりました。事前にアジェンダをまとめて情報を提供することで、今の自分に必要なアドバイスを得る事ができ、30分という短い時間でも濃密な時間を過ごす事ができています。また、それを元に質問を受ける事で、自分の思考の癖なども知る事ができ、自分を知る機会にもなっていたりします。

### 3.「1on1という場」を一緒に作っていく意識

2と関連してるのですが、自己の成長の場であるという意識を持つことは受身の姿勢がなくなり、自然と前のめりになるため、「**1on1という場をどういう場にしたいか？**」を考えるようになりました。会議などでもそうですが、自発性がないとどうしても聞き手に回りがちだと思うので、「成長機会を得る」という意識は副作用として、色々な面で役に立つなと改めて思いました。

## 意識したことで、どのような効果があったか

効果としては、主に２つあります。

- **自分の行動を省みるきっかけを作ることができた**
- **他の人の経験や知識から、自分の視野を広げる事ができた**

### **自分の行動を省みるきっかけを作ることができた**

業務をこなしていると自分の行動を省みるタイミングって中々作りづらかったのですが、1on1のタイミングで、その機会を作る事ができたので、結果として業務中でも「これは1on1で相談したい案件だな〜」みたいな成長機会を得るための意識が以前よりも働くようになりました。

### **他の人の経験や知識から、自分の視野を広げる事ができ、複数の視点も持てるようになった**

他の人の視点から得た学びを自分の視点に活かす事ができ、結果として視野を広げて物事を判断できるようになっていると思います。例えば、今までは自分の視点頼りの発想も別のアプローチを試みることもできるようになり、幅が広がった気がします。

## 1on1を通して感じた大事なこと

これは個人の主観になりますが、やはり**自発性**が大事だなと思いました。ただ、今回のように**そもそも自分が受け身である**ということに気づけないと、自発的に何かをやるといった行為は難しいと思うので、自発性と同じくらい**自分の行動を省みる事**が大事であるなとも思いました。
【zoxide】”いつもの場所に”ぴょんぴょん飛び回る

/darallium/です！ご覧いただきありがとうございます． 😊

「CLI初心者でも感動するような，それでいて汎用性・拡張性の高いCLIツール」を紹介する7日間の5日目の記事です 🙇

本日は「シェルにもショートカットを」をテーマに，zoxideを紹介します:relaxed:

# zoxide
![https://github.com/ajeetdsouza/zoxide/raw/main/contrib/tutorial.webp](https://github.com/ajeetdsouza/zoxide/raw/main/contrib/tutorial.webp)
公式より引用

zoxideは普段よくアクセスするサイトをブックマーク化して，ビュンビュン飛び回るためのツールである．古いユーザはautojumpやzと言えばわかるだろう．

## installation

### dependencies

- cargo / rust
- fzf 
#### optional
- tmux
- nvim
    - telescope.nvim
- zsh-autocomplete


## windows

```shell
$ winget install ajeetdsouza.zoxide
```

## linux

```shell
$ apt install zoxide
$ echo 'eval "$(zoxide init bash --hook prompt )"' >> ~/.bashrc
```

## macOS

```shell
$ brew install zoxide
$ echo 'eval "$(zoxide init zsh --hook prompt )"' >> ~/.zshrc
```

# チュートリアル


```shell
$ zoxide add <anywhere what you often access> 
```
まずは，`z <what you want to go>`でカレントディレクトリを飛び回ってcacheを貯めよう．`z add <where you want to go>`でキャッシュを貯めることもできる．


```shell
$ zi
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196553/808ac2ed-f063-beb2-4431-0a6dbceff4a1.png)

`zi`コマンドで，溜まったキャッシュを表示することができる．左の数字がアクセスした回数， 右がパスだ．移動した回数が多いほど下に表示される仕組みになっている．


## 設定
zoxideは設定ファイルは存在せず，`zoxide init`する前の環境変数によって設定が変化する．.bashrcやらのinitよりも前に環境変数に値を割り当てて設定を変更しよう．注意をしなければならないのが，`zoxide init`しなおさなければならないため，`source ~/.bashrc` をする必要があることだ．

- _ZO_DATA_DIR: zoxideのキャッシュ先を指定できる．デフォルトではwindowsだと`%LOCALAPPDATA%`，macOSだと`$HOME/Library/Application Support`，linuxだと`$HOME/.local/share`である．RAM diskを使用する際は使うといいだろう．
- _ZO_EXCLUDE_DIRS: キャッシュを除外する📁フォルダを指定できる．/tmpとかはあまり行くことはないが除外するのもありだろう． 
- _ZO_FZF_OPTS: fzfに渡すコマンドオプションを指定できる．
- _ZO_MANAGE:  キャッシュするフォルダの最大数を指定できる．あまりお勧めはしない．
- _ZO_RESOLVE_SYMLINKS: リンクを飛ぶ際，そのリンクではなくリンク先のパスをキャッシュする．

また，部分的にはzoxide initにコマンドライン引数を与えることで設定できるコマンドがあり，

- \-\-no-cmd: zとziをエイリアスを張るのを防ぐ．
- \-\-hook <prompt/pwd/none>: ziで飛ぶとき，キャッシュを自動で<プロンプト毎にする/ディレクトリが動く毎にする/しない>
- \-\-cmd: zとziを変更する．POSIXとNushell以外では，cdを置き換えると違和感なく使えるかもしれない．

また，initするとき，実はいくつかのfunctionが定義されている．これらをbashrcなどにべた書きして改変することで，さらなる拡張が望まれる．筆者の好きなhatredholderさんの設定がreferencing[2]に掲載しているのでぜひ見てほしい．


# あとがき
とりあえずワークスペースに飛んで，pullして，ふぅ作業をしよう．この前半の部分を簡単にしてくれるのがzoxideだ．また，設定どこだっけ？というのを解決してくれるものでもある．いつもやることはスクリプトに書き出すか，このような拡張ソフトウェアを導入することで自動化してしまおう．

# references

https://github.com/ajeetdsouza/zoxide#configuration

https://github.com/hatredholder/.dotfiles/blob/main/zsh/.zshrc#L90
最速のブリッジネットワーク設定on lima

# 環境
Intel版mac macOS Sonoma 14.1
lima 0.19.0
lima上のOSはLinuxのRocky-9

# やろうとしたこと
lima上で簡単なサーバーを作ったので、外部（他のPC）からアクセスできるようにしたい。

ホストPCからアクセスできることはlocalhostで確認済み。
後はネットワークを外に公開してあげれば良い。

# 詰まった箇所
limaの更新が結構早く、古い記事を見てしまったのが原因。
vde_vmnetは一応サポートされていると書いてありましたが、動かなかったです。
無駄なことをしてしまった。
結局[公式](https://lima-vm.io/docs/config/network/)最強ですね。

# 最終的な解決策
設定ファイルをいじって解決したんですけど、もう一度作り直した時に爆速でできたのでそっちを使ってください。
limaのVMを作る時に`--network=vzNAT`をつけるだけです。
例えばテンプレートから作る時は、以下のような感じ。

> limactl start template://hogehoge --vm-type=vz --network=vzNAT
ROS 2においてC++で作成したノードをlaunchファイルで起動する方法

# はじめに
　今回の記事では、ROS 2において、launchファイルを用いて複数のノードを起動する方法について記載していきます。ROSの際はlaunchファイルをxml形式で記述してきましたが、ROS 2ではpython、xml、yamlで記述する方法が提供されています。今回の記事ではこの3つの記述方法の内、pythonでのやり方について記載していきます。

:::note info
この記事は[ROSに関する投稿](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d)の一部です。
目次は[こちら](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d#%E7%9B%AE%E6%AC%A1)
:::

### 前提条件
　今回の記事は、以下の環境で動かすことを前提に記載しています。
|            |     条件     |
|:-----------|:-------------|
| OS         | Ubuntu 22.04 |
| ROS        | ROS 2 humble |

# 準備
### launchファイルを格納するディレクトリ作成
　ROSの時と同様、以下のコマンドでパッケージ内にlaunchディレクトリを作成します。今回の例では、[前回の記事](https://qiita.com/kccs_kazushi-uchida/items/70bb07e688953cf01e82)で作成したpub_sub_cpp_01パッケージ内にlaunchディレクトリを作成しています。
``` shell
cd ~/ros2_ws/src/pub_sub_cpp_01/
mkdir launch
```

### package.xmlの編集
　~/ros2_ws/src/pub_sub_cpp_01/package.xml の</exec_depend>を記述している場所に以下を追記します。
``` xml:~/ros2_ws/src/pub_sub_cpp_01/package.xml
<exec_depend>ros2launch</exec_depend>
```

### CMakeLists.txtの編集
　~/ros2_ws/src/pub_sub_cpp_01/CMakeLists.txtに以下を追記します。追記しなくても実行できますが、launchファイルを配置したディレクトリ以外でros2 launch コマンドを実行すると、launchファイルを見つけられないので、追記を推奨します。
``` cmake:~/ros2_ws/src/pub_sub_cpp_01/CMakeLists.txt
install(DIRECTORY launch
  DESTINATION share/${PROJECT_NAME})
```

### launchファイルの作成
　以下のファイルを~/ros2_ws/src/pub_sub_cpp_01/launch に配置します。今回ファイル名は、pub_sub_cpp_01_launch.pyとしています。6~15行目に記述しているように、Node()を追記することで起動するノードを追加することができます。また、今回の例では、パッケージ名、名前空間、実行ファイル名のみを記載していますが、remappingsを使用することで、トピックの再マッピングも可能です。名前空間については、同じノードを複数起動したい場合にnamespaceにそれぞれ異なる名前を設定する事で、同じノードを区別して実行することが可能になります。
``` python:~/ros2_ws/src/pub_sub_cpp_01/launch/pub_sub_cpp_01_launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='pub_sub_cpp_01',
            namespace='kccs_pub_sub_cpp_01',
            executable='publisher'
        ),
        Node(
            package='pub_sub_cpp_01',
            namespace='kccs_pub_sub_cpp_01',
            executable='subscriber'
        )
    ])
```

### ビルド
　以下のコマンドでビルドします。ビルドしなくとも直接launchディレクトリに移動して、ros2 launch pub_sub_cpp_01_launch.py とコマンドを打てば実行可能です。
``` shell
cd ~/ros2_ws
colcon build
```

# 実行
　以下のどちらかのコマンドを実行します。
``` shell
cd ros2_ws/src/pub_sub_cpp_01/launch
ros2 launch pub_sub_cpp_01_launch.py
```
``` shell
ros2 launch pub_sub_cpp_01 pub_sub_cpp_01_launch.py
```

# 実行結果
![Screenshot from 2023-11-15 16-33-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3635173/57fa8412-759e-759a-dcd5-b6f1958bb22d.png)

# おわりに
　今回の記事では、ROS 2でのlaunchファイルの書き方について記載しました。次回の記事では、今回の内容からは少し逸れますが、ament_cmake_autoについて記載する予定です。ament_cmake_autoを使用しなくともビルドは可能ですが、使用した方がビルド設定を比較的楽に記述できますので、興味がある方は是非ご覧ください。
ghqを使ったリポジトリ移動を高速化する

fishを使っており、[decors/fish-ghq](https://github.com/decors/fish-ghq) をinstallしてリポジトリ移動をしていました。
ただ使っていて重いなあと感じていたので、下記の関数を使うようにして高速化しました。
``Ctrl+g``で呼び出す想定です。

```shell
function peco_select_ghq_repository
  set -l query (commandline)

  if test -n $query
    set peco_flags --query "$query"
  end

  find $(ghq root)/github.com/*/* -type d -prune | sed -e 's#'$(ghq root)'/##' | peco $peco_flags | read line

  if [ $line ]
    cd $(ghq root)/$line
    commandline -f repaint
  end
end

bind \cg peco_select_ghq_repository

```

参考: [ghq + pecoが重くなったら](https://qiita.com/miyaoka/items/0493655418f4920efcb7)
ExcelDNAで、async/awaitを利用する

情報が分散しているので、ExcelDNAで非同期処理の関数を動かすのに時間がかかりました。

[ExcelDNA](https://excel-dna.net/)の非同期関数のサンプルは、
[AsyncFunctionExamples.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/AsyncFunctionExamples.cs)
にあります。

### プロジェクトに追加
- `nuget`で、`ExcelDna.Registration`を追加して下さい。

- `<PropertyGroup>`に次を登録します。

```xml
<ExcelAddInExplicitRegistration>true</ExcelAddInExplicitRegistration>
```
### コピーするファイル
次に列記したファイルを、プロジェクトにコピーします。
ただし、どこまで必要なコードか詳しく分析していないので、不要な部分も含むと思います。

- [ExampleAddIn.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/ExampleAddIn.cs)
このファイルのうち次の部分は、コメントアウトで良いです。
```csharp
InstanceMemberRegistration.TestInstanceRegistration();
```

次の部分で、C#のメソッドをExcel関数として登録していくと思われます。
```csharp
public void AutoOpen()
{
  ExcelRegistration.GetExcelFunctions()
    .ProcessMapArrayFunctions(conversionConfig)
    .ProcessParameterConversions(conversionConfig)
    .ProcessAsyncRegistrations(nativeAsyncIfAvailable: false)
    .ProcessParameterConversions(postAsyncReturnConfig)
    .ProcessParamsRegistrations()
    .ProcessFunctionExecutionHandlers(functionHandlerConfig)
    .RegisterFunctions();
```

- [CacheFunctionExecutionHandler.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/CacheFunctionExecutionHandler.cs)
- [FunctionLoggingHandler.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/FunctionLoggingHandler.cs)
- [ParameterConversionExamples.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/ParameterConversionExamples.cs)
- [TimingFunctionExecutionHandler.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/TimingFunctionExecutionHandler.cs)
ここまで、namespaceは適宜変更して下さい。

- [SuppressInDialogHandler.cs](https://github.com/Excel-DNA/Samples/blob/master/Registration.Sample/SuppressInDialogHandler.cs)　このファイルのnamespaceは、`ExcelDna.Registration`のままで良いです。

### 関数
次のように、Excelの関数にするメソッドに、`[ExcelAsyncFunction]`をつけます。
```csharp
[ExcelAsyncFunction]
public static async Task<string> dnaDelayedTaskHello(string name, int msDelay)
{
     await Task.Delay(msDelay);
     return "Hello " + name;
}
```

### 確認環境
.NET 6
ROS 2におけるワークスペース・パッケージの作成とビルド

# はじめに
　今回の記事では、ROS 2でのワークスペース・パッケージの作成方法とビルド方法について記載します。ROSとROS 2では少し異なる部分がありますので、その点も踏まえて記載します。

:::note info
この記事は[ROSに関する投稿](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d)の一部です。
目次は[こちら](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d#%E7%9B%AE%E6%AC%A1)
:::

### 前提条件
　今回の記事は、以下の環境で動かすことを前提に記載しています。
|            |     条件     |
|:-----------|:-------------|
| OS         | Ubuntu 22.04 |
| ROS        | ROS 2 humble |

# ワークスペースの作成
　ワークスペースの作成は、以下のコマンドで実行します。ここに関してはROSの時と同じで、mkdirコマンドでディレクトリを作成するだけになります。既に、[こちらの記事](https://qiita.com/kccs_yoshiteru-imamura/items/2ff8d1f56e26d781afe4#%E9%96%8B%E7%99%BA%E7%94%A8%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E4%BD%9C%E6%88%90)のコマンドを実行している場合は、ワークスペースが作成済みのため不要です。
``` shell
mkdir -p ~/ros2_ws/src
```

# パッケージの作成
　パッケージの作成については、ROSとROS 2で少々コマンドが異なります。ROS 2では、以下に記すコマンドの様に、C++用のパッケージとpython用のパッケージで異なるオプションを使用して作成する必要があります。

### C++パッケージ作成コマンド
``` shell
cd ~/ros2_ws/src/
ros2 pkg create --build-type ament_cmake パッケージ名
```

### Pythonパッケージ作成コマンド
``` shell
cd ~/ros2_ws/src/
ros2 pkg create --build-type ament_python パッケージ名
```

# ビルド
　ビルドについても、ROSとROS 2で異なります。ROSではcatkin_makeやcatkin buildなどを使用しましたが、ROS 2では以下の様にcolconを使用します。
``` shell
cd ~/ros2_ws/
colcon build
```
　このcolconコマンドについて、良く使用するオプションとして以下の様なものがあります。また、この他にも様々なオプションがありますが、詳細は以下のリンクを参考にしてください。

### シンボリックリンクを使用してインストール
``` shell
--symlink-install
```
### 指定したパッケージをビルド
``` shell
--packages-select パッケージ名
```

https://colcon.readthedocs.io/en/released/reference/verb/build.html#cmake-specific-arguments

https://colcon.readthedocs.io/en/released/reference/package-selection-arguments.html

# おわりに
　今回は、ROS 2でのパッケージの作成方法とビルド方法について記載しました。この時点では、まだROS 2でのコーディングについて触れられていませんが、次回の記事ではコーディング部分について記載する予定です。具体的にはコンポーネントを用いたPub&Sub通信について記載する予定ですので、興味がある方は是非ご覧ください。

# 参考資料
https://docs.ros.org/en/foxy/Tutorials/Beginner-Client-Libraries/Creating-Your-First-ROS2-Package.html
'Cannot find module react\jsx-runtime Did you mean to import react\jsx-runtime.js?'がReact V17で発生したら、、

## 問題
自作したReact Componentを含むnpmライブラリを、NextJsプロジェクトで`install`、`next build`したところ、`Cannot find module 'project\node_modules\react\jsx-runtime' imported from project\node_modules\my-library\my-component Did you mean to import react/jsx-runtime.js?`というエラーが発生しました。

[Stack Overflow](https://stackoverflow.com/a/73005867/19622195)などでも取り上げられており、ライブラリとプロジェクト間のVersion差異で、簡単に解決できるかなぁと思ったところで見事沼にはまりました。

まず、試したのは以下です。
`React`を最新Ver18に上げるという手段はプロジェクトへの影響上除外しています。

- `@types/react`を最新Verにあげる

    ライブラリ側も、Nextjsプロジェクト側も全てVersionを揃えてみましたが、改善しませんでした。プロジェクト側で問題なく`@types/react`によるModue resolutionは行えていたので望み薄だったので気にしません。
    
- `node_modules`と`.lock`ファイルを削除し、`install`

    lockファイルを削除するという荒業ですが、やるしかありません。`package.json`の各ライブラリVersionを色々と調整しつつ、やっとの思いで試してみましたが、改善しません。

単純な問題ではないことが分かり、色々と覚悟すると共に、「調子にのってライブラリなんて作るんじゃなかった」などの後悔も当然発生します。手がかりはエラーメッセージのみです。


## 環境

　以下で完全に再現というわけではなく、関連するパッケージのみ上げています。
 ※ちなみに`react:17.0.2`は、[こちら](https://legacy.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)記載の`jsx-runtime`によるJSX解析を行います。

- npmライブラリ
react:17.0.2
typescript:4.4.4

- NextJs Project(上記Packageをインストールする)
react:17.0.2
typescript:4.4.4

## 原因

エラー発生元は、npmライブラリの実ファイル、つまりバンドル後の`JavaScript`から発生しており、この時点で`@types`系の問題ではないことが分かりました。

つまり、本来は`react/jsx-runtime`という名称そのままでインポートされるべきということです。

ここで、npmライブラリを作成したときの知恵が役立ちます。

`parent/child`のような形式で、モジュールインポートを行えるようにするには、`reactライブラリ`の`package.json`に以下のような記載が必要です。パスを明示的に設定する必要があります。

```json:package.json
{
    "name":"react",
    ,
    ,
    "exports": {
        "./jsx-runtime":{
            "import": "xxxx",
            "require": "xxx"
        }
    }
}
```

プロジェクト側の`node_modules/react`の`package.json`を確認してみると、`exports`の記載がありません！

この問題をベースに検索してみると、[同じことを問題にしているIssue](https://github.com/facebook/react/issues/20235)が見つかりました。

一安心です。

## 対策

`react`の`v18`から修正されているようなので、シンプルな解決方法はnpmライブラリもNextJsプロジェクトのどちらも最新Versionに上げるということでしたが、それは色々な兼ね合いでできません。

したがって、npmライブラリ側のバンドルで`jsx-runtime`を含まないよう以下のように変更しました。これにより、`React`がJSX解釈に必要になるので、`Component`ファイルに`import React from 'react'`も行いました。

```json:tsconfig.json
{
  "compilerOptions": {
    ,
    "jsx": "react",
```

## 最後に

NextJsプロジェクトの`tsconfig.json`を見てみると、`"jsx":"preserve"`固定になっていたので、この辺がちゃんと考慮されているようでした。

## 補足

NextJsプロジェクト側で`react/jsx-runtime`と`react/jsx-runtime.js`を紐づけるように解決するという方法もありますが、npmライブラリ導入により、本体プロジェクト側に設定関連の修正を与えたくなかったので、採用しませんでした。
【Flutter】Because every version of flutter from sdk depends on・・・version solving failed.バージョンエラーが出たときにやったこと

Flutterで新しくライブラリを入れてpub getしたときに以下のエラーが出たので、やったことを解説します



```
Because every version of flutter from sdk depends on meta 1.8.0 and riverpod >=2.3.10 <3.0.0-dev.0 depends on meta ^1.9.0, flutter from sdk is incompatible with riverpod >=2.3.10 <3.0.0-dev.0.
And because hooks_riverpod >=2.4.9 <3.0.0-dev.0 depends on riverpod 2.4.9, flutter from sdk is incompatible with hooks_riverpod >=2.4.9 <3.0.0-dev.0.
So, because household depends on both flutter from sdk and hooks_riverpod 2.4.9, version solving failed.
pub get failed
command: "/Users/nakayamatakahito/fvm/versions/3.7.1/bin/cache/dart-sdk/bin/dart __deprecated_pub --directory . get --example"
pub env: {
  "FLUTTER_ROOT": "/Users/nakayamatakahito/fvm/versions/3.7.1",
  "PUB_ENVIRONMENT": "flutter_cli:get",
  "PUB_CACHE": "/Users/nakayamatakahito/.pub-cache",
}
exit code: 1
```


# 原因
ライブラリのバージョンと現在のSDKのバージョンとの互換性がなくてエラーが出てるのが原因っぽい
```
dependencies:
  flutter:
    sdk: flutter
  hooks_riverpod: 2.4.9
```
hooks_riverpodを最新バージョンで入れてたんですが、これが問題のようです




# 解決策
互換性のあるバージョンに変えるためには、まずバージョンを削除した状態でpub getします
```
dependencies:
  flutter:
    sdk: flutter
  hooks_riverpod: 
```

そしてpubspec.lockを見ると、インストール可能なバージョンでインストールされています
```:pubspec.lock
hooks_riverpod:
    dependency: "direct main"
    description:
      name: hooks_riverpod
      sha256: "117edbe7e5cfc02e31a94f97e2acd4581f54bc37fcda9dce1f606f8ac851ba24"
      url: "https://pub.dev"
    source: hosted
    version: "2.3.7"
```
この2.3.7をpubspec.yamlに記述して完了です
プロダクトオーナーは数字を読んで、数字で語る

# はじめに
この記事は [NTTコムウェア Advent Calendar 2023](https://qiita.com/advent-calendar/2023/nttcomware) 19日目の記事です。

NTTコムウェアの三浦です。
私のこれまでのキャリアは、レガシー系のシステム開発が中心でした。そんな私が今の部署への異動をきっかけにスクラム開発に触れ、その中でプロダクトオーナー業務を１年ほど経験しました。
サービスの企画をはじめて経験する中で、自分が苦労したこと・学んだことをこの記事を通して読者の皆様にお伝えできればと思います。

# 読んでほしい人
* スクラム開発をはじめたばかりの人・興味がある人
* プロダクトオーナー初心者（歴１年以内）
* プロダクトバックログアイテム（以下PBI）の優先順位付けがうまくいかない人


# プロダクトオーナーとして実践していること
基本的にスクラムガイドで定義されている役割に沿った業務をこなしていますが、具体的に文字に起こしてみました。
### 定量分析
ここで離脱が多い・ここの数値が予想より伸びていないなど、定量データをもとにユーザの課題とその解決手段の仮説を立てる
### 定性分析
立てた仮説の検証をユーザインタビューを通じて実施。
（インタビュースクリプトの作り方などの話も含めると長くなるので割愛）
### PBIの作成・並び替え（プロダクトの改善）
上述した定量分析・定性分析の結果を受けて、プロダクト価値向上のためPBIの追加・変更・優先順位の見直しを実施
### ステークホルダー調整
現状の課題共有とプロダクトの方向性について共有
（平たく言うと、次に何をやるかの宣言）

### 開発調整
開発チームとのやりとり、デザイナーさんとのやりとりなど

# 悩み
私がうまくいかないと感じていたのは、ステークホルダー調整でした。
分析を通じてこんな声が挙がってる・だから次はこれをやるべきだ…と説明しても承認されず、挙句の果てに別のPBIを着手せざるを得ないという経験が少なくありませんでした。
プロジェクトの中でユーザの生の声を最も聞いてる自負もあったため、自分たちが分析を通して得られた結果がなぜ受け入れてもらえないのか非常に頭を悩ませました。

# 偏っていた視野
なぜステークホルダーを納得させられないのか考えたときに、自分の視野がユーザ側に偏ってることに気づきました。事業会社で働く身である以上、必ずKPIや事業目標という数字があり、その数字にどれだけリーチできるのか？という観点の説明が足りていなかったのです。ユーザの声を一番よく聞いている自分がこのプロダクトを成長させることができる！という自負が、逆に自分の視野を狭めていました。

# 数字で語ってみた
そこでステークホルダー調整をする際に、数字の話もインプットすることにしました。
具体的には以下のような感じです。
* この課題を解決すると、
    * KPI（重要な業績評価の指標）のこの指標値が〇%伸びる見込みです
    * MAU（月１回以上の利用があったユーザの数）が〇%改善する見込みです
    * CVR（購入や申し込みなどに至った割合を示す数値）が〇%改善する見込みです

すると自分たちのPBIの価値を認識してもらい、すべて自分たちの思い通りにプロダクトを成長させることができました！
…という、いかにもありそうなサクセスストーリーにはなりませんでした。。
もちろんKPI達成も大事ですが、ROI（投資対効果）など気にすべき数字は他にもあり、自分たちが思い描いた通りになることは稀でした。
しかしながら、ステークホルダーとの対話内容が以前よりも府に落ちることが多くなりました。これはおそらく、自分がステークホルダーにより近い視野（KPIなどの数字）を持つことができたからだと思います。
逆に言えば、どのようにアプローチすればステークホルダーの承認を得ながらプロダクトを自分の思う方向に成長させることができるのかというヒントをこの経験から学ぶことができたと感じています。

# 学び
まとめると、自分がプロダクトオーナー業務を通じて得た学びは以下です。
* **プロダクトオーナーは数字から課題を読み取り、解決策を言語化することが大事**
* **さらに、解決策を講じることでどうなるのか？を数字に落とし込む力が必要**
* **常に広い視野を持って判断することが大切。偏った視野で判断すると、どこかで歪みが生まれる**

# 終わりに
いかがでしたでしょうか。
慣れてる方にとっては当たり前のことかもしれませんが、実際に業務に取り組むと見失ってしまいがちだなと思ったことを改めて言語化してみました。
プロダクトオーナーは今後も継続予定なので、また機会があれば記事を執筆できればと思います。
結局どっちが速いの？ for vs Stream

## はじめに

こんにちは、[@rs_tukki](https://twitter.com/rs_tukki)です。
これは[Java Advent Calender 2023](https://qiita.com/advent-calendar/2023/java)の18日目の記事です。

## 繰り返し処理と言えば

Javaで繰り返しと言えばいの一番に習うのはfor構文ですが、
Java8からは新たな繰り返しや集約処理の構文として`Stream`がサポートされています。  

https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Stream.html

これは処理の流れを宣言的に記述できる構文で、
たとえば、

```java
for (int i = 1; i <= 5; i++) {
    System.out.println(i);
}
```

といった繰り返し処理は、

```java
Stream.of(1, 2, 3, 4, 5).forEach(System.out::println);
```

といったように関数の繋ぎ合わせで記述することができます。  

…ところで、このfor文とStream文って、どちらが速いんでしょうか。  
感覚的には後から出てきたStreamの方が速そうですが、まずはGPTに相談してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308803/e03d3766-2535-8af6-84c2-5e1a1d28c6fb.png)

基本的にはデータ量が小さいほどfor文の方がパフォーマンスが向上する、とのこと。  
本当にそうなのか、ちょっと検証してみることにします。

## どちらが速いのか

という訳で、書いたコードがこちら。

ちなみにJavaのバージョンは`17.0.4`です。

```java
    public static void main(String[] args) {
        final List<Integer> dataSet = new ArrayList<>();
        for (int i = 1; i <= 100000000; i++) {
            dataSet.add(i);
        }

        System.out.println("開始:for");
        long startTime = System.currentTimeMillis();
        long sumFor = 0;
        for (Integer data : dataSet) {
            if (data % 3 == 0) {
                sumFor += data;
            }
        }
        System.out.println(sumFor);
        long endTime = System.currentTimeMillis();
        System.out.println("終了:for");
        System.out.println("処理時間:" + (endTime - startTime) + "ms");

        System.out.println("===============");

        System.out.println("開始:stream");
        startTime = System.currentTimeMillis();
        final long sumStream = dataSet.parallelStream()
                .filter(entry -> entry % 3 == 0)
                .mapToLong(entry -> entry)
                .sum();
        System.out.println(sumStream);
        endTime = System.currentTimeMillis();
        System.out.println("終了:stream");
        System.out.println("処理時間:" + (endTime - startTime) + "ms");
    }
```

めちゃくちゃ単純ですが、やっていることは

* 1から1億までの数値からなるListを用意し
* List内の3の倍数だけを足し合わせて最後に出力する
* forとStreamでそれぞれ行い実行時間を計測する

というプログラムです。
本当はもう少し大きい数でやりたかったのですが、int型の最大値までデータセットを用意するとOOMになってしまうので断念しました...

## 実行結果

そしてこちらのコードを実行してみると、以下のような結果になりました。

```
開始:for
1666666683333333
終了:for
処理時間:729ms
===============
開始:stream
1666666683333333
終了:stream
処理時間:504ms
```

何回か実行してみましたが、平均してStreamの方が1.4倍前後速くなっています。  
GPTによるとデータ量によってはforの方が速くなるとのことなので、データセットをもう少し減らして再度実行してみると、

**5000万**
```
開始:for
416666658333333
終了:for
処理時間:246ms
===============
開始:stream
416666658333333
終了:stream
処理時間:159ms
```

5000万ではまだStreamが優位でしたが、

**1000万**
```
開始:for
16666668333333
終了:for
処理時間:80ms
===============
開始:stream
16666668333333
終了:stream
処理時間:87ms
```

1000万ではforが逆転しました。
とはいえここまで来るとほぼ差はなさそうなので、コード上でどちらを採用するか迷った場合

* 巨大なデータセットを扱う処理はStream
* データセットがそこまで多くない場合、実際に実行時間を計測して
  * Streamの方が速い場合はStream
  * forの方が速い場合、(数msの差が気にならないなら)可読性で判断

とするのがよさそうです。

## まとめ

今回はforとStreamの実行時間を、実際にコードを書いて比較してみました。  
最終的には**場合による**という何とも言えない結果になりましたが、だからこそ何も考えずこちらと決めつけるのではなく、都度そのコードに対してどちらで書くのがよいかを考えるようにしてきましょう。
AVR ISP Shieldを使ってみた

今回は、AVR ISP Shieldを使用して、
ATmega328Pに書き込みをしたのでその記録を書いていきます！

## ハードウェア
1、AVR ISP Shield
https://www.amazon.co.jp/dp/B07HLMMJJM
2、Arduino uno
3、ATmega328P

## 手順
1、Arduino unoにスケッチの例でArduinoISPを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/9f527ea4-7ab2-0b2c-e487-aad2126bc971.png)

2、ボード「Arduino Uno」を選択し、書き込み装置「Arduino as ISP」を選択して、
ArduinoUnoに書き込み。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/f898cc28-81b0-e3d5-0600-96e75576e751.png)

3、このようにAVR ISP Shieldをセット。（電源はOFFの状態で設置する）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/450006d3-fdc7-4077-0239-79b9918a4716.png)

4、基本設定を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/65192413-495d-c05d-9a5f-ab8dd4ff4ee5.png)

5、以下のURLをボードマネージャに追加
https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/5b399c05-0fab-2af3-f1ee-081a6608c873.png)

6、ボードマネージャーを起動して、検索枠に「ATMega328」を入力し、
MiniCoreをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/9a9561bc-14a5-eeb7-ad9b-b2183793f0f0.png)

7、スケッチ例でBlinkを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/5e6b9c2f-9234-a0b4-497c-ded628572864.png)

8、ツールで以下の設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/780547e6-0482-30eb-2086-e123c0ad083e.png)


9、スケッチで書き込み装置を使って書き込むを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/f810a4ba-3b85-131c-0de9-93fdfac38452.png)

10、以下の写真のように接続。電源は、基準電圧発生器を使用しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/700bc2e4-839e-d446-3c6f-4fa120195c14.png)

以上

やっぱり書き込み装置を使用すると簡単に書き込みができますね！！
ATMega328Pの開発依頼があればお気軽にご相談くださいー！！