OmniAICreator/Qiita-1.07M huggingface dataset:
ViteでJavaScriptのデバッグを、vscodeのデバッグ機能で行いたい場合の設定

# 概要
Viteでvscodeのデバッグ機能が、成功した設定は以下となる。
しかし、この方法は`sourcemap`を読み込まなければならない。
つまり、**本番用**の`npm run build` を実行して、`soucemap`ファイルを、作成した時のみ有効なデバッグ方法である。
`npm run dev`でデバッグするなら、`debugger`構文の方が有効である。
# 環境
Laravel10
Vue3
Vite4.3.9
Docker Desktop 4.20
wsl2
# 各種の設定
````routes/web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});
````
````resources/js/app.js
import "/resources/js/bootstrap.js";

const greeting = "Hello World";

console.log(greeting);
````
````vite.config.js
import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";

export default defineConfig({
    plugins: [
        laravel({
            input: ["resources/css/app.css", "resources/js/app.js"],
            refresh: true,
        }),
    ],
    server: {
        host: true,
        hmr: {
            host: "localhost",
        },
    },
    build: {
        sourcemap: true,
    },
});
````
````.vscode/launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch chrome against localhost",
            "url": "http://localhost:80",
            "webRoot": "${workspaceFolder}/resources"
        }
    ]
}
````
````resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>

        ...        

        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>
    <body class="antialiased">
        
        ...

    </body>
</html>
````
# デバッグ方法
1. `npm run build` を実行して、`sourcemap`ファイルを作成する。
![debug01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/968572/65cf5c20-6f88-71e5-0e4f-ad6cbb9c5c9f.png)
2. `JavaScript`ファイルのどこでもいいので、ブレークポイントを設定する。
![debug02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/968572/257fd0a9-a7e9-be6c-0b90-b7537368f77f.png)
3. `F5`を押してデバッグを実行し、サイドバーに変数の値が表示されれば成功。
![debug03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/968572/9ead15f4-a7fc-1d75-1cd1-0182fabaac7d.png)
# 参考
https://github.com/vitejs/vite/discussions/4065
https://ja.vitejs.dev/config/build-options.html
WebGPU Native 踏んだエラーとその対処のメモ

## 概要
WebGPU Native開発で踏んだエラーとその対処をメモしています
## エラーと対処
### オフスクリーンレンダリング用のレンダーパス
* エラー内容
  * オフスクリーンレンダリング用のレンダーパスの`wgpuRenderPassEncoderEnd` でメモリアクセス違反を起こす
* 原因と対処
  * カラーバッファとデプスバッファのサイズが違った
  *  レンダーパスに使用するTextureViewのフォーマットは`WGPUTextureFormat_BGRA8Unorm` のみ対応していた
     * RGBAの順番じゃないことに要注意
### SSBOの使用
* エラー内容
    * Vertex ShaderやFragment ShaderでSSBOを使用すると `MissingFeatures(VERTEX_WRITABLE_STORAGE)` エラーで落ちる
* 原因と対処
    * `WGPUBindGroupLayoutEntry.buffer.type`を`WGPUBufferBindingType_ReadOnlyStorage`にする
    * nagaでGLSLをWGSLにするとSSBOが`read_write`になるので`read`に変更する
        ```
        var<storage, read> rw_TBO: TestBufferObject;
        ```
     * 何かnagaのオプションがあるかも？
         * GLSLで`readonly`を付けてやればWGSLでもそのように変換してくれるとのこと
             * https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object#:~:text=this%20wherever%20possible.-,readonly,-Normally%2C%20the%20compiler
            ```
            readonly layout(std430, binding = 1) buffer TestBufferObject
            {
                TestData data[];
            } TBO;
            ```
[Matt Pocock] Beginner's TypeScript

![Screenshot 2023-07-08 at 9.24.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/1b32ad01-1508-5b8a-565c-2931f409843b.png)

なかなかのボリュームがタダ。有料コースはなかなかの値段。

- ビデオで解説
- 実際に動く環境

https://www.totaltypescript.com/

https://www.youtube.com/@mattpocockuk

https://www.totaltypescript.com/tutorials/beginners-typescript
パソコン受験ができないIT系の資格・・・？

以下の記事を見つけました

https://xtech.nikkei.com/atcl/nxt/column/18/00138/062901320/

率直にまだパソコン受験できなかったんだという話。

字が汚い私としてはパソコン受験ができるようにしてほしい・・・。
エンジニア6年目でたどり着いたデータサイエンティストへの道のり

## はじめに

はじめまして。
マルマウンテンです。
現在、データサイエンティストとしてデータ収集のアプリやアンケート収集の解析などを行っております。
データサイエンティストとして本格的にジョブを始めるのに２回ほど転職しました。
本投稿では、その道のりについてや身につけた技術を記載します。

また、私以外のデータサイエンティストの先輩方とは当てはまらないことも多いと思います。
「へー、こんなキャリアもあるんだ。」と理解していただければ幸いです。


## 1社目でのキャリア
プリセールスとして入社しました。
なぜプリセールスかというと、ビジネス力を身につけるためです。
あとは、浅く広く技術を学びたかったこともあります。
展示会へ赴き、さまざまな会社と交流をすることもでき楽しかったです。
そのかわり苦労もありました。
- エンジニアの人と一緒に開発したいという思いが強くなる
- データサイエンスについて社内交流がない
- プライベートの時間を勉強する時間にたくさん割り当てる必要がある

苦労をプラスへ変換するために、積極的な行動をしてきました。
-  エンジニアの人が受講する勉強会やセミナーに混ざる
    プリセールスとして技術力を高めて受注につなげたいと意見を出して、参加しました。
- データサイエンスの交流はコンペで黙々と参加
    Kaggleなどで前処理の方法や可視化についてのノウハウを学べました。
- 自己投資として割り切って、資格や本を買って学ぶ
    応用情報技術者試験や統計検定に申し込み、モチベーションを保ちながら勉強してました。

一番オススメなのは、若いのに知識豊富で色々学ばせてみようと社内の人に思ってもらうことです。
そうすることで、どんどんセミナー参加やシステムのデモなどをやらせてもらえるようになり、自分のスキルとして定着していきます。
でしゃばってアピールするのも大切です。その分、結果を出すことが必要になってくるためアウトプットも大事です。
しかし、展示会やセミナーなどで社外の環境を見ると、転職してスキルを上げたいなと思ってしまいました。
そこで、スキルアップのために専門性を身につけたいと思い、研究職へ転職しました。

## 2社目でのキャリア
研究職として入社しました。
専門的な能力を身につけるためです。
生成AIをはじめとして、統計学や画像処理も学ぶことができました。
学会への参加や、英語の論文をたくさん読む機会もあり英語の能力も高めることができました。
研究職の仕事柄、めちゃくちゃ頭のいい人たちと一緒に仕事ができることもあり、学ぶことが多くありました。
特許のことや、解析に必要なデータについても今まで自分が知らなかった分野について教えてもらうことができ、恩返しができるように解析やデータ収集アプリの開発に専念することができました。
研究職の皆さんと共に技術力を高めることができたこともあり、非常に有意義な時間でしたが、
次のキャリアとしてはビジネスにより一層関わっていきたいと思い、キャリアアップすることに決めました。


## 3社目でのキャリア
データサイエンティストとして入社しました。
リモートワークと出社の交互でデータ解析を中心に行なっております。
データサイエンティストはさまざまな部署の人たちと関わり、問題を解決することもあり、出社することもあります。
出社して実際に体験したりモノを見たりして理解を深めていくことも大切です。
入社先によってはWebサービスをメインにしている場合はフルリモートでもデータサイエンスを行うことはできると思います。
私もキャリアアップとしてフルリモートでデータサイエンティストとして活躍できるようにスキル向上をしていきたいです。
今まで培ったプリセールスとしての能力をプロジェクトメンバーとのコミュニケーションで活かすこともでき、ビジネスの指標であるKPIなどに関わることもできています。
統計的仮説検定の説明などもすることもあり、教育役としても業務を行なっております。

## まとめ
エンジニア６年目で紆余曲折ありましたが、データサイエンティストとして必要なビジネス力、エンジニア力、データ解析力を着実に身につけることができています。
しかし、データサイエンスに関しても日進月歩のため引き続き学んでいく必要があります。
どんどん市場価値を高めて、キャリアアップを目指しています。
「俺たちの冒険はこれからだ」って感じです。
[ChatGPTに聞いた]SameSite=NoneでもSSLを使用するとCSRFが防げるのですか？

https://chat.openai.com/share/0bd5fd35-f43a-406b-abbc-b6b85afb4ef9

- 結論
    - CSRFトークンを仕込めば大丈夫っぽい
    - そういえばRailsでデフォルトでその仕組みあったよな。
    - 他のフレームワークも同じ仕組みあるのか？
Raspberry Pi 4で YOLOv5 v7.0を動かす

* Raspberry Pi 4 Model B/4GB
* logicool C270N
* micro SDXC 64GB
* 2023-05-03-raspios-bullseye-arm64.img

## 日付・時刻の設定
sudo date -s "YYYY/MM/DD hh:mm/ss"

## 各種Pythonパッケージのインストール
sudo pip3 install gitpython==3.1.30
sudo apt remove python3-numpy
sudo pip3 install matplotlib==3.6.0
sudo pip3 install opencv-python==4.7.0.68
sudo pip3 install pyyaml==6.0
sudo pip3 install torch==1.13.1
sudo pip3 install torchvision==0.14.0
sudo pip3 install tqdm==4.64.0
sudo pip3 install pandas==1.5.0
sudo pip3 install seaborn==0.12.0
sudo pip3 install ultralytics

## YOLOv5 v7.0のインストール
git clone https://github.com/ultralytics/yolov5.git
cd yolov5/

```:requirements.txt（全行、無効にしておきます。）
# Base ------------------------------------------------------------------------
# gitpython>=3.1.30
# matplotlib>=3.3

途中略

# albumentations>=1.0.3
# pycocotools>=2.0.6  # COCO mAP
```

## YOLOv5の動作確認
python3 detect.py --source 0 --imgsz=256 --nosave

:::note info
Raspberry Pi 4 Model B/4GB, RasPi OS(64-bit)：1 frame：0.329s（3.0fps）
:::
C#を使ってみようシリーズ　１．C#の基本


# c＃って何
>"C#（シーシャープ）は、Microsoft社が開発した、汎用のマルチパラダイムプログラミング言語である。C#は、Javaに似た構文を持ち、C++に比べて扱いやすく、プログラムの記述量も少なくて済む。また、C#は、.NET Framework上で動作することを前提として開発された言語であり、WindowsアプリケーションやWebアプリケーションの開発に適している。"

という風に[wikipedia先生](https://ja.wikipedia.org/wiki/C_Sharp)が言っていたのでアプリを作ってみようと思う。

# 基本
とその前にバージョンがあるらしいので確認。
`C:\Windows\Microsoft.NET`内の`Framework`や`Framework64`
の中にあるファイルがバージョンかな。
その中のcsc.exeがコンパイルする奴らしい
ただ、そのまま実行してもコンパイルできないから
cmd(コマンドプロンプト)で呼び出さないといけないらしい
それもbatファイルで。ちなみにbatファイルっていうのは、
簡単に作れるアプリみたいなファイル。
### batファイルを書こう
ってことで書いていきますか
```bat:c#4.0.30319.bat
@echo off
set PARAM=.cs

for /f "usebackq" %%A in (`dir /b ^| find "%PARAM%"`) do set FILE=%%A

echo %FILE%
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe %FILE%
pause

```
まあこんなもんかな
結構前に作ったから忘れたけど確か
１．同じ階層にある.csのファイルを取得してparamに入れる
２．paramをfireに入れる
３．C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exeを呼び出して、
　　コンパイルするファイルをfireにする
４．pauseコマンドでエラーを確認できるようにする
　　（batファイルは処理が終わるとすぐに消えるから）

ちなみに.csっていうのがc#の拡張子です。
拡張子が出てるかは、アプリの最後に.exeとかがついてたり
メモ帳のファイルの最後に.txtとかがついていればok
出てないと作るうえで少し不便だから出したほうがいいと思う
出し方は
１．ファイルエクスプローラーを開く
２．左上のファイルからフォルダと検索のオプションを押す
３．表示タブへ
４．登録されている拡張子を表示しないのチェックを外す
５．適用
で出来るはず

それでは、次回から軽くc#のコードが書けるかな
なにか間違いやわからないところなどがございましたら
修正リクエストやコメントでご連絡ください。
Rustのクロージャで再帰関数を書きたい

Rustにおけるクロージャ(closure)とは、いわゆる無名関数のことです

## structを使用する

クロージャで直接再帰を書く方法は現在のところ無いようです。[参考](https://stackoverflow.com/questions/16946888/is-it-possible-to-make-a-recursive-closure-in-rust#:~:text=As%20of%20Rust%201.62%20(July%202022)%2C%20there%27s%20still%20no%20direct%20way%20to%20recurse%20in%20a%20closure.)

そこで関数を保持するstructを用います。なるほど。（[参考　<- a great example!](https://stackoverflow.com/questions/16946888/is-it-possible-to-make-a-recursive-closure-in-rust)）

```rust
fn main() {
    struct Fact<'s> {
        f: &'s dyn Fn(&Fact, u32) -> u32,
    }
    let fact = Fact {
        f: &|fact, x| if x == 0 { 1 } else { x * (fact.f)(fact, x - 1) },
    };

    println!("{}", (fact.f)(&fact, 5));
}
```

## 再帰クロージャを別の関数に渡したいとき

無名クロージャを引数として別の関数に渡したいときは**Rc**と**RefCell**を使うと書けます

```rust
use std::rc::Rc;
use std::cell::RefCell;

struct Fact<'s> {
    f: &'s dyn Fn(&Fact, u32) -> u32,
}

fn main() {
    let f = Rc::new(RefCell::new(None));
    let g = f.clone();

    *g.borrow_mut() = Some(Fact {
        f: &|fact, x| if x == 0 { 1 } else { x * (fact.f)(fact, x - 1) },
    });

    some_fn(f.borrow().as_ref().unwrap());
}

fn some_fn(f: &Fact) {
    println!("{}", (f.f)(f, 5));
}
```

structが関数の外に出てしまいましたが、割とすっきり書けました。
[Chrome拡張]　ChatWork 全ての画像とビデオをサムネイル表示させる

「ChatWork」でサムネイルが表示されない画像とビデオのサムネイルを
表示させるChrome拡張をご紹介します。

今回ご紹介するChrome拡張はこれです。
[Chatwork サムネイル表示ツール](https://chrome.google.com/webstore/detail/chatwork-%E3%82%B5%E3%83%A0%E3%83%8D%E3%82%A4%E3%83%AB%E8%A1%A8%E7%A4%BA%E3%83%84%E3%83%BC%E3%83%AB/pngkjeelbmabohjchepdpiihpdkhlpjf)

2021年2月に公開した拡張ですが、
1年ぶりに見てみると動かなくなっていたので修正しました。。。

## 「Chatwork サムネイル表示ツール」とは？
Chatworkメッセージでサムネイル画像が表示されるのは、
「ファイル容量：10MB以内、画像の大きさ：縦x横x3が1048万ピクセル 以内」
と制限があります。

<font color="red">この拡張を使うことで全ての画像とビデオがサムネイルに表示されるようになります。</font>
また、この拡張によって表示されたサムネイルは赤枠で表示されます。

なお、対応しているビデオの拡張子は以下になります。
「.swf、.mpg、.mpeg、.mp4、.webm、.ogv、.mov、.qt、.avi」


<font color="blue">もし気に入っていただけたのなら、拡張機能の評価をもらえれば励みになります。。</font>

## 使い方
まずは、[ここ](https://chrome.google.com/webstore/detail/chatwork-%E3%82%B5%E3%83%A0%E3%83%8D%E3%82%A4%E3%83%AB%E8%A1%A8%E7%A4%BA%E3%83%84%E3%83%BC%E3%83%AB/pngkjeelbmabohjchepdpiihpdkhlpjf)からChrome拡張をインストールして下さい。

インストール後、お使いのChatWorkの***ページを更新***して下さい。
(ページを更新しないとインストールしたばかりのChrome拡張が使えません。)

そうすると。。。。

本来なら表示されない画像がサムネイルが表示されました。
<img widh="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/bac572c6-2690-9461-a32d-ed1ce9eb9f85.png">
ビデオもこの通り、サムネイルが表示されました。再生もできます。
<img widh="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/5d61c558-e09d-f251-4ba5-6380deb4a929.png">
USB2Dynamixelを使ってMX-106とRX-28を使う。

# はじめに

研究室に転がっていた2種類のDymanixel, MX-106とRX-28を使って遊んでみよう。

## 実行環境
Ubuntu22.04

# ハードウェア

以下のように配線します。

![dynamixel (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986389/74599adc-b5f8-403a-27be-0399b37c0c9a.jpeg)

TTL, RS485, RS232からRS485を選択します。

# DYNAMIXEL Wizard 2.0

Dynamixelの設定の為にDYNAMIXEL Wizard 2.0をインストールします。`<user_name>`はユーザ名に変更してください。[こちらのページからソフトウェアをダウンロードしてください。](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_wizard2/#introduction)

```bash
$ sudo chmod 775 DynamixelWizard2Setup_x64
$ ./DynamixelWizard2Setup_x64
$ sudo usermod -aG dialout <user_name>
```

インストールが終了したら再起動してください。

57600bpsで検索してみましょう。

# DYNAMISEL SDK

ではPythonで動かしてみましょう。[こちらのGitHubからもってきます。](https://github.com/ROBOTIS-GIT/DynamixelSDK)

```bash
$ git clone https://github.com/ROBOTIS-GIT/DynamixelSDK.git
$ cd DynamixelSDK/python
$ sudo apt install python3-setuptools -y
$ sudo python3 setup.py install
```

これでセットアップは完了です。`python/tests/protocol*_0/read_write.py`を使ってDynamixelを動かしてみましょう。該当するプロトコルを選んでください。MX-106は1, 2どちらも使えますが、RX-28はプロトコル1しか使えません。`DXL_ID`をDynamixelのIDに変更してください。今回はMX-106はプロトコル2で動かします。定数を以下のように変更してください。

```python:RX-28について protocol1_0/read_write.py
52 ADDR_MX_TORQUE_ENABLE      = 24
53 ADDR_MX_GOAL_POSITION      = 30
54 ADDR_MX_PRESENT_POSITION   = 36

67 DXL_MINIMUM_POSITION_VALUE  = 0
68 DXL_MAXIMUM_POSITION_VALUE  = 1023
```

```python:MX-106について protocol2_0/read_write.py
57 # MY_DXL = 'X_SERIES'
58 MY_DXL = 'MX_SERIES'
```

---

参考サイト

[RX-28](https://emanual.robotis.com/docs/en/dxl/rx/rx-28/)  
[MX-106](https://emanual.robotis.com/docs/en/dxl/mx/mx-106/)  
[DYNAMIXEL Wizard 2.0](https://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_wizard2/)
半加算器と全加算器

### 加算器
加算器、二進数を加算を行う回路。半加算器と全加算器がある。
#### 半加算器
半加算器は、二つの二進数を加算し、同桁の値（S）を桁上がり（C）を出力する加算器。上位桁への桁上がりのみ考慮した加算器
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/3a57ee5f-d0a0-9da6-0a9e-939d57907771.png)
半加算器は，排他的論理和と論理積の組合せで実現しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/20c4ed60-9f70-c756-54c1-8f7a52e3435f.png)
全加算器
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3293109/5d5d92e7-73fa-fa27-ee62-bebc8f50b1e5.png)
【備忘録】今更MySQLのインストールで詰まってしまった【Initializing database】

# 1.概要
デスクトップPCを買い替えたのでMySQLをインストールしようとしたところ、何回やってもうまくいかない・・・

ネットのどの記事を見てもアンインストールして再インストールで直った報告ばかり。深夜の眠たい時間に数時間沼ってしまいました。
二度とこの悲劇を起こさないためにも備忘録を書き残しておきます。

# 2.原因
とにかく「Initializing database」の実行中にエラーが発生する。
エラー発生時のログを見るとどうやら文字化けしているようだ。

```
Starting process with command: C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld.exe --defaults-file="C:\ProgramData\MySQL\MySQL Server 8.0\my.ini" --console --initialize-insecure=on --lower-case-table-names=1...
C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld.exe (mysqld 8.0.33) initializing of server in progress as process 6768
InnoDB initialization has started.
InnoDB initialization has ended.
mysqld: Error on delete of '.\髫・ｼ魯PC-bin.index' (OS errno 42 - Illegal byte sequence)
```

しかし文字化けの原因がわからない。どこかで日本語文字が使われているのだろうと推測しても、パスはデフォルト「C:\ProgramData\MySQL\MySQL Server 8.0」なのでどこにも日本語なんて使われていない。

そこでInitializing database実行時に参照している「my.ini」を確認。

すると125行目あたりに原因となる記載があった
```
general_log_file="【日本語のPC名】.log"
```

これでした。

PCのセットアップ時に何も考えずPCに日本語で名前をつけていたのをすっかり忘れていました。そしてこのせいで毎回Initializing databaseの実行に失敗していたのでした。

# 3.解決
PCの名前の変更後、MySQLのアンインストール→インストールで無事完了できました。

PCの名前の変更はwin11だと「システム」→「名前の変更」で簡単に変えられます。
皆さんも沼にはまってしまう前にPC名に日本語をつけるのはやめときましょう。本当に初心者丸出しのミスでした。
【乗り遅れないで！】学習なしで画像を任意のクラスに分類できるAI

# 学習なしで、なんでも分類できる

https://github.com/salesforce/LAVIS

このモデルを使えば学習なし分類できます。
過去には画像を分類する場合、分類したいクラスを設定して、クラスごとの画像を集めてデータセットを作って学習して。。。という作業が必要な時代がありましたが、必要ありません。
また、クラスの特徴が顕著でない微妙な画像に関しても、どのクラスが一番近いか分類できます。

画像とテキストをemmbeddingとして扱うモデルを使います。
emmbedingにしてしまえば、差分を計算するだけでどのクラスに一番似ているかわかるので、任意のクラスに分類できるという仕組みです。

# 手順

##### インストール

```shell
pip install salesforce-lavis
```

##### モデルの初期化

```python
import torch
from PIL import Image

from lavis.models import load_model_and_preprocess

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model, vis_processors, _ = load_model_and_preprocess("blip_feature_extractor", model_type="base", is_eval=True, device=device)
```

##### 画像読み込み

```python
raw_image = Image.open("sample_image.jpg").convert("RGB")
display(raw_image)
image = vis_processors["eval"](raw_image).unsqueeze(0).to(device)
```

![pexels-ömer-çeti̇n-16697135.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/4c705b0b-1f2f-52b1-ce3d-a99aafb99847.jpeg)

##### 分類クラスを任意に設定する

クラスはなんでも設定できます。今回は全クラス画像に写っているものにして、どれに分類されるか試してみました。

```python
cls_names = ["woman", "dress", "balloon", "sky", "meadow"]

# (optional) add prompt when we want to use the model for zero-shot classification
from lavis.processors.blip_processors import BlipCaptionProcessor
text_processor = BlipCaptionProcessor(prompt="A picture of ")

cls_prompt = [text_processor(cls_nm) for cls_nm in cls_names]
cls_prompt
```

##### 分類実行

画像とクラスのテキストをそれぞれemmbeding（数値行列）にして、差分から類似度を出します。

```python
sample = {"image": image, "text_input": cls_names}

image_features = model.extract_features(sample, mode="image").image_embeds_proj[:, 0]
text_features = model.extract_features(sample, mode="text").text_embeds_proj[:, 0]

sims = (image_features @ text_features.t())[0] / model.temp
probs = torch.nn.Softmax(dim=0)(sims).tolist()

for cls_nm, prob in zip(cls_names, probs):
    print(f"{cls_nm}: \t {prob:.3%}")
```

>woman: 	 1.623%
dress: 	 2.220%
balloon: 	 86.563%
sky: 	 8.036%
meadow: 	 1.557%

気球が一番確率高いと分類されました。

🐣
****
フリーランスエンジニアです。
AIについて色々記事を書いていますのでよかったらプロフィールを見てみてください。

もし以下のようなご要望をお持ちでしたらお気軽にご相談ください。
AIサービスを開発したい、ビジネスにAIを組み込んで効率化したい、AIを使ったスマホアプリを開発したい、
ARを使ったアプリケーションを作りたい、スマホアプリを作りたいけどどこに相談したらいいかわからない…

いずれも中間コストを省いたリーズナブルな価格でお請けできます。

お仕事のご相談はこちらまで
rockyshikoku@gmail.com

機械学習やAR技術を使ったアプリケーションを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
[GitHub](https://github.com/john-rocky)
Nodeバージョン管理（NVM）を導入方法、Windows/mac/linux

### NVMを使いやすいということはなぜですか？
異なるプロジェクトを開発するとき、互換性であるバージョンを切り替えできるためです。　互換性がないバージョンを使用したら不明なエラーが出てくる場合もあります。

### インストール
#### Windows:
nvm-windowsを使用します。
まずはこちらからをnvm-setup.exeをダウンロードし実行しましょう。

https://github.com/coreybutler/nvm-windows/releases

インストールが終わると、すべてコマンドプロンプト（VSCODE内のターミナルも）を終了しましょう。

またコマンドプロンプトを開きます。nvmは見つからない場合はwindowsからログアウトし再ログインしましょう。　nodeインストールするとき許可関係があるエラーが出たら、管理者/adminstrator　コマンドプロンプトを使用しましょう。

下記の使い方をご覧ください。

#### Mac：
ターミナルを開いて、以下のコマンドを実行しましょう

```bash
touch ~/.zshrc
```

bashのターミナル場合：

```bash
touch ~/.bash_profile
```

#### MacとLinux:

ターミナルを開いて、以下のコマンドを実行しましょう

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

すべてターミナルを終了しましょう。また新しいターミナルを開きます。 nvmが見つからないエラーが出たら以下に確認しましょう。

ターミナルタイプにより異なります：

bashなら: 

```bash
source ~/.bashrc
```

zshなら:

```bash
source ~/.zshrc
```

kshなら:

```bash
. ~/.profile
```
詳しいトラブルシューティングはこちらをご覧ください；
https://github-com.translate.goog/nvm-sh/nvm?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=en&_x_tr_pto=wapp#installing-and-updating

### 使い方：

最新バージョンをインストール

```bash
nvm install node
```

許可エラーが出たら、Windowsでコマンドプロンプトを管理者権限で起動しましょう

バージョン14.7.0をインストール

```bash
nvm install 14.7.0
```

バージョン14.7.0を選択

```bash
nvm use 14.7.0
```

インストールされたバージョンを表示

```bash
nvm ls
```
直交表の作成

## 目的
MTシステムなどの手法の項目選択に使うため、2水準直交表の作成のプログラムのメモ

## 参考にさせていただいたページ
https://qcplanets.com/method/doe/orthogonal-array8/

```
import numpy as np
## 認証を行ってグーグルドライブをマウントする
from google.colab import drive
drive.mount('/content/drive')

#基準になるL4直交表
l4 = [
    [1,1,1],
    [1,2,2],
    [2,1,2],
    [2,2,1]
]
L4 = np.array(l4,dtype=np.int16)


def Mplus(M):
  return 2 - (M + 1) % 2
#直交表を作成　Lは直交表のサイズ（4×2^自然数）
def make_org(L):
  if L == 4:
    return L4
  retu1 = np.vstack([np.ones((int(L/2) , 1)),np.ones((int(L/2) , 1))*2])
  M = make_org(int(L/2))
  M1 = np.vstack([np.hstack([M,M]),np.hstack([M,Mplus(M)])])
  return np.hstack([retu1,M1])

%cd "直交表のCSVを保存するファイルのパス"

#nは直交表の個数
n = 9

for i in range(n):
  print(2**i * 4)
  L = 2**i * 4
  np.savetxt("二水準L"+ str(L) + "_" + str(L -1)+ '因子直交表.csv',make_org(L),delimiter=',', fmt='%d')


```


## 直交表の各項目の交互作用を考慮した割付の自動化などが分からないため、参考できるページやコードなどを教えていただけるとありがたいです。
Power Automate で 「取得したテーブルの中に対象がない」を条件にする

# Power Automate で以下のことをやりたいとき

1. Item A を取得する
1. Table B を取得する
1. Item A の中の Arriburte C をキーにして、List B の中 で Column D に重複する Item があるかを確認する。
1. 重複がない場合は Item A を List B に登録する。

## こうやればいい


https://learn.microsoft.com/en-us/troubleshoot/power-platform/power-automate/how-to-copy-items-between-two-sharepoint-lists-via-flow

この中で、Condition の設定の仕方が 記載されているが、古い version と新しい version のPowerAutomate では Advance mode があったりなかったり

https://www.alanps1.io/power-platform/flow/flow-so-where-has-edit-in-advanced-mode-gone-on-condition-actions/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/cd5e2a74-34dc-00fc-48a3-74cf9c452c91.png)

なので、新しい vesion の Power Automate では 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/4d64ea07-9e8f-a7f7-0d14-de39c5461a56.png)

この Expression 部分を
`length(outputs('Get_items')?['body/value'])`
と書いてやればよい。

## どういうことをやっているのか
例えば SharePoint List を使用する場合
1. Table B を Get Items で取得する
1. 取得する時に Filter Query で Table B の Column D に Attribute C が同じものを filtering する
1. Table B の Column D に Attaribute C が存在しない場合は、Value が 空っぽで引っ張られる
1. Value が空っぽ = Length がゼロ と判断する
1. Length が ゼロ = Value が空っぽ = Table B に Item A が存在しない となるので、Condition が True となった場合には Create Item で Item A を Table B に作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/56e8d938-984b-1656-b2d9-c79632a60df3.png)

## これを何に使ったか
1. Outlook から送信したメールの管理表を作りたかった
1. Power BI を直接 MS Exchange に繋ぐことで Email の情報は取得できるのだが、In place archive に移った email は対象外になってしまう。
1. 仕方がないので、email (Item A) を送るたびに SharePoint List (Table B) に archive することにした
1. PowerAutomate の Office365 の Action でArchive 自体は出来るのだが、Trigger に「メールを送信したとき」がなかった（「メールを受信したとき」はあった）
1. あくまでも 送信メールを Archive したいので、仕方なく 数時間おきに取得することにした
1. しかし、取得できる email の上限数が 25件だった
1. 数時間に一回 25件を取得して、ひたすら SharePoint List にログを残しても良かったが、流石に重複するので SharePoint List に記録する前に既に記録済みのものを省きたかった
1. Outlook email で固有のものとなるのは PowerAutomate では Conversation Id であったので、これをUnique Key として SharePoint List に記録し（= Attribute C）存在の有無を確認した後に存在しないものだけ記録するようにした。

つまり、自分の Outlook のメール内容を Archive 自動でするのに使える。

ちなみに、Power Automate でメールをArchive すると思いの外 メール内の全ての情報を引っ張ることが出来るのでオススメ。

## 結果こういうFlowになった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/f1487c15-67ac-ba87-fd9d-92f23e78c887.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/8e8f890f-c0e9-eae3-9c0e-caabb667bd80.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/b4ad058e-2669-286b-a5a6-dfa6944a5e80.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/0e3babd0-3ee6-1ad2-6cee-636dd354c0f7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/b6824b21-c550-165e-0fe3-fa01c0db8ce1.png)
VirtualBox のVMの「説明」欄で自分がよく記載する内容のメモ

WSL2全盛の昨今でも、やりたいことの組み合わせによっては素直に（？） VirtualBox でVM建ててます。

そしてたくさんVMを作ります。
Linux です。
NATポートフォワードも設定しましょうね。

するとどうなるか。
「あれ？このVMってSSH接続パスワードどうしてたっけ？」
「このVM、NATポートフォワード設定なんだったっけ・・・」
「新しくNATポートフォワード追加したいんだけど、空いてるポートどれだっけ？」
「ローカル開発環境へのSSHだから `StrictHostKeyChecking` も `UserKnownHostsFile` もスキップさせたいけどオプション思い出せねぇ・・・」

混沌があなたを手招き始めます。

そうならないよう、自分はVMの「説明」欄で↓のような感じに、すぐ参照できるようなメモを記載してます。

```
CentOS Stream 8(, misc label)
created by foobar at YYYY-MM-DD
keyboard layout: Japanese
user: (username)/(password)  (sudo enabled)
network: DHCP enabled

[vobx nat port-forwarding]:
host:10001 -> guest:22 (password auth)
host:10002 -> guest:80

[ssh/scp]:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 10001 (username)@localhost
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 10001 xxxx (username)@localhost:/home/(username)/work/

NOTE:
- (ex)root user is disabled
- (ex)"Development Tools" package group installed.
- (ex)VirtualBox Guest Additions is NOT installed.
  - If you need, install at your own risk.
```

上記はあくまでも例で、実際は多少アレンジしたりはしてます。共通してるのは以下の内容です。
1. SSHログインも含めた、通常操作用のユーザ名とパスワード
1. NATポートフォワード設定
1. ssh/scp のコマンド例ショートカット

他に必要に応じて、例えばどんなパッケージを追加でインストールしたのかを含めておくこともあります。

会社であれば、VMをOVAにエクスポートして他の人に使ってもらうときとかに、「OVAをインポートしたら説明欄見てね」でさくっと引き継ぎできるので便利です。

適宜カスタマイズして使ってみてください。
Chrome で proxy 設定するときに localhost や 127.0.0.1 宛が proxy を通ってくれないときの対処法

メモです。

ローカル開発環境で起動したWebアプリの挙動を調べようと、Chrome で http proxy 設定して通信をキャプチャしようとするときがあるんですが、肝心の localhost や 127.0.0.1 宛が proxy を通ってくれなくてションボリしませんか？

自分はションボリしてました。だいぶ長いこと。(´・ω・`)

でももう大丈夫。proxy 設定フォームに大抵一緒に設定できるようになってる「bypass 一覧」的なところに `<-loopback>` を加えるだけで、ちゃんと proxy を通ってくれるようになります。

これで明日から笑顔です。ヽ(=´▽`=)ﾉ

参考:

- https://www.whitesmith.co/blog/a-note-about-chrome-and-proxying-requests-to-localhost/
- https://superuser.com/questions/1418848/how-to-avoid-google-chrome-proxy-bypass-for-localhost
- https://chromium.googlesource.com/chromium/src/+/HEAD/net/docs/proxy.md#bypass-rule_subtract-implicit-rules

(Switchy Omega なら、proxy profile の Bypass List に `<-loopback>` 入れれば大丈夫でした。)

余談ですが burp の組み込みブラウザ、あれ使えば最初から localhost 宛も通ってくれるのでアレ使えばいいじゃん、ってなりそうなんですが、組み込みブラウザ、微妙に落ちやすくて・・・。普通のChrome使いたいです、先生・・・。
(´・ω:;.:...
新しくなった Databricks CLIで Secretsを設定する


# はじめに

databricks CLI がversion 0.200から新しくなり、RestAPIなども扱えるようになっている。またSecretの設定方法などが変わったため、簡易的な設定方法をまとめてみました。


# Install or Migration

はじめての方はこちらを参考に databricks CLIをPCにインストールしてください。

https://docs.databricks.com/dev-tools/cli/databricks-cli.html#install-the-cli

従来のDatabricks CLIからの移行の場合は、既存の databricks-cliをuninstallしてから実行する必要があります。(.databrickscfgファイルは残ります）

https://docs.databricks.com/dev-tools/cli/migrate.html

# Databricks接続のための認証設定

新規インストールの場合、利用したいDatabricks HostやTokenなどを用いて認証設定を行います。Token以外の認証方法にも対応しております。（[対応している認証方式](https://docs.databricks.com/dev-tools/cli/databricks-cli.html#set-up-authentication)）

また古いDatabricks CLIからMigrationした方は、従来設定した情報が残っておりますので、特に再設定は不要です。

ここでは、Personal Tokenを用いた設定をご紹介します。

対象のDatabricks Host-URLとPersonal Access Tokenを取得します。
Personal Access Tokenは、ユーザー設定画面から取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206424/c0f5bd08-2304-935b-80c7-f1b4d26f1a27.png)

以下のコマンドを実行し、ホストとトークンを登録します。

```:Tokenを用いた認証設定
databricks configure --host <workspace-url> -t -p <some-unique-configuration-profile-name>
```

登録すると、以下のように *.databrickscfg* ファイルに登録されます。
```:.databrickscfg
[<some-unique-configuration-profile-name>]
host  = <workspace-url>
token = <personal-access-token>
```

# Secret作成

https://docs.databricks.com/security/secrets/example-secret-workflow.html

### 1. Scopeの作成

最初にKey/Valueを登録するScopeというものを作成します。このScopeはフォルダーのようなもので、その中に複数のKeyを登録でき、グループ化することができます。プロジェクト毎にキーを分けて管理するなどに便利です。
作成方法は　`databricks secrets create-scope SCOPE` です。 

```:scope作成例(openai scope)
$ databricks secrets create-scope openai
```

### 2. Key/Valueの作成

次にKey/Valueの作成をします。以下のように `databricks secrets put-secret SCOPE KEY [flags]` という形式で作成します。すると Valueを入力するプロンプトが表示されます。

```:Key/Value作成例
$ databricks secrets put-secret openai openai-api-key
✔ Enter your secrets value: ************************************█
```

以上で完了です。それ以外の使い方は、 `databricks secrets -h` で確認できます。

### 3. ノートブックでの呼び出し方

以下のようにdbutilsを使って呼び出せます。

```
key = dbutils.secrets.get(scope = "openai", key = "openai-api-key")
```
【Swift】文字列の中に特定の文字列が含まれているかを確認する方法

## containsを用いて特定の文字列が含まれているか確認する

`apple`という文字列の中に`pl`という文字列が含まれているかどうかを確認します。

```diff_swift
import Foundation
let str = "apple"

// "apple"に"pl"が含まれているかどうかを確認する
print(str.contains("pl")) // true

// "apple"に"al"が含まれているかどうかを確認する
print(str.contains("al")) // false
```

含まれているかどうか確認したい文字が`a`や`p`のように1文字であるときは **import Foundation** は不要なようです。

## 配列でのcontainsの利用

**contains** は配列で利用することもできます。

```diff_swift
let array = ["a", "p", "p", "le"]

// arrayに"le"が含まれているかどうかを確認する
print(array.contains("le")) // true

// arrayに"o"が含まれているかどうかを確認する
print(array.contains("o")) // false
```

では 👋
macOSでFinderの右クリックから新規テキストファイルを作成する

macOSのFinderでは、Windowsのエクスプローラーのように右クリックメニューから直接新規テキストファイルを作成する機能はデフォルトでは提供されていません。しかし、AutomatorとAppleScriptを使用すれば、この機能をカスタムで追加することができます。

以下にその手順を示します。

### 1. Automatorを開く
まずは、Applications フォルダから Automator を開きます。
(cmd + spaceで検索)

### 2. 新規ドキュメントを作成
Automatorの起動画面が表示されたら、「クイックアクション」をクリックします。
![スクリーンショット 2023-07-08 0.14.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178576/10098f40-a9b2-5290-25eb-98da36beee87.png)

### 3. クイックアクションの詳細を設定
次に、右側の詳細設定エリアで以下のように設定します。


「ワークフローが受け取る現在の項目」: ファイルまたはフォルダ
「検索対象」: Finder

### 4. AppleScriptを追加
左側のライブラリから「ユーティリティ」を選択し、「AppleScriptを実行」を右側のワークフローエリアにドラッグ＆ドロップします。

### 5. AppleScriptを記入
AppleScriptのコードエリアに以下のスクリプトをコピー＆ペーストします。

```
applescript
Copy code
on run {input, parameters}
    tell application "Finder"
        set currentPath to insertion location as text
        set theDate to current date
        set yearString to year of theDate as string
        set monthString to my zeroPad(month of theDate as integer as string)
        set dayString to my zeroPad(day of theDate as string)
        set hourString to my zeroPad(hours of theDate as string)
        set minuteString to my zeroPad(minutes of theDate as string)
        set secondString to my zeroPad(seconds of theDate as string)
        set newFileName to yearString & monthString & dayString & "_" & hourString & "." & minuteString & "." & secondString & ".txt"
        set newPath to POSIX path of currentPath & newFileName
        make new file at currentPath with properties {name:newFileName}
    end tell
end run

on zeroPad(num)
    if num's length < 2 then
        return "0" & num
    else
        return num
    end if
end zeroPad
```

設定すると、以下のようになるはずです。
![スクリーンショット 2023-07-08 0.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1178576/8eff7d64-3b56-25f4-6d7e-f97c40715daa.png)


### 6. クイックアクションを保存
「ファイル」メニューから「保存」を選択し、クイックアクションに名前をつけて保存します（例：「New Text File」）。

これで設定は完了です。Finderで右クリックすると「クイックアクション」の下に先ほど作成した「New Text File」が表示され、これを選択すると新規テキストファイルが作成されます。

なお、このテキストファイルの名前は「yyyymmdd_hh.mm.ss.txt」の形式になります。
(ファイル名重複するとエラーになるため)
※注意事項として、localの環境では動きますが、iCloudドライブなどでは、右クリックしてもメニューが出てきません。


以上で、Finderで直接新規テキストファイルを作成する環境が整いました。
お試しください。
WSL2で環境構築するときの操作まとめ

# 目的

WSLでWebアプリ(フロントエンド+バックエンド)のステージング環境を作ろうと思っていろいろ調べたところ、環境を作るという視点でまとめられた記事が見当たらなかったので自分で作ることにした。
ある程度やり方覚えても、ちょうどコマンドとか忘れたころに作業発生するから自分でまとめるのがいい。

# やりたいこと
1. スナップショットを取る（任意の時点の環境のバックアップ・再構築）
2. distroに名前を付ける
3. 同じdistroのイメージを複数起動する
~~~powershell: 例
PS C:\Users\Admin> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04-a  Stopped         2
  Ubuntu-22.04-b  Stopped         2
  Ubuntu-22.04-c  Stopped         3
~~~

# 前提 (環境に合わせて適宜読み替える)
- ベースとなるdistroはUbuntu-22.04を使う
- 起動中のdistroは`Z:\wsl\distro`に保存する
- スナップショットは`Z:\wsl\snapshot`に保存する
- distro = ディストリビューション

# 環境
- Windows 10 Pro 22H2
- Powershell

# 手順

~~~powershell
# インストールできるdistroの一覧表示 distroが決まっているならskip 今回はUbuntu-22.04を使用する
# wsl -l -o 

# distroのインストール
wsl --install -d Ubuntu-22.04 # 上記で表示された一覧のNAME列の文字列を入力
# -> wsl -l -v の一覧でUbuntu-22.04が追加される

# distroの停止
wsl -t Ubuntu-22.04 
# -> wsl -l -v の一覧でUbuntu-22.04のSTATEがRunning > Stoppedに変わる

# スナップショットの作成
wsl --export Ubuntu-22.04 Z:\snapshot\Ubuntu-22.04-base.tar
# -> Z:\snapshot\にUbuntu-22.04-base.tarが作成される。

# distroの削除
wsl --unregister Ubuntu-22.04
# -> wsl -l -v の一覧からUbuntu-22.04が消える

# distroのimport & 名前付け
wsl --import Ubuntu-22.04-a Z:\wsl\distro Z:\wsl\snapshot\Ubuntu-22.04-base.tar
# -> Z:\wsl\distroにext4.vhdxが作成される

# distroの起動
wsl -d Ubuntu-22.04-a
# -> wsl -l -v の一覧でUbuntu-22.04のSTATEがStopped > Running に変わる

# おまけ distroのデフォルト設定
wsl -s Ubuntu-22.04-a
# -> wsl -l -v の一覧でUbuntu-22.04-aの先頭に*がつく

~~~



※`wsl -l -o`で表示される一覧からdistroをインストールする場合、distroに名前を付けることができず、また同じdistroを複数インストールすることもできない。そのため、インストールしたdistroのスナップショットを取って、それを名前を付けてインポートすることで同じUbuntu-22.04のイメージを複数起動できるようにしている。
【SwiftUI】iPhoneを傾けてボールを転がす方法

# はじめに
モーションセンサーを使ってボールを転がす方法を紹介します。

# 作るもの
デバイスを傾けるとボールが転がるアプリを作ります。

https://twitter.com/shota_appdev/status/1677300944386785291?s=61&t=YxRQGnSdwBxHzB5nPjXScg

# 対象者
SwiftUIの基本的な使い方を知っている人

# やり方
```swift
import SwiftUI
import CoreMotion

struct ContentView: View {

    // ボールの位置
    @State private var ballPosition: CGPoint = .zero
    
    // モーションマネージャー
    private let motionManager = CMMotionManager()

    // 直径
    private let diameter: CGFloat = 50

    var body: some View {
        GeometryReader { geometry in
            Circle()
                .frame(width: diameter, height: diameter)
                .foregroundColor(.red)
                .position(ballPosition)
                .onAppear {

                    // ボールの初期位置を画面の中心にする
                    ballPosition = CGPoint(x: geometry.size.width / 2, y: geometry.size.height / 2)

                    // モーションマネージャーを開始する
                    motionManager.startAccelerometerUpdates(to: .main) { data, _ in
                        guard let data else { return }

                        // x軸とy軸の加速度を取得する
                        let x = data.acceleration.x
                        let y = data.acceleration.y

                        // ボールの位置を更新する
                        let newX = ballPosition.x + CGFloat(x * 10)
                        let newY = ballPosition.y - CGFloat(y * 10)

                        // 半径
                        let radius = diameter / 2

                        // 画面の外に出ないようにする
                        if newX > radius && newX < geometry.size.width - radius {
                            ballPosition.x = newX
                        }
                        if newY > radius && newY < geometry.size.height - radius {
                            ballPosition.y = newY
                        }
                    }
                }
                .onDisappear {
                    // モーションマネージャーを停止する
                    motionManager.stopAccelerometerUpdates()
                }
        }
        .edgesIgnoringSafeArea(.all)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
```

# おわりに
モーションセンサーを使ってボールを転がす方法を紹介しました。これを使ってゲームを作ろうと思います。
Typescript+Vite環境での.envの利用方法

Vite環境下で.env内の環境変数が読み出されないなということが起きたので覚書でまとめておきます。
# Viteでの環境変数の書き方

Create React Appでは、環境変数を設定するためには、それらの名前が `REACT_APP_`
Vite環境下ではこれが`VITE_`に変わります。

```diff
- REACT_APP_API_KEY=APIKEY
+ VITE_API_KEY=APIKEY
```

そして`vite-env.d.ts`ファイルに（Typescript使用時）
```diff
/// <reference types="vite/client"/>
+ declare namespace NodeJS{
+    interface ProcessEnv{
+        VITE_API_KEY: string;
+    }
+}
```
を追加しておきます。TypeScriptでコーディングする場合は型を宣言することにより、IDEやエディターの補完機能やコードチェックを行えますので可能な限り行っておきましょう。

# 参考リンク
https://zenn.dev/longbridge/articles/575190b038f805
Power Automate で SharePoint List の 複数行テキストには Filter Query が出来ない

# Power Automate で SharePoint List
## SharePoint List のアイテムを取得する際に Filter Query を使いたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/22686b3a-3642-97d0-521e-d777d9c0d26e.png)

普通に書くと、Filter Query のところに
Title eq 'aa' とか substringof('aa',Title) という風に書くことで、SharePoint List から取得するItem をFiltering 出来る。

が、しかし、出来ない事象がある。（2023/07/07 時点）

どうやら、SharePoint List での 列の設定が **複数行テキスト** になっていると、Filter Query が使えないっぽい。

複数行以外では 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/acfeca83-05e0-cc8d-7996-336a184c2c69.png)
という形で、並び替え（Sort) や Filterが使えるが、

複数行テキストに設定していると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573860/4bd7ed76-c30c-cb73-7a49-9437f60a927d.png)
その選択肢が出てこない。

現時点では SharePoint List の複数行テキストには Filter / Sort が使えない = Power Automate でも使えない。
ということみたい。
なので、**一行テキスト**として列設定をするしかない。
インスタの投稿を自動でTwitterとSlackにシェア

# はじめに 🐢
インスタグラムの投稿を Twitter と Slack に自動でシェアします。

基本的に自家用です。誰かご興味ある方居られればお試しを。

# TL;DL
トークンを差し替えれば動く連携用プログラム [insta2twislack](https://github.com/tmatsumor/insta2twislack) を作成。
手持ちのレンタルサーバーでcronで呼び出してインスタ監視。
新規投稿を検出したら、Twitter と Slack に自動投稿。

# 背景
インスタのアプリからの Twitter 連携が廃止されました。
社内の Slack にも自動で連携してほしいです。
IFTTT や Zapier とかのノーコード系に課金すればできそうですが、
そのバジェットで円谷のウルトラサブスクしたいです。

# 前提
次のプログラムを使います。
- [insta2twislack](https://github.com/tmatsumor/insta2twislack)

以下のトークン類が必要です。
- instagram long lived access token
- twitter OAuth 2.0 client id and secret
- twitter OAuth 2.0 access token
- slack api user OAuth token
- 投稿先の Slack チャンネル名


# 詳細

## 1. サーバーの準備
まず PHP と cron が動作する サーバーを用意します。

## 2. インストール手順
[insta2twislack](https://github.com/tmatsumor/insta2twislack) の README.md の [Installation](https://github.com/tmatsumor/insta2twislack#installation) を実行します。

## 3. 動作確認
[insta2twislack](https://github.com/tmatsumor/insta2twislack) の README.md の [Example](https://github.com/tmatsumor/insta2twislack#example) を実行します。

インスタグラムの最新の投稿１件を Twitter と Slack に即時にシェアします。

## 4. 定期処理

cron にてこんな感じで設定します（3分毎の例）。
```bash
*/3 * * * * (cd /hoge/insta2twislack && /usr/local/bin/php insta2twislack.php)
```
※ 手元のレンタルサーバーでは
> cron は 3分以内の処理で、1時間間隔で、10個まで

と制限がありました。

その中でもほぼ3分毎に cron できたのですが、
それは別の記事に書きました。こちらを参照下さい ↓

- [制限のあるサーバーの中で3分毎にcronする](https://qiita.com/tmatsumor/items/54baaf4d8bedb43f12e8)

# 5. 仕組み
以下のファイルに、インスタグラムの投稿IDを保持しています。

リクエストにより取得された新しい投稿IDのリストと、
ファイルに保存されている古い投稿IDのリストを比較し、
差分を取って、新規投稿を検出します。

```
insta2twislack/insta_api_php/insta_post_ids.txt
```


# 免責
大変申し訳無いのですが、不慣れでして
トークンがリフレッシュされなかったり、
何か間違っていて、連携が途切れる事があるかもしれません。
長期稼働試験を行っておらず、未だ Alpha 版ですので、
ご自身のご責任のもと、ご利用下さい。

# その他
トークンの取り方、留意事項、参考文献、などなど
書きたいのですが、あまりに眠いのでまた後日にさせて下さい。
RubyでAtCoder ABC234(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC234のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Weird Function
https://atcoder.jp/contests/abc234/tasks/abc234_a
```ruby:a-234.rb
def f(x)
  return x ** 2 + 2 * x + 3
end

t = gets.to_i
puts f(f(f(t) + t) + f(f(t)))
```

# B - Longest Segment
https://atcoder.jp/contests/abc234/tasks/abc234_b
```ruby:b-234.rb
n = gets.to_i
array = Array.new(n){ gets.split.map(&:to_i) }

puts array.combination(2).map{ Math.hypot(_1[0] - _2[0], _1[1] - _2[1])}.max
```
## 解説
`combination`メソッドを使ってそれぞれの組み合わせにおける距離の最大値を求めます。

# C - Happy New Year!
https://atcoder.jp/contests/abc234/tasks/abc234_c
```ruby:c-234.rb
k = gets.to_i.to_s(2)
puts k.to_i * 2
```
与えられた整数を２進数にして、その値を２倍したものが答えとなります。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
【Swift】ラベル付きループ文でbreakを制御する

# はじめに
Swiftの知らない構文があったので記録しておきます。

# 実装
```swift
outerLoop: for i in 1...5 {
    innerLoop: for j in 1...5 {
        if i * j > 10 {
            break outerLoop
        }
        print("\(i) * \(j) = \(i * j)")
    }
}
```

# おわり
あんまり使う機会はなさそうですが、iOSエンジニアとしてSwift構文はマスターしておきたいです
required: trueでフォームの空送信を防ぐ

## はじめに

通常モデルに記述するバリデーションとは別でフォームに空での送信を
`required: true`で防ぐことが出来ます。
利便性を上げる為に実施しました！


## 例その1
```ruby:qiita.rb
<%= f.email_field :email
                   required: true,
                   autocomplete: "email",
                   placeholder: "メールアドレスを入力して下さい",
%>
```

## 実装イメージ

下記のように空で送信した際にメッセージを表示してくれます！便利！
![スクリーンショット 2023-07-07 22.52.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3478070/536fc15a-5ba7-8c0e-6185-485d76b299dd.png)
WebApps+Docker-composeでwordpressサイト作る

# はじめに
Docker-composeの勉強のために調べたら簡単にwordpressつくれたので記念に。

# 参考
いわれた通りやったら簡単にできました
https://learn.microsoft.com/en-us/azure/app-service/tutorial-multi-container-app

# 前提
以下の環境で作業

* OS:Windows11
* エディタ:Visual StudioCode
* Az CLIインストール済み
* GitBashインストール済み

# 手順
ローカルPCにて作業
## リポジトリをクローン

```
git clone https://github.com/Azure-Samples/multicontainerwordpress
cd multicontainerwordpress
```

## WebAppService構築
az cli使ってWebApp作成

```
### ログイン
az login

### リソースグループ作成
az group create --name myResourceGroup --location "South Central US"

### WebAppServicePlan作成
az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku S1 --is-linux

### Docker-composeを読み込んでWebApps作成
az webapp create --resource-group myResourceGroup --plan myAppServicePlan --name nabehiro-wordpress --multicontainer-config-type compose --multicontainer-config-file docker-compose-wordpress.yml
```

詳細は実際にリポジトリの中身をみたらいいけど
ざっくり理解のために、docker-compose-wordpress.ymlの中身はこちら

```yml:docker-compose-wordpress.yml
version: '3.3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

```

これで完成

## 実行後の確認
ポータルから見た画面がこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/72cf6d8f-fdb9-78f7-7f8a-48b437b82fe0.png)

出来上がったサイトを見てみよう、以下URLクリック。

https://nabe-wordpress.azurewebsites.net/

リンク先ではワードプレスの初期設定画面が現れた。大成功！
いろいろと動かした後なので直後のものではないけどこんな感じでちゃんと動きました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/25047ee1-5097-d870-0e3b-20fdd7596048.png)

# 最後に。一点だけ不満を。
維持費が高い。。。ちょっと確認してみたら$70/月だった。
以前にちょっと手間だけどAWSのlightsailを使って試したときは、$3.5/月で超激安で作れた。
独自ドメインはお名前ドットコムつかったので年１円だったのであってないようなものだったし。
お手軽さとコストとのトレードオフを迫られる。。。そんな感じ。今回はお試しで作ったのでせっかく作ったけど閉鎖しよう。。。

勉強になりました。
OMVでFailed to execute command 〜とでてアップデートできなかった

# 概要
OMVをweb uiでアップデートしようとしたらエラーが出た。
掲題の
Failed to execute command 'export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/
みたいなやつ

# 症状
ぶっちゃけ心当たりがない。何もしてないのに壊れたの感覚に近い

# 原因
HDDのマウント情報が原因のことがあるらしい。
...が自分の場合は違った。

自分の場合はレポジトリからうまく情報が持ってこれなくなっていたのが原因だった。
海外のサイトの通りにomvにsshでアクセスしてsuで
` ` ` export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin; export LANG=C.UTF-8; export LANGUAGE=; omv-salt deploy run --no-color apt 2>&1` ` ` 
と打ち込むとaptで失敗しているみたいなことを言ってきた。どうやらレポジトリにうまくアクセスできないようだ。

` ` ` cat /etc/apt/sources.list` ` ` 
して中身を見ると

```
#〜〜〜〜〜〜〜〜略〜〜〜〜〜〜〜〜
deb http://ftp.yz.yamagata-u.ac.jp/debian/ bullseye main
deb-src http://ftp.yz.yamagata-u.ac.jp/debian/ bullseye main 
#〜〜〜〜〜〜〜〜略〜〜〜〜〜〜〜〜
```
山口大学のレポジトリから落としているようだ。うまくいかないんだったらダウンロード先をjaistに変える。
` ` ` cp /etc/apt/sources.list  /etc/apt/sources.list.old ` ` `
してバックアップを取っておいて
` ` ` /etc/apt/sources.list` ` ` 
の中身を以下のようにした。


```
#〜〜〜〜〜〜〜〜略〜〜〜〜〜〜〜〜
deb http://ftp.jaist.ac.jp/debian/  bullseye main
deb-src  http://ftp.jaist.ac.jp/debian/ bullseye main 
#〜〜〜〜〜〜〜〜略〜〜〜〜〜〜〜〜

deb http://ftp.jaist.ac.jp/debian/  bullseye-updates main contrib non-free
deb-src  http://ftp.jaist.ac.jp/debian/ bullseye-updates main contrib non-free
#〜〜〜〜〜〜〜〜略〜〜〜〜〜〜〜〜
```
 この状態で
` ` ` export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin; export LANG=C.UTF-8; export LANGUAGE=; omv-salt deploy run --no-color apt 2>&1` ` `
を再度打ち込むと正常終了した。

最後にweb uiでアップデートしたら掲題のエラーが出ずに終了した。

# 終わりに
私は本職のバックエンドエンジニアではないのではっきりしない説明と操作をしてます。詳しい方がいたら補足なりなんなりしてくれると嬉しいです。
OneDrive 従業員の共有状況を管理者が知る

みなさんこんばんは、本日はMicrosoftに関する記事です。

企業の情シス担当者は以下のようなことを感じるときはないでしょうか？
「従業員はOneDriveのファイルの権限をどのように設定しているのか？安全な共有ができているか？」

上記は実際に実現可能なのか？

## 結論

こたえはYes.
Microsoft365の管理者権限を持っている方は、従業員の共有状況の確認が可能です。
手順は以下で記します。


## 手順
1. 管理者アカウントにて [Microsoft 365 管理センター](https://admin.microsoft.com/)にアクセスします。

2. 画面左欄から [ユーザー] - [アクティブなユーザー] をクリックします。

3. 確認したいユーザー名をクリックします。

4. 右側に表示された画面のメニューから [OneDrive] をクリックします。

5. "ファイルへのアクセス" 欄にて [ファイルへのリンクの作成] をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586845/7d232ad0-98a8-9f9c-80dc-f5e8bf09fdcd.png)


6. 生成されたリンクをクリックすると、該当ユーザーの OneDrive 領域へアクセスが可能です。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586845/696d0be1-2e0d-d305-0753-298db63a1415.png)

7. 生成されたリンクをクリックすると対象のユーザーのOneDrive画面に移動します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586845/0f5197cb-62c5-4e91-3c54-da5dd44136e1.png)

8. 各ファイル、フォルダの「・・・」から「アクセス許可の管理」を選択することで共有状況を確認できる。


## おまけ（ファイル、フォルダの権限一覧を出力）

上記のNo.7の手順で表示されたファイルやフォルダの権限一覧を取得する方法を紹介します。

1. 上記No.7のページへ移動します。

2. 画面左下の「従来の OneDrive に戻す」をクリックします。

3. クラシックUIに切り替わると、画面右上の歯車マークから「サイト コンテンツ」をクリックします。
4. 「サイトの利用状況」をクリックします。

5. ページを 1 番下までスクロールし、「外部ユーザーと共有」セクションの [レポートを実行] をクリックします。

6. データが出力される Excel ファイルの保存先であるフォルダーを選択し [保存] をクリックします。




※データ量やネットワーク環境にもよるが、約5～15 分程度で出力が完了するはずです。
※出力ファイルの保存先は、管理者ではなく当該ユーザーのOneDriveとなります。

## 最後に
以上です。是非参考にしてください。
弊社ではMicrosoft365に関する豊富な経験がありますので、是非お気軽にお問合せください！
モダンアクティビティを使ってみた(Excel編Part3～グラフを取得？更新？知っちょん？～)

## はじめに
①本記事は、2023年7月開催の「UiPathブログ 発信チャレンジサマー」の7日目のブログです。
ブログの詳細、参加方法については以下のブログを参照ください。
https://note.com/shumpei_w/n/nd082bdf28853
②このブログ情報は、2023/7時点の情報です。
③UiPathはCommunity Edition、Versionは2023.6.1を使用しています。

## 前回のおさらい
第1回、第2回目は以下をご覧ください。
・モダンアクティビティを使ってみた(Excel編)
https://qiita.com/saosao885/items/3401b0d8708cc5fb3d3c
・モダンアクティビティを使ってみた(Excel編Part2～グラフも作れるのかや？～)
https://qiita.com/saosao885/items/c27b9171317481b37530
なお第2回目では、グラフがExcelに挿入することができることを確認しました。
こんな感じで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/3bb9e102-6736-35ca-e569-4ec5f9df193f.png)
ということで、ほかにもあるグラフ関連のアクティビティを調べてみましょう。

## グラフを取得アクティビティ
作成したグラフの変数を、クリップボードへ格納or画像へ出力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/a6b82f54-03e1-c145-48c4-a80b900a0fa3.png)

グラフ：グラフ用変数を格納します。
アクション：対象のグラフをクリップボードにコピーor画像として保存することができます。画像はPNG、もしくはJPEGで保存可能です。

## グラフを更新アクティビティ
作成したグラフに何らかの更新をかける場合に使用するアクティビティです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/6d135842-1cc4-5929-a7bc-7cd0da094296.png)
グラフ：グラフ用変数を格納します。
変更を追加：グラフのタイトルや軸の最大値/最小値等、グラフで変更を加える対象を設定できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/441cbcf4-4767-b125-1277-25d5dd36982c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/cb74b9f9-f242-8f81-4dea-9f9e49a15ae5.png)


## 実行してみよう
第1回目から使用している「出身地.xlsx」ファイルを使用します。
第2回目に作成したグラフをもとにタイトル変更&凡例表示&データラベルを表示&画像へ貼り付けるようにしましょう。
※ほかの処理のテストもしていたため、一部コメントアウトしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/356a1704-3e02-ac67-ca11-c9553f5cd9ad.png)
その結果を見てみましょう。
画像は...できた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/e51a6932-684a-2b64-d1b0-13ee4f08aaa3.png)
タイトルも凡例もデータラベルもついている！すごい！
ちなみに、今回の変更でこれだけ変化が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502614/1a312982-2c94-7f88-1001-e03e33399186.png)

## まとめ
グラフはExcelでも作れますが、アクティビティで作成することで作成の負担も少しは減るかもしれませんね。
モダンアクティビティの奥は深いようです。
最後までお読みいただきありがとうございました。
【環境構築】viteでVue3の環境構築

# NodeJSのインストール

こちらからダウンロードしてください。

https://nodejs.org/ja

ダウンロードが完了したら、以下のコマンドでバージョンが確認できます。
```
node -v
```

nodeと共にnpmもインストールされるはずなので、とちらもバージョンを確認してください。

```
npm -v
```

# Yarnのインストール

こちらはコマンドからインストールします。

```
npm install -g yarn
```

完了したら、バージョンを確認します。

```
yarn -v
```

# プロジェクト作成

保存するディレクトリは好きな場所で構いません。
ディレクトリに移動したら、以下のコマンドを実行します。

```
yarn create vite
```

順調に進むと、以下のようにプロジェクトの名前を聞かれますので、任意の名前を入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/f71cfa71-4a4a-5a9e-d592-237188361f12.png)

プロジェクト名を記入すると、次に使用するフレームワークを聞かれます。
今回はVueを選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/cc4b445d-4e43-e2ad-e04f-6d026437bb93.png)

次も使用するフレームワークを問われます。
今回は、TypeScriptを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/10883afe-c8f5-d148-8d09-f771e690731b.png)

インストールが完了したら、作成したプロジェクトに移動し、様々なパッケージを一括でインストールしてくれる以下のコマンドを実行します。

```
yarn
```

完了したら、以下のコマンドにより作成したVueのアプリケーションをブラウザから見れるようになります。

```
yarn dev
```
ファインマン図をLaTeXで書くパッケージを見つけた。

今日、僕の開発している[Grow My Search](https://www.growmysearch.com/login.php)で「リチャードファインマン・量子」と英語で検索していたら、ファインマン図をLaTexで書くパッケージを見つけました。　
まだ試していませんが、一応将来的に使うかもしれないのでメモを残しておきます。　

https://jpellis.me/projects/tikz-feynman

加藤翼 
[My Twitter Account](https://www.twitter.com/_stingraze)
CSS filterの効果は実行環境（ブラウザ）によって違うから気をつけろ

こんなことは常識なのかもしれないが、私はハマった。

## 再現経緯
画像が出現するという演出を実装した。
人物が、まず白いシルエットで現れて、それが色変化して最終的に人物として出現するというものだ。
人物画像とは別にシルエット画像を用意して読み込ませるのは冗長なので、
以下のように、`filter`と`transition`で実装した。

```scss
img {
  transition: opacity 500ms linear, filter 300ms linear 500ms;
  &[aria-hidden="true"] {
    // 出現前
    filter: brightness(100);
    opacity: 0;
  }
}
```
まず`opacity: 0`で透明化していた画像が出現するが、そのとき`filter: brightness(100)`で白く飛ばした状態で出てくる。
その後、時間差で`filter`が外れた状態（つまり本来の画像）へ移行する。

MacOS Chromeで見る限り問題なかったのだが、モバイル端末実機での検証で「色がおかしい」という指摘が入った。

## 各ブラウザでの`filter: brightness`を検証
もしかして、閲覧環境によって見え方が違うのではないかと思い、Safariで確認したところ、見え方が違うことが判明した。
以下は、Chrome, Firefox, Safariで`filter: brightness`の見え方を検証したものだ。（Edgeは知らん）
※画像はいらすとやさん。
![aa2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31785/bf2c0014-d9b4-a16f-1c03-74c0b22bfe78.png)
`brightness(2)`程度なら、さほど違いはないが、
`brightness(10)`になると、全然違う。
FirefoxとSafariは、かなり近い効き方をしている。Chromeと違って、白飛びすることがあまりない。

## ついでに、他の`filter`も検証
`brightness`以外の`filter`プロパティも検証してみた。
（キャプションつけ忘れたけど、先ほどと同じく左から Chrome, Firefox, Safari）
![cd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31785/e5834266-1154-9946-23bb-841911a49fa8.png)
`contrast`や`saturate`では若干の違いを確認できたが、
`brightness`ほど顕著なものはなかった。

## 結論
CSSの`filter`は、実行環境で違いが生じうる。
特に、`filter:brightness`で白いシルエットにしようとするのはやめるべき。