OmniAICreator/Qiita-1.07M huggingface dataset:
【Git hub】草が生えない？！git hubのメールアドレスはあっているのに、、、

こんばんは！
実は1月からプログラミングを初めて早1ヶ月と少しですが、
Git hubを半月前に勉強したものの、ディレクトリを作成したときしか草生えなくない？
commitとかpush毎日しているのになぜ???と悩まされていました。
Git hubのプロフィールのメールアドレスはあっているのに、草が生えないと思っている方は
もしよかったら参考にしてみてください。

## リモートとローカルのemailアドレスが登録されていなかった！(ターミナル上)
　『草生えない』と調べると大体git hubのプロフィールを見てみましょうとなりますが、そちらはもう登録済みの方は、ターミナル上で下記の検索をしてみてください。
 ```terminal:ターミナル
$ git config --global user.email 
$ git config --local user.email 
 ```
 検索したのに何も出てこないという方、私と同じです！！
 今日から草を生やすために以下のコードでemailアドレスを登録しましょう。
 といっても先ほどのコードの後ろにアドレスを加えるだけです。
  ```terminal:ターミナル
 $ git config --global user.email 自分のメールアドレス
 $ git config --local user.email　自分のメールアドレス
 ```
 これで登録できました。その後一応確認で最初の検索で使ったコードを打ち込んでみて、
 検索結果でメールアドレスがターミナルに表示されればOKです！
 要するにGit hubでメールアドレス登録をしてたけど、リモートとローカルの設定をしていなかったため、連携されておらず直接Git hubをつかうディレクトリ作成でしか草が生えていないということでした。

## 反映されてない？
　実はターミナル上で登録した後にもう一度commitやpushをしなければ反映されないため、
 何か更新したものがあれば試しにcommitやpushをしてみてください。そうすると今日の分の草が生えています！
 （私は今日の分の草は生えましたがこれまでの分は生えませんでした...ドンマイ:sob:）

解決されましたか？おそらく初期設定し忘れている初心者あるあるだと思うので、
今日からたくさん草を生やしましょう:herb:

### 補足
 　すっかりお伝えし忘れていたのですがこれでも直らない方は、デフォルトブランチの設定やGit hubとローカル、リモートのアドレスに相違がないかもう一度確認してみてください。また、シンプルに時差で草が生えないパターンもあります。
ImageMagickを使ってAndroidのスクショにデバイスフレームを合成する方法（ストア画像作成）

Play Consoleでストアに公開するにはスクリーンショットを用意する必要があります。
エンジニア一人の趣味開発でも、それなりのものを用意したいところ、本当のスクリーンショットよりも、デバイスフレームがついた画像の方が見栄えしそうなので、これぐらいはなんとかしたいと思いました。

|ノーマルなスクショ|フレーム付き|
|:-:|:-:|
|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/c222e687-d032-9916-dbf8-9e0e93354ec4.png)|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/d60d11b0-8763-0659-a152-9e5f6048b338.png)|

しかし、不慣れな画像編集ソフトでちまちま調整して何とか一枚できて、さて、同じ作業を何回繰り返すんだ？マクロとか？よくわからん！
よし、ImageMagick使おう！ということでやり方調べたのでそのメモです。

# デバイスフレームの素材

Android Studioでエミュレータ（AVD）で、Device Frameをつけることができますね。この素材が`Sdk/Skins`以下にありますので、これを利用させてもらいましょう。

例えば、Pixel 7の場合
- back.webp
- layout
- mask.webp

という3つのファイルが入っていると思います。

layoutの中身を見てみます
```
parts {
  device {
    display {
      width 1080
      height 2400
      x 0
      y 0
    }
  }
  portrait {
    background {
      image back.webp
    }
    foreground {
      mask mask.webp
      cutout hole
    }
  }
}
layouts {
  portrait {
    width 1200
    height 2541
    event EV_SW:0:1
    part1 {
      name portrait
      x 0
      y 0
    }
    part2 {
      name device
      x 59
      y 58
    }
  }
}
```

正確な意味は不明ながら、なんとなくどういうことを表現しているのか読み取れますね。
デバイスの解像度が1080x2400で、スクショ機能でとれる画像がこのサイズになります。
背景にback.webp、前景にmask.webpが使われ、フレーム付きの画像サイズが1200x2541でオフセットがx:59 y:58といったところでしょうか？

正確な仕様は以下にあるらしいです。

https://android.googlesource.com/platform/external/qemu/+/emu-master-dev/android/docs/ANDROID-SKIN-FILES.TXT

重ね合わせの方法としては、スクショ画像にmask.webpを適用した上でback.webpの上に乗せるような形みたいですが、back.webpを見てみると、オフセット加工したスクショの上にback.webpを重ね合わせるだけで良さそうです。

|back.webp|mask.webp|
|:-:|:-:|
|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/bc19ff80-fbb3-1593-8d66-bdd7d35b20ea.png)|![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/ab0e0634-3545-5c4f-59d9-bdf74c538846.png)|

# ImageMagickで重ね合わせる

ということで、コマンドラインツールで加工できればいかようにでもできるぜ。ということでImageMagickつかって加工しちゃいましょう。これができれば、あとはシェルスクリプトなりで、何枚画像があろうが同じ加工を適用しちゃえば良いです。

## インストール

ImageMagickはほとんどの環境のパッケージマネージャでインストールできるかと思います。

Windows
```powershell
winget install ImageMagick.ImageMagick
```

Ubuntu
```sh
sudo apt install imagemagick
```

Mac
```sh
brew install imagemagick
```

その他、公式サイト配布のバイナリを使ってもいいですし、ソースコードからコンパイルするという方法もあります。

https://imagemagick.org/script/download.php

## 加工

```shell
convert screenshot.png -background transparent -extent 1200x2541-59-58 back.webp \
-compose over -composite out.png
```

スクショの上にそれよりも大きな画像を重ね合わせるので事前のコンバートが必要です。
背景を透過にして、x:59,y:58のオフセットを付け、1200x2541に拡大して、back.webpを重ね、出力という命令ですね。

AVDでスキンが用意されていればどのデバイスでも同じ要領でいけますね。

---

これで、不慣れな画像編集ソフトと格闘せずに、フレーム付きスクショを作成できます。
以上です。
画像見開き表示で、ウィンドウをリサイズしても比率を維持したままにする

画像ビューアを作成していたら久々に詰まった。

```html
<div class="box">
  <img alt="left-image" class="image-view">
  <img alt="right-image" class="image-view">
</div>
```

```css
.box{
  display: flex;
  justify-content: center;
  height: 100dvh;
  overflow: hidden;
}

.image-view {
  height: auto;
  object-fit: contain;
  max-width: 50%;
}
```

お試しあれ。
YOLOv8でのエラー(Could not run 'torchvision::nms' with arguments from the 'CUDA' backend.)を解決

## 状況

[公式サイト](https://pytorch.org/)の通りPyTorch, Torchvision, Torchaudioをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1950815/70a8bb0f-7877-f846-e4ec-13e06b44e41a.png)

YOLOv8モデルを実行すると
```python
from ultralytics import YOLO

dataset_path = "datasets"

model = YOLO("yolov8n-cls.pt")

results = model.train(data=dataset_path, epochs=100, device="cuda")
```
エラーが発生
```
~略~
Could not run 'torchvision::nms' with arguments from the 'CUDA' backend.
~略~
```
## 解決

pip listでパッケージを確認
```
torch                        2.2.0+cu118
torchaudio                   2.2.0+cu118
torchvision                  0.17.0
```
torchvisionがgpu verになっていない

gpu verのtorchvisionをインストール
```
pip install torchvision==0.17.0+cu118 -f https://download.pytorch.org/whl/torch_stable.html
```
pip listで正常にインストールされていることを確認
```
torch                        2.2.0+cu118
torchaudio                   2.2.0+cu118
torchvision                  0.17.0+cu118
```
再度YOLOv8モデルを実行すると別のエラーが発生
```
RuntimeError:p
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.
```
プログラムを修正
```python
from ultralytics import YOLO

dataset_path = "datasets"

if __name__ == "__main__":
    model = YOLO("yolov8n-cls.pt")

    results = model.train(data=dataset_path, epochs=100, imgsz=200, device="cuda")
```
無事正常に動作
```
Starting training for 100 epochs...

      Epoch    GPU_mem       loss  Instances       Size
      1/100     0.539G      1.551          6        224: 100%|██████████| 79/79 [00:05<00:00, 15.60it/s]
               classes   top1_acc   top5_acc: 100%|██████████| 9/9 [00:00<00:00, 16.66it/s]
                   all      0.494          1
```
ネガティブプロンプトを比較してみる。【StableDiffusion】

結局ネガティブプロンプトが結構大事ということなので、
どれくらいネガティブで違いが出てくるか検証してみました。

https://romptn.com/article/2905


今回使う`モデル`と`ポジティブプロンプト`は以下
|モデル|anything_v50|
|-|-|
|Positive|1girl, solo, medium breasts, skirt, blonde hair, black vest, socks, brown footwear, bow, school uniform, long hair, shoes, jacket, white socks, bowtie, loafers, blush, kneehighs, pink bow, grey skirt, blue jacket, open jacket, pink eyes, shirt, one side up, white skirt, white shirt, long sleeves, star-shaped pupil <lora:hoshinoruby_v1:0.9>, outdoor, sunny, city, building <lora:more_details:0.3>, standing, upper body|

# 1

|参考URL|https://civitai.com/images/1818277|
|-|-|
|Negative|EasyNegativeV2, (bad_prompt_version2:1), bad-hands-5, (worst quality, low quality:1.8), bad anatomy, (monochrom:1.8), simple background, green background|

![image (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/6fb01a56-b9e1-64fd-f44e-5c26669647a9.png)

# 2

|参考URL|https://civitai.com/images/1739531|
|-|-|
|Negative|EasyNegative, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, (worst quality:1.2), low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, lowres graffiti, (low quality lowres simple background:1.1), (holding:1.5)|

![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/4365b11a-41c2-9350-925f-36e23e7167fa.png)

# 3

|参考URL|https://civitai.com/images/1739531|
|-|-|
|Negative|EasyNegative, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, (worst quality:1.2), low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, lowres graffiti, (low quality lowres simple background:1.1), (holding:1.5), (bag:1.5)|

2とあんま変わってない...

![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/92de1626-b4e0-7ab6-f890-88d3aabfd4ec.png)

# 4

|参考URL|https://civitai.com/images/6369984|
|-|-|
|Negative|(worst quality, low quality:1.4),|

![image (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/33fe778f-8cd0-25a9-2aed-be677e6c3c68.png)

もしかしてポジティブプロンプトが強すぎる？

# 5

|参考URL|https://civitai.com/images/6174137|
|-|-|
|Negative|(worst quality:1.4, low quality:1.4), (bad anatomy), (inaccurate limb:1.2), bad composition, inaccurate eyes, extra digit, fewer digits, (extra arms:1.2), multiple views, badhandv4, physical-defects:2, unhealthy-deformed-joints:2, unhealthy-hands:2|

![image (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/0f40e9b9-414b-2f08-2888-c02c6f0a0f99.png)
【jQuery】valメソッドとは

# valメソッドとは
`val`メソッドは、フォーム要素の値を取得したり設定したりするためのメソッドです。具体的には、テキスト入力フィールド、テキストエリア、セレクトボックス、チェックボックス、ラジオボタンなど、フォーム要素の値を取得または設定するのに使用されます。

# セレクトボックスの入力値
selectタグを用いると選択肢式のセレクトボックスを作ることができます。selectタグとoptionタグからなり、各optionタグが選択肢になります。下図のように、selectタグはvalメソッドによって、選択中の値（optionタグのvalue属性の値）を取得できます。
```html
<!-- html -->
<form>
    <div>性別</div>
    <select id="gender">
        <option value="male">男</option>     //セレクトボックスの選択肢
        <option value="female">女</option>   //セレクトボックスの選択肢
    </select>
</form>
```
```js
//js
var gender = $('#gender').val();
//select要素の選択されているoptionのvalue属性を取得
```
# 入力欄への自動入力
valメソッドは値を取得することもできますが、引数に値を指定することでフォームに値をセットすることもできます。例えば、inputタグへの値のセットを行う場合は以下のように記述すると「山田太郎」という値がセットできます。
```html
<!-- html -->
<form>
    <div>名前：</div>
    <input id="name" type="text">
</form>
```
```js
//js
$('#name').val('山田太郎');
//input要素（text内）に「山田太郎」という値をセット
```
# セレクトボックスの自動入力
selectタグもvalメソッドを用いて自動で選択させることができます。先ほどのinputタグとの違いは、selectタグの場合選択肢が限定されているということです。以下のように記述するとセレクトボックスの中に「女」という値が自動入力されます。
```html
<!-- html -->
<form>
    <div>性別：</div>
    <select id="gender">
        <option value="male">男</option>     //セレクトボックスの選択肢
        <option value="female">女</option>   //セレクトボックスの選択肢
    </select>
</form>
```
```js
//js
var gender = $('#gender').val(female);
//select要素のoptionのvalue属性がfemaleのものを選択させる
```
Qiitaの記事をGithub で管理したくて、WSL にvolta でnode インストールしてQiita 記事をpull まで


# 今回の趣旨

Qiita の記事をQiita 内で管理してもよかったのですが、どうせならGithub で管理してみたいなという欲望があったので、設定をしてみることにしました。その時にWSL と普段は連携しているので、WSL 上にnode をインストールする必要が出てきました。

# 今回の記事の前提

- Github のアカウントをもっていること
- Qiita でpersonal access token を発行済みであること
(後にGithub action を使うため)



# volta install

curl でvolta をインストールします。

```powershell
$ curl https://get.volta.sh | bash
```


volta のインストールの確認をしていきます。

```
volta -v
1.1.1
```

(volta のバージョンを確認するコマンドでバージョンが表示されない時は、一度WSL などを閉じてから再度開いてみるとバージョン確認コマンドが通ると思います。)


# node install

今回 Qiita-cli を使うにあたって、18 以上のnode のバージョンが必要なため今回はnode のバージョン20 をインストールしていきたいと思います。

```
volta install node@20
```

npm も必要みたいですが、npm はすでにnode をインストールした時にインストールされているので、追加でのインストールは不要です。


# Qiita の準備


npm で qiita-cli をインストールしていきます。

```
npm install @qiita/qiita-cli --save-dev

# devで使用するため --save-dev を入れています
```

ちゃんとインストールされたかを確認するために、npx コマンドで確認します。そして、init コマンドを叩いてプロジェクトの初期化を実施します。
```
# バージョン確認
npx qiita version

# プロジェクト初期化
npx qiita init
```

プロジェクト初期化すると以下の表示が出るので、それに沿って進めていきます。

```
次のステップ:

  1. トークンを作成してログインをしてください。
    npx qiita login

  2. 記事のプレビューができるようになります。
    npx qiita preview
```

Qiita にログインします
```
#login 
npx qiita login 

# 以下の表示がtoken を入力後に出力

ログインが完了しました 🎉
以下のコマンドを使って執筆を始めましょう！

🚀 コンテンツをブラウザでプレビューする
  npx qiita preview

🚀 新しい記事を追加する
  npx qiita new (記事のファイルのベース名)

🚀 記事を投稿、更新する
  npx qiita publish (記事のファイルのベース名)

💁 コマンドのヘルプを確認する
  npx qiita help
```

最後にQiita ですでに公開されている記事をpull してきます。
そうするとpublic というディレクトリの中にmd ファイルが作成されていると思います。

```
npx qiita pull 
```

ここまでできたら、後は新しい記事を公開して、push して公開するだけです。記事の削除は手動で行わないといけないらしいので、今後の発展に期待です

# 参考サイト



https://zenn.dev/taichifukumoto/articles/how-to-use-volta


https://zenn.dev/hrkmtsmt/articles/5f4a0e5c79b77a


https://volta.sh/
義肢をブレインマシンインターフェースを通じて動かす技術の臨床研究をしたい

# はじめに

私は義肢をブレインマシンインターフェースで操作する技術の臨床研究をするため、医学を学びたい。
工学と医学の橋渡しをしたいと考えています。

少し調べれば大抵のことはWikipediaを通じて分かることですが、自分の言葉で話をしたいので、極力借りてきた言葉を使わずに自分の言葉で話したいと思います。

脳に電極を刺してスマートフォンを動かす技術をブレインマシンインターフェースなどと呼ぶらしいのですが、それを、義肢の操作に応用できないかと考えているのです。

アメリカでは、イーロン・マスク氏率いるニューラリンク社が先端技術を行っているようですね。スマートフォンの実験では、成功しているようです。恐らく、義肢を操作する技術もイニシアチブを握っていくでしょう。

そこで、研究を通じて疑問に思ったこと、新たに知識となったことをを纏めてこの場で発表しようと思います。

## 人工物を生体内に入れることのリスク：

#### 人工物の導入に関する問題点、免疫システムとの融合について

[https://medicalnote.jp/contents/170425-003-TX](https://medicalnote.jp/contents/170425-003-TX)より

人工関節置換術は多くの施設で行われている手術ですが、この手術後、ごくまれに置換した人工関節が細菌感染を起こしてしまうことがある。
この状態を人工関節周囲感染（PJI）と呼びます。

・PJIを生じる頻度はそれほどない。
・自覚症状がないため、診断が難しいが、早期診断・治療を行えば治癒できる可能性もある。
・早期診断が重要

人工関節周囲感染(Prosthetic Joint Infection:PJI)とは、人工関節の周囲に感染が起きた状態を指す。
人工物はバイオフィルムと呼ばれる防護膜のようなものが生成され、最近に対する生体の防御反応や抗菌薬の効果が働きにくくなっている。
この人工関節が何らかの原因菌によって感染を起こすと、インプラントの周りの骨がとけてしまう。
その際、抗菌薬の投与や再手術が必要になる。

細菌感染のルートは？
・歯周病、虫歯、扁桃炎、糖尿病もPJIのリスクを高める

PJIの確率は、人工関節置換術を受けて人の0.5～1%程度。それほど高くない。

人工関節と生体内の器官との間には、バイオフィルムというシールドが作られるというのがキーポイントみたいです。次回は、このバイオフィルムについて調べたことを、かみ砕いて説明してみようと思います。

### バイオフィルムについて

[https://www.med.osaka-cu.ac.jp/bacteriology/b-online/biofilm/b1.shtml](https://www.med.osaka-cu.ac.jp/bacteriology/b-online/biofilm/b1.shtml)からの引用です。

バイオフィルムとは、微生物が固形物や生物の体の表面などに付着して形成する集合体です。
例えるなら、シンクの三角コーナーの水切りの周りについた「ぬるぬる」のことです。
あれが、バイオフィルムです。

#### インプラントとバイオフィルム

バイオフィルムはカテーテルなどの治療のために体の中に入れておく器具の表面に形成された場合、私たちの体を攻撃して感染症を引き起こすことがあります。
しかも、病原菌がバイオフィルムマトリクスに覆われることで抗生物質や免疫が効きにくくなるため、バイオフィルムがかかわる感染症は治療が困難だと言われています。
バイオフィルムマトリクスは、いわば病原菌を守るバリアとして機能するので厄介です。

恐らく、インプラントにバイオフィルムがまとわりついてインプラントに悪い細菌がついて、バイオフィルムが免疫による攻撃をかわしてしまうことなんだと思います。
そして、インプラントに付着した悪い細菌が骨を溶かしたりする。
免疫とは、素晴らしい味方でもあれば厄介な敵にもなるわけですね。

バイオフィルムを完全に除去する再手術が必要になるという理由がよくわかりますね。

次回は、人工関節の脱臼、ゆるみ・摩耗について問題点を探っていきます。

### 脱臼・ゆるみ・摩耗

[https://www.ishamachi.com/?p=90497](https://www.ishamachi.com/?p=90497)よりの引用です。

症例として、人工股関節手術を例に挙げて説明します。
人工股関節置換術を受けると、円滑に日常生活を送ることができるようになりますが、術後、筋力が安定するまで脱臼を予防するための禁忌肢位を指導されることがあります。
禁忌肢位とは、取ってはならない姿勢です。

股関節周囲の筋肉や腱、間接を覆う膜を切離しているため脱臼やすい姿勢があり、禁忌肢位として動作に制限が設けられています。
一方で、筋肉や腱、間接を覆う膜を切らないで行う方法も普及しているので、従来に比べ脱臼しにくいと言われています。

ゆるみとは、こんな感じです。
人工関節で軟骨の役割をする高分子ポリエチレンのライナー(凹のくぼみ)と大腿骨頭の代わりのボールは(凸の突起)が接触しながら動きます。
ポリエチレンは徐々にすり減ることがわかっていて、削りカス(摩耗粉)が発生する。その摩耗粉に免疫系が反応し、周りの骨を溶かしてしまうことがある(骨溶解)。
そうすると、しっかり固定していたはずの人工股関節周辺に隙間ができてしまいます。これがゆるみの原因です。
骨を溶かす反応には、個人差があります。
これが、ゆるみと摩耗の関係になります。

次に、筋電位の仕組みについてお話しします。
顔の表情だけを変えて画像を生成する【ADetailer】

すごい拡張機能あるんですね。
勉強していくと次々とすごい技術が出てきます。

https://romptn.com/article/6752

# 導入方法

install欄に以下を入力
> https://github.com/Bing-su/adetailer

# 使い方

画像を適当に生成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/fcdca72e-5913-837c-4816-880b926a69c6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/02fa6605-e236-4ebe-64e0-0fff4b22f6ae.png)

- シード値を固定
- Enable

試しに、Adetailerのプロンプトに
`angry`と入れてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/2a92f372-e70b-8c30-76bd-eb544114056c.png)

ちょっと怒った？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/96e93fbb-474f-31b3-a641-8c42ada3b173.png)

`Inpaint denoising strength`を`0.4から0.6`にあげてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/58605253-8a87-d1dd-9399-a7b2c10c89c0.png)

かなりお怒りのご様子。
もっと怒らせてみる？(→0.7)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/387e4e7c-18c6-9660-8c45-b6a615ccfc84.png)

これはさすがにやりすぎっすね。

ちなみに`1`にするとクッパになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/69bc84b9-96ca-8c97-8bd6-ec7d72509fd3.png)


# 微調整

元画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/f9b5150b-9152-75a6-9b00-b5a55729658b.png)

smile, enjoy(0.50)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/89c92073-1838-1904-1553-71e604d86987.png)

smile, enjoy(0.55)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/35531d91-2126-9037-a533-74f42de5a7c0.png)

smile, enjoy(0.60)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/7ca003ab-3ce3-e8a7-754c-157a4ed8bbff.png)

smile, enjoy(0.80)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573902/fea962b5-9705-c15e-481f-e6fcac27e105.png)

`smile`に関しては効果は薄い？
Oracle CloudのCanonical Ubuntu 22.04 にデスクトップ環境(LXQt)を構築し、Windowsのリモートデスクトップ接続から利用できるようにする

# はじめに
Oracle Cloud(OCI)のComputeではUbuntu Serverを構築することができるが、
デフォルトではCLIの操作しかできず、デスクトップ環境はインストールされていない状態となる。
今回とあるGUIアプリケーションをUbuntu上で動作させたい需要があり、
UbuntuにLXQtと呼ばれるデスクトップ環境を構築し、Windows OS標準のリモートデスクトップから接続できるような環境を整備する。

今回[こちら](https://www.youtube.com/watch?v=onjz8AYMqwo)の動画を参考にさせていただき記事を投稿致します。

# LXQtとは

> LXDE、LXQt共に、GNOMEやKDEと同じようにウィンドウマネージャ、ファイルマネージャなどのソフトウェアをまとめたデスクトップ環境の1つです。
LXDEはC言語で実装され、GTK+ツールキットを利用しています。一方、LXQtはC++で実装され、Qtツールキットを利用しています。LXQtはLXDEをQtを用いて書き換えたもの、と言うことができます。
LXDE、LXQtは、Windowsに似たインターフェイスを提供し、初心者にも使いやすいデスクトップ環境となっています。また、軽量に作られており、スペックの低いPCでも動作します。

https://linuc.org/study/knowledge/500/

# 早速構築
## インスタンス作成
OCIのコンソール画面のコンピュート→インスタンスよりインスタンスの作成をクリック

- イメージは"Canonical Ubuntu 22.04"を選択
     ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/a9c77a5b-8305-2afc-0b63-8f5fe9c1900f.png)
- Shapeは任意のものを選択
    - 今回はVM.Standard.E5.Flexの2 core OCPU, 24 GB memoryを選択してみました
- プライマリネットワークやサブネットも任意になりますが、ssh(22)とRDP(3389)をセキュリティリスト or ネットワークセキュリティグループで許可するように設定ください
- 他必要項目を埋めた後に作成ください

## 必要なパッケージのインストール＆設定

sshでログイン
```shell
#- Connect to the server
ssh -i /path/to/key ubuntu@server_ip
```

Rootに変更＆パスワードの設定
```shell 
#- Switch to root and set password for root
sudo su -
passwd
```    
必要パッケージのインストール
```shell
# -Install desktop env. and xrdp
apt update && apt -y upgrade
apt install -y lxqt sddm xrdp
```
途中Pending kernel upgradeの画面が表示されますが、Ok→Okで進めてください

xrdpの有効化
```shell
systemctl enable --now xrdp
systemctl status xrdp
```

iptablesに3389 Portの許可
```shell
vim /etc/iptables/rules.v4
```
22番ポートと同様に、3389ポートも許可するように追記ください
```shell
# ~ 16行目あたり
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3389 -j ACCEPT #追記★
# ~ 
```
設定の反映をします
```shell
iptables-restore < /etc/iptables/rules.v4 
```
.xsessionにstartlxqtを記述
```shell
# Set startlxqt in the  .xsession file
echo startlxqt  >> ~/.xsession
```
> startlxqt - script to initialize and launch LXQt sessions  
> https://manpages.ubuntu.com/manpages/bionic/en/man1/startlxqt.1.html

以上で設定は完了です

# Windowsのリモートデスクトップから接続
上記設定が正しくできていれば、Windowsのリモートデスクトップ接続からアクセスが可能です。

- コンピューターにサーバのIPアドレスを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/546d06cc-a278-e12b-f62f-2fd77969537e.png)
- Login画面が出てくるので、username: root, password: [設定した値]を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/c6621073-a08f-9fc1-645b-ddd34a683f30.png)
- デスクトップ画面が表示されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2470077/2741f527-694a-7674-5782-22fc0dd19fea.png)

これで簡単にデスクトップ環境の導入が成功しました。
うまく接続できない場合は、3389がOSとOCIからそれぞれ許可されているかをご確認ください。

# 参考記事
https://www.youtube.com/watch?v=onjz8AYMqwo
PowerAutomateを使って自動でExcelファイルを開いてみた

みなさん、こんにちは。
今回はpowerAutomateを使った実装編を紹介します。



Excelファイルを自動で開くシステムを試してみました。



実装のフローはこんな感じです

**Excelファイルを開く→シートの中身を取得（変数A)→（変数A）を表示**
![スクリーンショット (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/c250fe30-be11-5742-ef13-24e9c7f9f79c.png)

### 手順 ###

**①Excelファイルを作成（既存のものでも可）**
※今回は商品名とJANコード

![スクリーンショット (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/f8e17109-b849-b07e-9f8b-b7b25fefd6d0.png)
**②Excelの起動**
・ドキュメントパスでファイルを選択
![スクリーンショット (25).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/8cef018c-4090-4fe7-cd7d-0d1187b67aae.png)
③**Excelワークシートから空の列や行を取得する**
・Columnは列、Rowは行
![スクリーンショット (26).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/7d45ac29-4a1d-9656-7d53-d27abd59dfbe.png)
**④Excelワークシートから読み取る**
・最終列は空列になるため－1をする、最終行も空列になるため－1をする
![スクリーンショット (27).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/ff2407b6-1479-83df-ebff-0f795b2a9ee3.png)
**⑤メッセージを表示**
![スクリーンショット (28).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655358/6136fad2-e601-c873-66d7-3267329364dd.png)
・メッセージボックスのタイトルはExcelの中身を見たいため**Excelの中身**とする

実行すると一番上のフロー画像となります。

### 実際に使ってみた ###

私と店長とのやり取りの一部を紹介します。


私「店長、PowerAutomateでExcelファイルを自動で開くシステムを作りました！」

店長「**PowerAutomateって何？**」

私「定型業務をルートに従って自動化することです」

店長「どんなのができたの？」

　　　　　　　　　ここで、手順①～⑤を紹介

店長「へ～、便利だけど、どんな時に使うの？**使う機会あるのかな？**」

私「店長の事務作業の中で反復している作業があれば生かせると思いますよ」

店長「じゃあ、試しにやってみてね」


### フィードバックから学んだこと ###

　実際に特定のセルの行だけを表示する機会があるのか？といわれると言葉に詰まってしまいました。事実、私自身業務でパソコンを使う機会が極端に少ないため、このような機会が普段、実践されているのかがわかりません。
　まずは、PowerAutomateを**使用する目的や、意味を理解**していないと、どのような場合に使えるのかがわからないことを知りました。
　今回は、店長以外にもPowerAutomateについて知らない方が多かった印象を受けました。
Androidで物理キーボード・Bluetoothキーボードを日本語配列で使う

# 概要
Bluetoothキーボードを日本語配列で使うための戦い。半角と全角を、キーボードを切り替えたいのに切り替えられなくてイライラしていたのですが、見つけたらむっちゃ簡単でした。
そもそもネットの情報が古いなと思いました。Google日本語入力を使うとかいろんなホットキー試すとか。

# 環境
* Logicool K380
* NEC Lavie Tab 10FHD3
    * Android 12
    * Gboard

# 手順
### IMEをGboardにする
設定アプリで「システム > 言語と入力 > 画面キーボード > 画面キーボードを管理」
Gboardを有効にする。

### 物理キーボードの設定を変える
Bluetoothキーボードはつなげた状態にしておきましょう。

https://support.google.com/android/answer/14114879?hl=ja
これによると設定アプリに「システム > キーボード > 物理キーボード」というのがあるらしい。…ないんだけど。（設定がある人は次の項目を飛ばして読んでください）

#### 設定が表示されないとき
* 文字入力状態でGboardの「あ」のマークを選ぶ。
* 「設定」を押してGboardの設定を開く。
* 「設定 > 物理キーボード > システムの物理キーボード設定」を選ぶ。

これで無理やり物理キーボードのレイアウトの設定を開くことができます！！！！神！！
設定が表示されたはずなので下の項目に行ってください。

#### 設定が表示されたら
「物理キーボード > Keyboard K380 Keyboard（機種によって変わる）」を選んで、「日本語109A配列」を選びます。これで```全角/半角キー```を使って切り替えることができるようになります。

ちなみに「英語（アメリカ）、インターナショナル配列」も選んでおくと英字配列も使えます。切り替えは文字入力状態で```Ctrl+Space```です。
【MySQL】Windows起動時にMySQLサーバが自動起動させないようにする方法

# 目的／背景
Windowsのlocal環境にMySQLをインストールすると、OS起動時に毎回MySQLサーバが立ち上がってしまう。
勝手にMySQLサーバが立ち上がるのをやめさせたい。

# 概要
OS起動時のMySQLサーバ自動起動を手動起動に設定する。

# 手順．MySQLサーバ自動起動の設定
WindowsツールのサービスよりMySQLを見つけてプロパティを開く。
（コントロールパネル＞システムとセキュリティ＞Windowsツール＞サービス）

<img width="100%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2628353/a4ed13ff-0b4a-2082-9bf5-80d2252402f7.png">



スタートアップの種類を「自動」から「手動」に変更し、適用する。

<img width="400px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2628353/f362831b-92f0-a64b-821b-870cd5a8854e.png">


以上で、OS起動時にMySQLサーバが勝手に立ち上がるのをやめさせることができます。


　[次回：【Windows】サービスの確認・起動・停止をコマンド実行](https://qiita.com/Shime_texas/items/262b412a458721af30ef)
Laravel×minio×Dockerで環境構築

# minioとは
Go言語で実装されたオブジェクト・ストレージ・サーバーです。Amazon S3とも互換性が高くローカル環境など個人で利用することに非常に使いやすいものになります。  
今回こちらを使用する機会が訪れましたのでその時行ったことの備忘録用に残しておこうと思います。

# 手順
今回はminioに焦点を当てたい為、laravelの環境構築は割愛します。
まず、docker-compose.ymlに以下の内容を記載します。
```docker-compose.yml
version: '3'
services:
  minio:
    image: minio/minio:latest
    container_name: minio
    environment:
        MINIO_ROOT_USER: localid  # minioユーザーネーム
        MINIO_ROOT_PASSWORD: localpassword # minioパスワード
    command: ['minio', 'server', '/data', '--console-address', ':8080']
    volumes:
        - ./minio_data:/export  # minioストレージの永続化
    ports:
        - '9000:9000'  # APIのエンドポイント
        - '8080:8080'  # GUI画面のポート
```

次に`docker-compose build`,`docker-compose up -d`でminioを立ち上げます。
立ち上がったら`composer require league/flysystem-aws-s3-v3 "^3.0"`をインストールします。  
※"^3.0"はLaravelのバージョンによって異なるのでそこは調べてみて下さい。  
composerのインストールが終わったら以下ファイルを編集します。
```Laravel/config/filesystems.php
's3' => [
            'driver' => 's3',
            'key' => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_DEFAULT_REGION'),
            'bucket' => env('AWS_BUCKET'),
            'url' => env('AWS_URL'),
            'endpoint' => env('AWS_ENDPOINT'),
            'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
            'throw' => true, // minioのエラーをcatchしたい場合はtrue
        ],
```
それに合わせて.envファイルも編集します。
```.env
AWS_ACCESS_KEY_ID=localid
AWS_SECRET_ACCESS_KEY=localpassword
AWS_SESSION_TOKEN=
AWS_DEFAULT_REGION=ap-northeast-1
AWS_BUCKET=test
# ローカル環境のみ必要
AWS_URL=http://localhost:8000
AWS_ENDPOINT=http://minio:9000
AWS_USE_PATH_STYLE_ENDPOINT=true
```
するとhttp://localhost:8080
でminioのページが見れるようになります。  
MINIO_ROOT_USERとMINIO_ROOT_PASSWORDを入力して
bucketsを作成して下さい。名前はtestにしておきましょう。  
そこまで完了したらphpのコンテナに入り以下のコマンドを打ち出したtrueが出たら接続完了です。
```php
php artisan tinker

Storage::disk('s3')->put('hello.json', '{"hello": "world"}')
```
# 感想
今回minioの環境構築をやってみました。少しエラーに悩まされた部分もありますが、全体的に簡単に構築できおすすめです。laravelのstrage以外に保存してみたい方や、今後S3を使う予定のある方は使ってみてはいかがでしょうか。

是非弊社開発課のXのフォローもよろしくです！
毎日エンジニアに向けた情報発信を行っています！

https://twitter.com/tech_cin
【kotlin】文字列の中に特殊文字が含まれているか確認する方法

# はじめに
文字列操作って案外大変だったりしますよね。
特に正規表現を使って行うようなバリデーションなどは条件によっては少し考えてしまうことも多いのではないでしょうか。
今回はバリデーションでありがちな文字列の中の特殊文字の有無を判定する方法をまとめておこうと思います。

# 文中の特殊文字の判定方法
文中の特殊文字の有無を判定するには、以下により実現可能です。

```main.kt
fun hasIncludeEmoji(str: String) {
    val regex = Regex("\\p{So}")
    return regex.containsMatchIn(str)
}

val value1 = hasIncludeEmoji("あいうえお😊") // true
val value2 = hasIncludeEmoji("あいうえお") // false
```

以上になります。
今回はUnicodeのSymbolOtherカテゴリに属するものを判定する形になっていますが、SymbolOtherカテゴリには様々な文字ブロックが存在するので、バリデーションによっては特定のブロックのみに絞るなどの対応をしても良いかもしれませんね。

# さいごに
正規表現も複雑な領域ではありますがわかると中々面白いですよね。
実験的にさまざまなパターンの検証をしたくなります。
巨人の肩の上にのって開発しよう　- 3Dカメラを例にして -

## 主旨
ロボットの分野の画像認識技術は、2次元画像としての理解では足りない。
そのため、3D計測と画像認識の連携が必要になる。
ロボットのビジョン技術を開発するには、ステレオ計測などの３D計測技術と画像認識技術の双方の力が要求される。

しかし、3D計測用のカメラと推論を実行するためのプラットフォームを選んだ後は、その標準の環境によっては、最初から豊富なサンプルアプリケーションが用意されていることもある。

先に述べた[カメラと推論アクセラレータの共進化](https://qiita.com/nonbiri15/items/f6db1767a245a5b3d22a)の結果、豊かな果実がもたらされている。

ここでは、その例として、StereoLabs のZED SDK のサンプルアプリケーションを紹介する。

## StereoLabs ZED SDK Code Samples
StereoLabs のwebページ上のドキュメント
https://www.stereolabs.com/docs/samples

Github [zed-sdk](https://github.com/stereolabs/zed-sdk) 
これらのサンプルプログラムは、MIT licenseで公開されている。

このドキュメントは、StereoLabsの製品を購入していなくても、ダウンロードできます。説明の文書と実行例の画像を見ることも、サンプルプログラムのC++のソースコード、pythonスクリプトなども含まれています。

![Screenshot from 2024-01-31 15-15-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83761/2148cf80-22fc-5110-b308-a0811a7216fe.png)
[引用元](https://github.com/stereolabs/zed-sdk/tree/master)

これらのアプリケーションが、対象の3DカメラとNVIDIAのGPUのあるPCやJetsonですぐに実行できるのです。

（他の３DカメラのSDKについても同様なアプリケーションが増えているに違いない。）

## 優れた3Dカメラが出るまでの状況
これらのアプリケーションは、従来なら画像認識のエンジニアと3D計測のエンジニアが協力しただけでは、すぐには開発できなかったであろう優れものです。
　なぜ、画像認識エンジニアと3D計測のエンジニアが協力しただけじゃ不十分なのかだって。
 当時は、カメラのPositional Tracking ができなかったはずです。カメラの姿勢情報が欠落しているからです。

このZED2iは、ステレオカメラの導入がとてもしやすいものになっている。

## 節約できた作業
- カメラパラメータの決定作業
- 決定したパラメータを機体ごとに管理する作業
- ステレオ平行化の処理・視差計算などの明示的なプログラミング
- 基線長（左カメラ・右カメラ間の距離）に基づく、距離への換算
- IMUの選択・IMUを利用できるようにする環境設定
- IMUからの姿勢情報の取得
- 時刻の対応のとれた、カメラとIMUの情報の関連付け
- ステレオカメラからの点群データを、鉛直方向をそろえたデータへの変換

こういった作業をすべて代行してくれているのです。


## 僕たちはもっと先に進もう
- 画像認識・機械学習は、大規模言語モデル特にVision Transformer の進展でもっと先に進みつつあります。
- 既に解決された問題に対して、車輪の再発明をしている暇はありません。
- 僕たちはもっと先に進める。そういうラッキーな時代に生きている。

## コミュニティに寄与しよう。
- CPU・GPUのプラットフォームと3Dカメラとして、同じものを使っているユーザーは、そのプラットフォームが成長していくことがともに自らの利益になる状況にある。
- 実現したいことは山ほどある。しかも、一つ一つは自力開発したら、それ以上のことができなくなってしまう。
- これまで誰も到達したことのないところへ行きつくためには、協力するしかない。
- 修正を私家版だけにしておくと、本家の改版のたびに同じ修正をしなくちゃならない。
- そしてあなたが利用するコードは、広い範囲に及んでいるので、たくさんの修正を自分で管理し続けるのは現実的じゃない。
- さっさと本家にPRを申請して、自分の手から離してしまおう。そうすれば、身軽になって、もっと先へ進める。
Dockerでコンテナ間通信 (Python)

# はじめに
Pythonを使用してコンテナ間通信をお試ししたのでそれのメモ。
サーバ(api)に対して、クライアント側からrequestsライブラリでgetし、
実行結果をクライアント側で標準出力させた。

# フォルダ構成
clientフォルダとserverフォルダを作成し、それぞれにDockerfileを作成した。
必要なpythonライブラリ類はrequirements.txtを使用せず、直接Dockerfile内でインストールするようにした。
~~~
my-app
├─ client
│   ├ client.py
│   └ Dockerfile
├─ server
│   ├ server.py
│   └ Dockerfile
└─ docker-compose.yml
~~~

# サーバ側(web_server)
[FastAPI](https://fastapi.tiangolo.com/ja/tutorial/query-params/)を参考にserver.pyを実装させていただいた。

~~~Python:server.py
from typing import Union
from fastapi import FastAPI
app = FastAPI()

@app.get("/users/{user_id}/items/{item_id}")
async def read_user_item(
    user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item
~~~

`./server/Dockerfile`では必要なライブラリをインストールした後、APIを起動する。
~~~Dockerfile:Dockerfile
FROM python:3.9-buster
ENV PYTHONUNBUFFERED=1

WORKDIR /usr/src/app
COPY . ./

RUN pip3 install --upgrade pip
RUN pip3 install fastapi
RUN pip3 install "uvicorn[standard]"

EXPOSE 5000
ENTRYPOINT ["uvicorn", "server:app", "--host", "0.0.0.0", "--port", "5000", "--reload"]
~~~

# クライアント側(client)

サーバ側(web_server)では5000番ポートを使用するため、そこに対して
getさせるようにした。

client.pyについて、`requests.get('http://0.0.0.0:5000/・・`のようにIPアドレスを使用したいところであるが、
今回の環境では同一ネットワークに所属するweb_serverに対して名前解決が可能となっているためこちらを使用する。

~~~Python:client.py
import requests

r = requests.get('http://web_server:5000/users/100/items/100?q=100&short=True')
print(r.status_code)
print(r.json())
~~~

`./client/Dockerfile`必要なライブラリをインストールした後、client.pyを起動する。
~~~Dockerfile:Dockerfile
FROM python:3.9-buster
ENV PYTHONUNBUFFERED=1

WORKDIR /usr/src/app
COPY . ./

RUN pip3 install --upgrade pip
RUN pip3 install requests

# サーバーを起動
CMD ["python", "client.py"]
~~~

# docker-compose.yml

web_serverとclientの2つのコンテナを起動する。2つのコンテナは同一ネットワーク(api_network)に所属し、clientの実行はweb_serverの起動に依存させる。
~~~docker-compose.yml
version: '2'
services:
  web_server:
    build: ./server
    container_name: web_server
    tty: true
    # 5000番ポートを使用
    expose:
      - "5000"
    networks:
      - api_network

  client:
    build: ./client
    container_name: client
    networks:
      - api_network
    # web_serverに依存
    depends_on:
      - web_server

networks:
  api_network:
~~~

# 結果

2つのコンテナ起動後、クライアント側のコンテナで実行結果を標準出力できた。
~~~
$ docker compose up
web_server  | INFO:     Application startup complete.
web_server  | INFO:     172.19.0.3:40442 - "GET /users/100/items/100?q=100&short=True HTTP/1.1" 200 OK
client      | 200
client      | {'item_id': '100', 'owner_id': 100, 'q': '100'}
client exited with code 0
~~~
変なfor文にビビらないために

# はじめに
for文？ああ
```c:sample.c
for(int i = 0; i <= 10; i++){
    sum = sum + i;
}
```

みたいなやつね知ってる知ってる～ぐらいの人に、

・初期化式
・条件式
・変化式

について一度知っておこう、という記事。


# 初期化式
`int i = 0;`
に代表される部分。

for文を実行するとき、最初に一度だけ実行される。
`for(int i = 0;`のように、for文の中で初めて宣言された変数は、
for文の外では使えない。(変数のスコープ)

なので、for文の外で使いまわしたい場合、宣言も、for文の外でする必要がある。
```c:sample.c
int i;
for(i = 0; i <= 10; i++){
    //繰り返し処理
}

int x = i + 1;
```
for文の外で宣言と初期化 `int i = 0` するとどうなるか？
初期化式が必要なくなる。

しかし、初期化式がどこからどこまでかコンピュータが把握するには、
セミコロン`;`が必要。

という事情から、ごく稀に下のような、セミコロン`;`だけ急に出てくるfor文がある。

```c:sample.c
//for文の外で宣言 & 初期化
int i = 0;

//既に宣言 & 初期化されているので初期化式を省略可能
for(; i <= 10; i++){
    //繰り返し処理
}

//iを初期化せず続き(i = 11)から実行する
for(; i <= 20; i++){
    //繰り返し処理
}
```
初期化式が省略されたfor文を見て
「なんだこのセミコロン？いらないだろうし消しておくか」
をすると当然のようにコンパイルエラーが出る。(体験談)

後者のように`i`の値を使いまわす目的がないのであれば、
宣言時に初期化していてもちゃんと初期化式を書く方が見た目のやさしいコードになる。
```c:sample.c
int i = 0;
for(i = 0; i <= 10; i++){
    //繰り返し処理
}
```


# 条件式
この部分が`TRUE`の間、for文が実行される。
つまり、`i`自体を評価する式でなくても問題ない。
実例を示すと
```c:sample.c
int sum = 0;
//合計値が55未満の間、繰り返す
for(int i = 0; sum < 55; i++){
    sum = sum + i;
}
```

のように`sum`を基準とした条件式でも構わない。
一般的なfor文は「どんな条件のとき終了か」というより「最大で何回繰り返すか」
を考えるので、普通は上のような書き方にはならない。breakを使う。
```c:sample.c
int i = 0;
int sum = 0;

for(i = 0; i <= 10; i++){
    sum = sum + i;

    if(sum >= 55){
        break;
    }
}
```
個人的には、for文の主役は初期化式で初期化したものと同じ変数
( この場合`i` ) にしておくのが無難だと思う。

ちなみに、初期化式のように条件式も省略可能なので
`i <= 10`と`sum >= 55`のようにループを抜けるタイミングが一致している場合、
```c:sample.c
for(i = 0; ; i++){
    sum = sum + i;

    if(sum >= 55){
        break;
    }
}
```
としても "実行は" できる。(コンパイラによってはエラーを出すかも)

:::note alert
無限ループの可能性を生むので条件式の省略はやめましょう
:::


# 変化式
ループ1周分の終了と開始の間に実行される式。
いわゆる`i++`の部分。
ここまででなんとなく予想はつくかもしれないが、変化式も省略できる。

for文の末尾か開始に`i++;`を書いてあげるだけで同じ処理になる。

```c:sample.c
for(int i = 0; i <= 10;){
    //繰り返し処理
    i++;
}
```
変化"式"とあるように、1行に収まる式であればよいので、
三項演算子なんかもその気になれば使うことができる

```c:sample.c
for(int i = 0; i <= 10; i = i + ((i % 2 == 0) ? 1 : 3)){
    //繰り返し処理
}
```
:::note
偶数の場合、`i = i + 1`
奇数の場合、`i = i + 3`
されるfor文。
:::


もっと複雑な処理が挟まれる場合、関数を作って`i`のポインタ`&i`を渡す、という手もある
```c:sample.c
void main(){
    for(int i = 0; i <= 10; function(&i)){
        //繰り返し処理
    }
}

void function(int* i){
    i = i + 1;
}
```
:::note
これは結局のところ`i++`しているだけ。
:::



# おわりに
上の3つを合体させるとこんなfor文も作れるらしい。
泣かないで ( ; ; )

```c:sample.c
int i = 0;
int sum = 0;

for( ; ; ){
    sum = sum + i;
    if(sum >= 55){
        break;
    }
    i++;
}
```

:::note alert
特別な理由がない場合は3つとも式を書きましょう。
:::
ZED SDK を使いこなす inspectでデータ構造を理解する

## 想定する読者
- Python 言語での利用者
- 利用しているライブラリの使い方についてもっと知りたい人


利用するライブラリで、十分に網羅性があって、わかりやすい、検索しやすいドキュメントがあればうれしい。
しかし、そうじゃない場合もある。

## 対処方法
そんなときには、python のinspectモジュールを使おう。
そうすれば、対象のオブジェクトのデータ構造を知ることができる。

何かpythonでのオブジェクトがあったとき、そのオブジェクトのデータメンバー・メソッドを表示させる。

```:.py
import inspect
from pprint import pprint
object = 何かのコード
for k, v in inspect.getmembers(object):
    print(k, v)  # object のデータメンバーを表示させる。
```

そうすれば、そのデータ構造についての、情報を得ることができる。
赤外線受信

とても何年かぶりに、プログラムを再開。
時間ができたので、arduinoというマイコンを触ってみた。
エラー続出したので備忘記録を。

ELEGOOのリモコンを使って
arduino UNO に接続した赤外線受信機で受信し
リモコンのどのボタンが押されたか確認してみた

```
#include <IRremote.h>
```
このincludeでarduino IDE シリアルモニタを確認すると
受信信号はFFFFFFFFとなってしまう

シリアルモニタでは警告として
新しい書式を確認、みたいなことを言ってたので
スケッチ例のsimpleReciverを見て書き換えた

```
#include <IRremote.hpp>

void setup() {
Serial.begin(115200);
IrReceiver.begin(11,true);
}

void loop() {
if(IrReceiver.decode()){
  Serial.println(IrReceiver.decodedIRData.command,HEX);
}
IrReceiver.resume();
delay(100);
}
```
こうしたら、ボタンによって受信する情報がFFFFFFFFではなくなった。
備忘として
レガシーシステムのエンジニアが、モダンWeb開発に挑戦した話

## 私のエンジニアのキャリアについて

私はJavaを使用したレガシーシステムの開発経験しかなかった所からモダンWebの開発エンジニアへ移行するキャリアを手にしました。

この記事では、私のキャリアパスの転機となったConnecteteでの経験と3年目までのキャリアパスについて紹介しようと思います！

## 大学時代の就活

大学では法律政治学科を専攻し、21卒の就活生として営業職を志望していました。
しかし、50社の面接を受けましたが、全て不採用でした。

今だから分かる不採用の原因は、当時コロナウイルスによるパンデミックで希望する就職先は求人数が減っていたことと、私には学チカがなく、ハキハキとした話し方でのコミュニケーションが苦手という課題があったからだと思います。

## キャリア初期の不安

上述の課題を打開する作戦として、4年生の10月からPayPay導入店舗の新規開拓営業のアルバイトに挑戦しました。

アルバイトをしながら就活を続け、営業に挑戦したチャレンジ精神と身につけたコミュニケーション能力を評価して頂き、SIerにエンジニアとして内定をもらえ入社しました！

そこでは、コミュニケーション能力を活かして積極的にチーム新人の方に技術を教えたりして周りからの信頼を獲得し、技術のリードを任せてもらえました。

しかし、エンジニアとして2年目になるとき外の世界は技術が進歩しているのに私の現場は、
- 貸与端末がインターネットと接続されていない
- 手動デプロイ、手動テストをしていて非効率な開発であったこと
- モダンな技術に触れられないこと
- 上流工程やマネジメントの経験が欠けていること

といったレガシーな環境で自分の将来の選択肢を狭めてしまうと不安になりました。

## 交流会への参加

エンジニア2年目の10月頃から、上述の状況を打開するため、
「何か得られるかもしれない…」
と期待を胸にエンジニアの交流会へ積極的に参加し始めました。

結果としては、その中で知り合った方から、フロントエンドでTypeScript×React、バックエンドにFirebaseを使用した個人開発を手伝ってほしいと声をかけていただき、その方と一緒に個人開発の経験をすることができました。

## Connecteteへの転職

さらにその方の所属会社のリファラル採用でモダンな技術を使用した開発を得意としているConnecteteという会社に転職しました。

Connecteteでも、前職のリードエンジニアとしての経験と個人開発の経験で得たスキルを活かし、上流工程の経験やモダンWebの実務経験を積む機会を頂き、上流工程と技術面で成長を実感しています。

結果としては以下のような経験ができ、フロントエンドとバックエンド両方が対応出来るエンジニアに成長しました。

- 要件定義
- 基本設計
- テスト仕様書作成
- Next.jsでのフロントエンド実装
- Ruby on Railsでのバックエンド実装
- Node.jsでのバッチ実装

## モダンな技術を触りたい方向けにキャリアチェンジのアドバイス

個人開発で実際にモダンな技術に触れることが、転職や部署移動などでアサインしてもらえるチャンスを得るための鍵だと思います。

個人開発でモチベーションが続かない方は、一人で勉強せずエンジニアの交流会に行ってこんなアプリが作りたいと仲間を探すのも手だと思います。

きっと同じようにモチベーションに課題を感じているエンジニア仲間がいると思います！

## 最後に

今後も新たな挑戦を恐れず、成長し続けたいと思っています！

Connecteteはチャレンジ案件へのアサインや研修等、モダンWebエンジニアの育成に力を入れている会社だと思います！

もし私達の会社に興味を持っていただけましたらご応募お待ちしております！
↓HPリンク
https://connectete.com/
batファイルのpauseが効かない方へ（bat pause not working）

## 発端

このバッチファイルを実行すると何故かpauseが効かず勝手にDOS窓が閉じられてしまった。

```test.bat
npm test
pause
```

## 解決方法

こうしたら直った。

```test.bat
call npm test
pause
```

マジか… という感じ。
JXA で note のお気に入り作者の記事一覧を csv 形式で保存する

## きっかけ
自分の note の記事とスキされた数を一覧で取得したいと思ったのがきっかけ。
調べてみると note はAPIが提供されていて、JSON 形式で取得できることが分かった。
私はMacユーザなので、慣れている JXA (JavaScript for Automation) で作成した。JXAは Apple Script の JavaScript 版のようなもの。

## 汎用的にして、好きな作者の記事一覧を
最初は自分用だったが、 note のユーザーIDを入力して、お気に入りの作者の一覧を取得できるようにして、ソースを公開することにしました。
出力項目は
"タイトル","スキされた数","公開日","記事へのリンク"
です。

## ソースコード
備忘録も兼ねてソースを公開します。

``` javascript:NoteContent.scpt
// note.com から、好きな作者の記事一覧を csv 形式のファイルに出力します。
// 起動するとユーザーIDを聞いてきますので、NoteのユーザーIDを入力します。
// ファイル名は「ユーザーID_NoteContents.csv」で、デスクトップに出力されます。
// 内容は　"ニックネーム","ノート記事数","フォロー数","フォロワー数" と
//      "タイトル","スキされた数","公開日","記事へのリンク"　です。
//

var app = Application.currentApplication()
app.includeStandardAdditions = true

try {
    var res = app.displayDialog('出力するNoteのユーザーID', {
        defaultAnswer: 'YOUSER_ID'
    }).textReturned;
	} catch(e) {
	    throw new Error('ユーザーIDが取得できませんでした')
	}

const userID = res
const baseURL = '"https://note.com/api/v2/creators/' + userID

var URL = baseURL + '"'
var ans = app.doShellScript('curl -s ' + URL)

var jsonData = JSON.parse(ans)
var noteCount = jsonData.data.noteCount     // note 記事数

var contentsData = ''

// 作者情報　（不要なら記事情報まで削除）
contentsData += '"ニックネーム","ノート記事数","フォロー数","フォロワー数"\n'
contentsData += '"' + jsonData.data.nickname + '"'         // ニックネーム
contentsData += ',"' + noteCount + '"'                      // ノート記事数
contentsData += ',"' + jsonData.data.followingCount + '"'  // フォロー数
contentsData += ',"' + jsonData.data.followerCount + '"'   // フォロワー数
contentsData += ',\n"==============================="\n'

// 記事情報
contentsData += '"タイトル","スキされた数","公開日","記事へのリンク"\n'
for (let i = 1 ; i <= (noteCount / 6) + 1 ; i++) {
    URL = baseURL + '/contents?kind=note&page=' + i + '"'
    ans = app.doShellScript('curl -s ' + URL)
    jsonData = JSON.parse(ans)
    if (jsonData.data.contents == []) {
        app.displayDialog('no content')
     } else {
	     for (let j = 0 ; j < jsonData.data.contents.length ; j++) {
		     contentsData += '"' + jsonData.data.contents[j].name + '"'        // タイトル
			 contentsData += ',"' +jsonData.data.contents[j].likeCount + '"'   // スキ数
			 contentsData += ',"' + jsonData.data.contents[j].publishAt + '"'  // 公開日
			 //  記事へのリンク
			 contentsData += ',"https://note.com/' + userID + '/n/' + jsonData.data.contents[j].key + '"'
			 contentsData += '\n'
		 }
	 }    
}

path = app.pathTo("desktop",{from:"user domain"}) + "/" + userID + "_" + "NoteContents.csv"
try {
    f = app.openForAccess(path, {writePermission:true})
    app.setEof(f, {to:0})
    app.write(contentsData, {to:f, as:"text"})
} catch(e){
    console.log(e)
    app.displayAlert(e.toString())
} finally {
    app.closeAccess(f)
}

app.displayDialog('投稿記事数：' + noteCount + '件　出力完了しました。')

```
とりあえず動いたというレベルで、恥ずかしいコードですが公開しますので、ご意見・ご指摘をいただければ喜びます。
私の記事の問題点【振り返り】

# はじめに
体調不良でダウン中です。
勉強ははかどらないけど、記事は書いていきたい！
ということで、最近感じていたアウトプット（記事）の問題点を考えていこうと思います。
### 現状の記事フォーマット
```
はじめに
問題
解決方法
おわりに
参考
```
あるいは、「メモず」シリーズ
```
はじめに
メモず
おわりに
```
# 問題
## 「はじめに」 = 「問題」
たいてい、行き詰まったことが発端で記事を書いているので、
「はじめに」で書くことと、「問題」で書くことが被ります。
もしくは、後述するように「日記・ユーチューバーの挨拶」のような文になり、
「場違い感」を感じます。
## 「はじめに、おわりに」の日記感
「はじめに、おわりに」で書くことは、おおむね日記のようなものになりがちです。
例えば、
>体調不良でダウン中です。
>勉強ははかどらないけど、記事は書いていきたい！

これをどう思うでしょうか？
例えば、技術記事にふさわしいのか

**近況報告なんて興味あるだろうか。技術記事を読みに来たのに、異物感があるのでは・・・？**
**「おわりに」に関しても、「まとめ」以外のことを書くと、やはり異物感があるのでは・・・？**

と思います。
## 問題→解決方法、だと冗長になる  
「何につまって、どうしたのか」という「ストーリー」を書くことになります。
ぶっちゃけ、**結論・解決方法だけ書いた方が簡潔だよなあ・・・** と感じます。
ただし、「読み手の解釈の幅をある程度狭める」「読み手と状況を共有しながら話を進められる」
というメリットはあるかもしれません。
また、記事の文字数をある程度以上にする効果も多大にあると思います。
## 「質」か「量」か
基本的に、「質」と「量」は反比例する。
「毎日1本、計100本」を目標にしているため、基本的には「量」重視なのですが、
ここで示すように、「質」の低さは感じます。
**「まずは量を書くことで学び、その中で自分のスタイルも見えてくる」**
というのが私のスタンスであり、その点はぶれないのですが、
とはいえ解決はしていきたい。
**より低い負荷で、より高い質を** 目指していきたいです。
## 「参考」いらない
調べもの・解決方法はChatGPTが大部分を占めるため、「参考」という項目を使いません。
また、もしその他の参考になるサイトがあっても、記事内に直接[このような形で]()表記しており、
やはり「参考」という項目は使いません。

ただ、「参考」を書くことで「記事っぽく」なる事実があります。
ChatGPTとの会話歴でもおいとこうかしら、いやいや、ほんとに飛び飛びでいろんなこと聞いてるしなあ・・・・・・わざわざ見る人もいないでしょう。
## 画像の使用
私は普段、画像を使用しません。理由は以下の2つ
- 記事エディタ・集約所として利用しているObsidianの容量を増やしたくない
- 作る / 探す手間が面倒
- 何に画像を使用して、何に使用しないかの判断が面倒

一方で、
- あったら伝わりやすいよなあ・・・

というのも感じます。うーん。
これも「質」「量」問題につながりますね。
画像を使用することは「質」を高めるが、「量」が作れなくなる。
・・・とはいえ、手間を面倒がっているだけな気もします。
わかりやすくなるなら取り入れていこう
## 何を伝えたいのかはっきりしない
今回のような、「つながりのない・つながりの薄い」トピックを複数集めてひとつの記事にすることが多く、
よほど暇なら、あるいは身近な人なら読んでくれるかもしれないが、「継続して読みたい」内容になっていないように感じます。

具体的に「〇〇入門レベル・・・これがわかればＯＫ！」みたいな内容にすれば良いのかなあ・・・
でも、RUNTEQのカリキュラムには触れられないし、
一般レベルを策定するとこから始めるのは難しいしなあ・・・

Railsガイドを読む！〇〇編、ならいいのかなあ
でも、**「トピックを網羅的に扱うこと = 疲れるし、学びも少ない（読んでわかることも多いため）」** 
問題があるんですよね。

# 解決方法
## 「はじめに・おわりに、参考」は必須ではない
今までもそうだったのですが、改めて言葉にして認識しようと思います。
正確には、「問題」を書くときは「はじめに」と統合してよさそう、ということです。
「おわりに」は、気分で書いていきます。とりあえず。

## ChatGPTにページを要約してもらい、そこから気になるトピックを深堀する  
要約（ある程度、トピックについて網羅的な内容）の共有により、
「これがわかってるならOK！」という価値を提供します。

「今までのやり方」+少しの負荷、でできそうです。試してみます。
## ChatGPTに「各トピックの要約」と、「各トピックへのリンク」を作ってもらう
「メモの集合」も、少しマシになるのでは？という期待があります。
## 画像を使用する
特に、「部分スクショ」はWindowsならショートカットでできるお手軽なものなので、使っていきます。

# 終わりに
いつものごとくとりとめのない記事ですが、お読みいただきありがとうございました。
いったんの対策は考え付いたので、今後試して、また記事にしようと思います。
Qiita Advent Calendar 2023 完走賞のノベルティセットが届きました！

## はじめに
　Qiita Advent Calendar 2023 完走賞のノベルティセットが２月上旬頃に届いたので、報告したいと思います。

## 実物を見た感想
　QiitanのぬいぐるみとQiitaのオリジナルTシャツ１枚とピンバッジが届きました。ぬいぐるみは、表面の触り心地がとてもよかったです。また、Tシャツは、思っていたより生地が分厚くてしっかりしていました。
![IMG_2402.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2942430/464d5b54-70bc-cb34-3c70-d8308459edf0.jpeg)

## おわりに
　Qiita Advent Calendar 2023で投稿した記事は、以下の記事でまとめています。今年（2024年）のAdvent Calendarも完走賞を目指したいと思います。

https://qiita.com/cyber-yuito723/items/baeb4e79d44c53096244
setodaNote CTF Logger を scapy 無しで解く


キーボードをつないだ USB の通信をキャプチャしたもの

scapyをinstallできない環境下でもこの手の問題が解けるように手持ちのpythonは封じる

まず、いつものように Wireshark に表示するカラムを追加する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/3cab68e9-1509-0680-6ca4-c213488fa6cc.png)

必要なデータだけコピペ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/2273ae8b-d2cf-cb70-e0fe-7699749f7f3c.png)

```:key.txt
0200000000000000
0200120000000000
0200000000000000
0000000000000000
0000110000000000
0000000000000000
0000080000000000
0000000000000000
00002c0000000000
（中略）
0000000000000000
00000c0000000000
0000000000000000
0000110000000000
0000000000000000
0000080000000000
0000000000000000
0000370000000000
0000000000000000
0000280000000000
0000000000000000
```

これを解く python を作り、動かす。

```
>python usb_pcap2.py key.txt
One popular bbut unverified explanatioon for the QWERTY arrangement is that it wwas designed to reduce the likelihood of flag{QWE_keyb0ard_RTY} internal clashhing of typebars by placing commonly ussed combinatiioons of letters farther froom each oher inside the machine.
```

flag{QWE_keyb0ard_RTY}
Google日本語入力ででシフト+スペースを使って日本語/英語を切り替える方法

Google日本語入力で日本語と英語の切り替えを自由に行う方法について、明確なガイドが見つからないため、この記事を記録として残します。

## 入力モードの基本

- **日本語入力モード**: アルファベットをタイプすると、IMEがこれを日本語文字に自動変換します
- **英語（直接入力）モード**: IMEが無効になり、タイプされたアルファベットはテキストとしてそのまま使用されます。このモードを俗に「直接入力」と呼びます

## シフト+スペースによる入力モードの切り替え

この便利なショートカットを使用することで、以下のように入力モードを簡単に切り替えることができます。

- **英語から日本語へ**: 「直接入力」モードのShift Spaceで「IMEの有効化」
- **日本語から英語へ**: 「直接入力」以外の既存のShift Space全てに「IMEの無効化」
How To Grow Strawberries – In Just 3 Easy Step

How To Grow Strawberries – In Just 3 Easy Step 
https://thegardenfarming.com/
Summer wouldn’t be complete without the delightful presence of strawberries. While supermarkets offer them year-round, the joy of home-grown fruit during the season is unparalleled. Strawberries thrive in various containers like pots, window boxes, hanging baskets, growing bags, and specialized planters, making them suitable for small gardens, balconies, and even windowsills. Growing strawberries can be a delightful activity, especially for children. so, let’s know how to grow strawberries beautifully.

Whether purchased as pot-grown plants from a garden center in summer or as mail-order runners in spring or autumn, strawberries come in different varieties with varying harvest times – early, mid-, and late-season. Opting for a mix of varieties allows for a prolonged harvesting season.
【Ruby on Rails】rails g コマンドが反応しないことに関して

現在スクールで学んでいます。
Ruby on Rails学習中に新たにアプリ作成しようとした際に、つまづいたことを備忘録としてこちらで共有します。追記や修正等ありましたら、ご指摘いただけるとありがたいです。



### 環境
・MacBookAir 13インチ M1(2020)
・OS：Sonoma 14.3
・メモリ：16GB
・Rails： version 6.1.7.6




### 概要
　Ruby on RailではControllerやModelを新規で作成する際に、コマンドから簡単に作成することが出来ます。その際にrails g または、rails generateというコマンドをターミナル上で実行します。




### 状況

```zsh 
$ rails g model post title:string content:text
Running via Spring preloader in process 82269
      invoke  active_record
      create    db/migrate/20240208095330_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
```

```create    db/migrate/20240208095330_create_posts.rb``` 
```create    app/models/post.rb```
とターミナル上では出ているのに、実際にVScodeを開いてみると、ファイルが見当たらない・・・
dbディレクトリにもmigrateファイル見当たらず。
（すみません、VScodeは写真撮り忘れました）




### やったこと
・ 再度ターミナルのログの確認、DBが作成されているか確認しました。
→ ```$ rails db:create``` も ```$ rails db:migrate```も完了している。
・ ```$ bundle install``` もしているか確認しました。
・ ```$ yarn add @babel/plugin-proposal-private-methods``` も完了。
・Railsのバージョンやgemも確認。
・スクールのメンターに質問する。




### 原因
**gems/ のファイルのパッケージ「spring」**　が実行し続けているのが原因。
つまり他のアプリ制作で立ち上げたRailsサーバーを```exit```していなかったのが原因。




### 対処法
```zsh
$ spring status
Spring is running:
```
まだ **「spring」** が実行し続けていました。

```zsh
$ spring stop
Spring stopped.
```
この状態で再度、下記を実行。

```zsh
$ rails g model post title:string content:text
Running via Spring preloader in process 82269
      invoke  active_record
      create    db/migrate/20240208095330_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
```

出てきた内容は同じでしたが、ファイルは作成できていました。




### 最後に
おそらく　```$rails s```　で他のサーバーも立ち上げたままにして、アプリ制作に移ったため、なかなかターミナルの内容が反映されない状況だったと思います。都度サーバーは```exit```する大切さを実感しました。参考文献、そしてメンターさんありがとうございました。




### 参考文献
https://dara-blog.com/about-rails-error05
いつか使えるかも

# コード
```PHP

echo div('class="my-div"', 'This is my div content.');


$this->load->library('javascript/jquery');
$this->jquery->event('#myButton','click', '$("#myElement").hide();');



```

# 結果
```javascript


```
イベントは、blur、change、click、dblclick、error、focus、hover、keydown、keyup、load、mousedown、mouseup、mouseover、mouseup、resize、scroll、またはunloadのいずれかです。
element_pathは、有効なjQueryセレクターです。jQueryのユニークなセレクター構文のため、これは通常、要素のidまたはCSSセレクターです。例えば、#notice_areaは<div id="notice_area">に影響を与え、#content a.noticeはidがcontentのdiv内のすべてのnoticeクラスを持つアンカーに影響を与えます。
code_to_run()は、自分で書いたスクリプト、または下記のjQueryライブラリからのエフェクトなどのアクションです。


https://codeigniter.jp/user_guide/3/libraries/javascript.html#hide-show







関数内でasyncキーワードを使用し、awaitを使って非同期処理が完了するまで待ちます。


```javascript
async function fetchData() {
    const data = await doAjax('deck_tool_get_type_list', {'select_id': select_id});
    window.aaa = data.send_data['bbb'];
    console.log(window.aaa);
}

fetchData();

async function fetchData() {
    const data = await doAjax('deck_tool_get_type_list', {'select_id': select_id});
    window.aaa = data.send_data['bbb'];
    console.log(window.aaa);
}

fetchData();

```
Go言語でLINE botを使って画像を送信してみた

---
<font color="green">Go</font>言語でLINE botを使って画像を送信してみた
---

**imagin**

考えるな、感じろ。

感じるな、動け。

動くな、手を上げろ。

強盗だ！

何？理解できない？

考えるな、感じろ。

......。

**目次**
- [1. LINE botとは](#1-line-botとは)
- [2. コード例](#2-コード例)
- [3. おわりに](#3-おわりに)


## 1. LINE botとは

　LINE botは、LINE Messaging APIを使用してLINEプラットフォーム上で動作する自動応答プログラムです。
 
　ユーザーからのメッセージに対して自動で返信したり、特定のイベントに基づいて情報を提供することができます。
 
　ビジネスでの顧客サポートや、エンターテイメント、教育目的での情報提供など、幅広い用途に使用されています。

## 2. コード例


 以下に簡単なコード例を示します。

 `YOUR_SECRET_TOKEN`
 `YOUR_ACCESS_TOKEN`
 `toUserID`
 `IMAGE_URL`

 は適切に設定してください。
 
```go
func sendMessageToLineBot(message string) {
	// LINE BOTのチャネルシークレットとアクセストークン
	channelSecret := "YOUR_SECRET_TOKEN"
	channelToken := "YOUR_ACCESS_TOKEN"

	// LINE BOTクライアントの初期化
	bot, err := linebot.New(channelSecret, channelToken)
	if err != nil {
		fmt.Println("LINE BOTの初期化に失敗:", err)
		return
	}

	// ここにメッセージを送信するユーザーのIDを設定
	toUserID := "SEND_USER" // 送信先のユーザーID

	// メッセージの送信
	if _, err := bot.PushMessage(toUserID, linebot.NewTextMessage(message)).Do(); err != nil {
		fmt.Println("メッセージの送信に失敗:", err)
	} else {
		fmt.Println("メッセージを送信しました")
	}

	var imageURL string = "IMAGE_URL"
	// 画像メッセージを送信
	if imageURL != "" ![IMG_8471.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493200/bca581b3-af5a-6f4e-7c7b-a5a5b77799b8.png)
{
		if _, err := bot.PushMessage(toUserID, linebot.NewImageMessage(imageURL, imageURL)).Do(); err != nil {
			fmt.Println("Error sending image message:", err)
		}
	}
}
```

　そうすると下のような画像が届きます。

![IMG_8471.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493200/a4232c40-9536-81c5-942e-8ac205506d50.png)



## 3. おわりに

　文章はもちろん、画像や音声、位置情報も送れるらしいので、色々と遊んでみたいです。