OmniAICreator/Qiita-1.07M huggingface dataset:
JUnit 実践入門　メモ

## テストフェーズ
フェーズ1: 事前準備
ここで、テスト対象の初期化、必要な入力値、期待される結果などの準備を行う
フェーズ2: 実行
テスト対象オブジェクトに対して、テストする操作を行う
フェーズ3: 検証
テスト結果として得られた実測値が期待値と等価であるかを比較検証する。
フェーズ4: 後処理
次のテストに影響が出ないように処理を行う

## アノテーション
@Test
テストを行うことを宣言する
@Ignore
一時的にテスト実行から除外する
@Before
重複する初期化処理を@Before内で設定することで、何度も同じコードを書く必要がなくなる。
@After 
テスト実行後の後処理時に使用するアノテーション

## モックとスタブ
どちらもテスト対象が依存するクラスやモジュールの代用として使用するクラスやモジュール。モックの使用する理由は、目的のメソッドがテストの実行中に呼び出されたかを検証するため。スタブは予測が難しいテストケースを検証可能なテストケースに変えるため。
## Mockito
モックとスタブを利用する際に、利用される外部ライブラリ。
### Mockitoを利用する準備
#### モックオブジェクトの作成
```java
List<String>createMock = org.mockito.Mockito.mock(List.class);
```
#### スタブメソッドの再定義
スタブオブジェクトの戻り値を再定義するには、Mockitoのwhenメソッドとその戻り値の型であるthenReturnメソッドを利用する。
```java
List<String>createMock = org.mockito.Mockito.mock(List.class);
when (createMock.get(1)).thenReturn("Hello");
assertEquals("Hello", createMock.get(1));
```
例外処理を行いたい場合は、
```java 
when (createMock.get(1)).thenThrow(new IndexOutOfBoundsException());
createMock.get(1);
```
## 参考資料
JUnit実践入門 ~体系的に学ぶユニットテストの技法
草莽Erlang ── 34. lists:last

口で言うより行うことがErlang習得への近道と信じています。

https://qiita.com/mnishiguchi/items/9237780e849d80a85e11

## lists:last/1

リストの最後の要素を返します。リストが空の場合はエラーになります。

https://www.erlang.org/doc/man/lists.html#last-1 

```erlang

> lists:last([1]).
1

> lists:last([1, 2, 3]).
3

> lists:last([]).
** exception error: no function clause matching lists:last([]) (lists.erl, line 256)
```

[listsモジュール](https://www.erlang.org/doc/man/lists.html)には他にもリスト処理のための関数がたくさんあります。

## Elixirにも挑戦したい

闘魂ElixirシリーズとElixir Schoolがオススメです。

https://qiita.com/torifukukaiou/items/3b65e5c04fa8c55f526e

https://elixirschool.com/ja

https://qiita.com/piacerex/items/09876caa1e17169ec5e1
世界一わかりやすいかもしれないnpmパッケージ公開方法

# npm publishの前にnpm adduserがむずい。

ええ、とにかくnpm adduserもしくはnpm loginの処理がむずいんですね。

# んで肝心のやり方は?

もうなんでもいいから早く教えろあまみやさんと聞こえてきそうなのでやっていきます。

えせエンジニアなので間違ってるかもです。よろしこ。

まずは[npmjs.com](https://www.npmjs.com/)にアクセスしてアカウント名とパスワードを決めます。ここで登録アカウント名を忘れるとのちのnpm adduserで詰むので注意。

- アカウント登録とログインを済ませたら、右上のアカウントマークから”accestokens”選択
- Generare New token選択後トークン名設定の後Select typeをAutomationに設定。
トークンをコピー(一応コピペミスったとき用にページはそのままで。)
- Terminal上で

```
npm adduser --scope=@OWNER --auth-type=legacy --registry=https://registry.npmjs.org/:authToken=<コピペしたトークン>
```
github packageの場合は

```
npm adduser --scope=@OWNER --auth-type=legacy --registry=https://npm.pkg.github.com/:_authToken=<コピペしたトークン>
```

を入力。

ちなみに2FA認証を有効にしてる場合はワンタイムパスワードを入れてくださいな。Logged in ...と表示されればOK!


あとは公開したいパッケージのディレクトリに入り、
```
npm init -y
```
でpackage.jsonを作成。

ちなみにわしはこんな感じ。

```json

{
  "name": "project-example",
  "version": "1.0.0",
  "description": "",
  "repository": {
    "type": "git",
    "url": "githubリポジトリのURL"
  },
  "main": "index.js",
  "scripts": {
    "test": "echo \"Wait!\" && exit 1"
  },
  "keywords": [
    "web5",
    "nft",
    "web3",
    "crypto",
    "metaverse"
  ],
  "author": "アカウント名 <自分のメルアド> (自分のレジストリアカウントURL)",
  "license": "MIT",
  "dependencies": {
    "@tbd54566975/dwn-sdk-js": "*" //これはWeb5のパッケージ。(このコメントは消してネ。)  
}
}


```

ここまで来たら
```
npm publish
```
で行ける...はず。
ちなここでもう一回ワンタイムパスワードのに入力を求められます。（めんどくさい。）

ちょいとコツがいるのでギブアンドテイク精神で行くとよきだと思います。

最後にわいの開発中のnpmパッケージとgitリポジトリ。

web5用


https://www.npmjs.com/package/project-v-web5

https://github.com/NknightA/project-V-web5



全体の設定とか


https://www.npmjs.com/package/projectv

https://github.com/NknightA/project-V-E-Rust

よろしく。
opendkim with postfix on Amazon Linux 2

(訂正) DNS のエントリはサブドメイン単位で必要でした。

# 切っ掛け
iCloud だと 130円で DKIM できるよ？
って読んだので、一瞬乗り換えようかと思ったが、
いやいや、うちのサーバーにも DKIM を付けられるだろう？
と、思ったので試してみた。

実は SPF は随分前に対応したのに、
DKIM って、DNSSEC が必須だろう、
なんていう訳の分からない思い込みがあったため、やっていなかった。
※ 勿論 DNSSEC 無しでできる。

うちの環境は、記事タグの通り。

# 参考

* [Postfix + OpenDKIMで送信元ドメイン認証を実装するメモ](https://qiita.com/taku1201/items/3b2dffd950340b9726d0) 

# 導入手順

## opendkim インストール
```
# yum install -y opendkim
```

## DNS 設定
### key pair 生成
```
# cd /etc/opendkim/keys/
# opendkim-genkey -b 2048 -d example.com -s 202301220
# chown opendkim:opendkim 202301220.*
```

202301220 は作業日付。

### zone ファイルへの追加
```
202301220._domainkey    IN      TXT     ( "v=DKIM1; k=rsa; p=..." )
; ----- DKIM key 202301220 for example.com                                
_adsp._domainkey      IN TXT  "dkim=unknown"
```

1, 2 行目は、先程生成した 202301220.txt の内容をそのまま使用。
3行目はこのように記載。
これを使用しているドメイン/サブドメイン全てに追加。


### 動作確認
```
# rndc reload
# dig TXT 202301220._domainkey.example.com
# dig TXT _adsp._domainkey.example.com
# dig TXT 202301220._domainkey.sub1.example.com
...
```

zone ファイルに追記した内容がサブドメイン分を含めて、全てきちんと引けることを確認。

## /etc/opendkim.conf の修正箇所
```
Mode                sv
SyslogFacility      mail
#                                                                               
KeyTable            /etc/opendkim/KeyTable
SigningTable        /etc/opendkim/SigningTable
ExternalIgnoreList  /etc/opendkim/TrustedHosts
InternalHosts       /etc/opendkim/TrustedHosts
ExemptDomains       /etc/opendkim/ExemptDomains
```

### refile を使わない

検索で引っかかる殆どの事例が refile(正規表現使用) の dataset を指定しているが、見る限り余り意味が無いので、止めることにした。

## /etc/opendkim/ 下のファイル

### KeyTable
```
202301220._domainkey.example.com   %:202301220:/etc/opendkim/keys/202301220.private
```
opendkim.conf(5) より
>　KeyTable (dataset)
>      --- snip ---
>      If the first value consists solely of a percent sign ("%") character, it will be replaced  by  the apparent  domain of the sender when generating a signature.
>

% は送信者のドメインに置換される。

### SigningTable
```
.example.com               202301220._domainkey.example.com
```

example.com の全てのサブドメインに一致。

### TrustedHosts
```
127.0.0.1
::1
192.168.1.0/24
```

192.168.1.0/24 には内部の smtp relay が置いてある。

### ExemptDomains
```
.example.com
```

example.com の全てのサブドメインに一致。
MUAから submission port 宛に投入したメールの DKIM 署名に必要。

### opendkim 起動
```
# systemctl start opendkim
# systemctl enable opendkim
```

systemctl status opendkim で起動状況を確認し、
/var/log/maillog や /var/log/messages に異常が無いことを確認する。

## postfix への追記
### /etc/postfix/main.cf
```
#
#   DKIM
#
smtpd_milters           = inet:localhost:8891
non_smtpd_milters       = $smtpd_milters
milter_default_action   = accept
```

### postfix reload
```
systemctl reload postfix
```

systemctl status postfix で起動状況を確認し、
/var/log/maillog や /var/log/messages に異常が無いことを確認する。

# 動作確認

動作確認については、参考記事を参照のこと。

以上
HTTPメソッドについての備忘録

HTTPメソッドについて改めて細かく復習したので備忘録として書いていきます。

# HTTPメソッドの種類
まずはHTTメソッドの種類と概要は以下の通りです。
|  メソッド名  |  説明  |
| ---- | ---- |
|  GET  |  HTMLファイルや画像といったデータを取得する場合に利用するメソッド。  |
|  HEAD  |  HTTPヘッダーの情報のみを取得するメソッド。  |
|  POST  |  フォームに入力したデータを送信する場合に使用するメソッド。  |
|  PUT  |  データをアップロードする場合に使用するメソッド。 |
|  PATCH  |  リソースへの部分的な変更を行う場合に使用するメソッド。  |
|  DELETE  |  指定したデータを削除する場合に利用するメソッド。  |
|  CONNECT  |  Webサーバーを接続するまでに別のサーバーを中継する場合に利用するメソッド。  |
|  OPTION  |  利用できるHTTPメソッドを問い合わせる場合に利用するメソッド。  |
|  TRACE  |  WebブラウザとWebサーバーの途中経路をチェックするためのメソッド。  |

メソッド自体は9つありますが、HTMLフォームで使用できるのはGETとPOSTの2つのみです。
なのでHTMLのformタグのmethod属性にPUTを入れても動きません。（私は過去に一度これやってエラー出てびっくりしたことがありますw）

今回はHEAD,GET,POST,PUT,DELETEについて詳しく見ていきたいと思います。

## GET
GETメソッドはWebサーバーに対してHTMLファイルやコンテンツを取得したい場合に利用します。
名前の通りデータを取得するために使いますが、一応Webサーバーに対してデータを送信することはできます。
ただGETメソッドでデータを送信する場合はURLの末尾にそのパラメータを付与して送信してしまいます。
なので絶対にGETメソッドでデータを送信するようなことがないようにしましょう。
## HEAD
HEADメソッドはGETメソッドの仲間で、GETメソッドを送信した時に帰ってくるレスポンスのヘッダー部分だけを取得するメソッドです。
データのコンテンツ入らないけど更新日時やサイズのみを得たい場合などに使います。
## POST
POSTメソッドはフォーム入力したデータを送信するメソッドです。
CRUDで言えば主にCREATE(作成)に用いられます。
POSTメソッドは冪等性がなく連続して同じものを実行すると、複数回渡してしまうなどの追加の影響が発生する可能性があります。
## PUT
PUTメソッドもPOSTメソッドと同様フォームに入力したデータを送信するメソッドです。
PUTメソッドは冪等であり同じものを何度実行しても結果は変わりません。
CRUDで言えば主にUPDATE(更新)に用いられます。
## DELETE
DELETEメソッドはその名の通り指定されたデータを削除するメソッドです。
もちろんCRUDのDELETE(削除)に用いられ冪等性のあるメソッドです。

## 最後に
今回はHTTPメソッドの基本的な部分について改めて復習した内容についてまとめてみました。
誰かのためになれば幸いです。
４０代おっさんFastAPI、MongoDB連携メモ 認証関係②

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
などありましたらコメントにてお知らせいただければ幸いです。

## CORS

オリジン間リソース共有 (Cross-Origin Resource Sharing, CORS ) は、追加のHTTPヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えようウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間HTTPリクエストを実行します。

### オリジン(Origin)

Originとは

`<scheme> "://" <hostname> [ ":" <port> ]`

例

scheme: https,http
hostname: google.comなど
post : 443など

これがすべて同じになるのが同一オリジンとみなされる

### Cross

オリジン単位でのアクセス制御可能
Requestは送信できるが、Responseは受け取れないなどの制限をかけれる

## XSS

クロスサイトスクリプティング（XSS）とは、Webサイトの脆弱性を利用し、記述言語であるHTMLに悪質なスクリプトを埋め込む攻撃です。クロスサイトスクリプティングの英語表記「Cross Site Scripting」の略称として「XSS」と表記する場合もあります。

- 不正なサイトに誘導されアクセス
- 不正なJavaScript codeが実行される
- 被害者のブラウザのCookieを読み取られて外部に送信されお供養される

### 対策

httpOnlyと言うCookieの属性があり、それをtrueにすることでJavaScriptから読み取れなくする。

## CSRF

クロスサイトリクエストフォージェリ（CSRF）とは、Webアプリケーションに存在する脆弱性、もしくはその脆弱性を利用した攻撃方法のことです。掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他サイトからのリクエストを受信し処理してしまいます。

- 不正なサイトに誘導されアクセス
- Cookieが自動送信されるので不正なDB操作などが行われる(不正書き込みなど)

### 対策

正規サイトからのリクエストが判別する仕組みが必要
CSRF Tokenを使う

#### CSRF Token

- 正規サイトアクセス時にServerからCSRF Tokenを発行する
  - GET:api/csrf_token
- DB操作(Create,put,Delete)request時に、headerにCSRF Tokenを付与する。Server側で正規のリクエストか検証する。
- 外部サイトからCSRF Token発行requestをしてもCORSによりResponseを読みれない。

## SameSite

SameSiteというのはCookie設定の1つの属性となります。
SameSiteには3つの設定を行うことが可能です。
None、Lax、Strictの3つとなります。

セキュリティレベルの高さの指定となり、None(なし)、Lax(緩い)、Strict(厳しい)の順番でセキュアに対するセキュリティレベルを示しています。

シングルアプリケーションの場合はNoneにしてCookieの送受信を可能する

Secure:true -> httpsで暗号化された通信のみCookie使用可能

## 参考

https://www.udemy.com/course/farm-stack-react-fastapi
【Android】Barrierとは【kotlin】

# はじめに
前回　[【Android】Guidelineとは【Kotlin】](https://qiita.com/Tsubasa12/items/04a3676922cbfe2a7ba3)　こちらの記事でGuidelineについて書きましたが、今回はそのGuidelineを調べている中で見つけた
Barrierについて調べたものを記事にします。

# Barrier
Guidelineでは親Viewを基準にして補助線を引くものでしたが、
Barrierは子Viewを基準に補助線を引くものです。

constraint_referenced_ids にViewを指定することでそのViewを基準にして補助線を引くことができます。
barrierDirection　でそのViewのどの位置を基準にするか指定でき、
barrierMargin　でその基準からMarginを指定することができます。


例
```
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Barrier
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:barrierDirection="start"
        app:barrierMargin="100dp"
        app:constraint_referenced_ids="text" />
```

今回は　ど真ん中にある”Hollo World！”の文字の左側(start)から100dpのmarginをつけた位置に補助線を指定しました


![スクリーンショット 2023-01-22 21.50.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2394054/8edb76a3-7ee7-876f-13d3-8d1eddaa2d3c.png)


# 参考
https://qiita.com/yamadacsa/items/3434c277d23e04ee50cb#barrier


https://developer.android.com/reference/androidx/constraintlayout/widget/Barrier
JenkinsにGitHub認証情報を登録してJenkinsfileからジョブを作成できるようにする

# 概要
[親記事](https://qiita.com/drafts/78945bf5e4fe575843d9/edit)の事前準備

GitHubで管理されているJenkinsfileからジョブを作成する場合、JenkinsからGitHubへアクセスするための認証情報登録が必要となるため、下記設定を実施
- Jenkinsインストール
- GitHubでpersonal access tokenを発行
- GitHub認証情報をJenkinsに登録

## Jenkinsインストール
### 環境
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
mac OS Monterey
ver 12.6.2

### 手順
1. jenkinsをインストール
    [Jenkins](https://www.jenkins.io/download/)
    ```
    brew install jenkins-lts
    ```
1. インストール後のセットアップ
    1. jenkinsの起動
        ```
        brew services start jenkins-lts
        ```
    1. アクセス
        http://localhost:8080
    1. 初期パスワードを入力し「Continue」押下
        赤字で初期パスワードが格納されているファイルが表示されるため、中身を確認して入力
        ```
       〜〜/〜〜/.jenkins/secrets/initialAdminPassword
        ```
    1. プラグインのインストール
        「Install suggested plugins」押下押下
    1. Adminユーザーの情報を入力し「Save and Continue」
        - user naem 
        - password
        - mailaddress
        - full name
    1. 「Start using Jenkins」を押下し、セットアップ完了

## GitHubでpersonal access tokenを発行
- personal access tokenとは？
    ```
    Personal access tokenは、GitHub API またはコマンド ラインを使用する場合に、GitHub に対する認証でパスワードの代わりに使用できます。
    ```
    参考：https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token
- [対象GitHubリポジトリ](https://github.com/karaage578tech/jenkins-learn)

### 前提
GitHubアカウントを持っている

### 手順
1. GitHubでPersonal access tokensを発行
    1. 自分のGitHubページにアクセス
    1. アイコン > Settings を押下
        ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/e949398a-8e5f-b37b-a73c-7b0a8edb0f79.png)
    1. メニューから Developer settings 押下
    ![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/906ff221-1901-da0f-f021-84613e55ef6e.png)
    1. Personal access tokens > Tokens(classic) > Generate new token(classic) 押下
        ![３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/0674937e-ac72-a9c4-59c7-d58f150acfd2.png)
    1. Note：tokenの用途、Expiration：tokenの有効期限、Select scopes：許可範囲　を入力・選択
    ※ 各スコープ内容については[公式ページ](https://docs.github.com/ja/developers/apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes)を参照。今回は「repo」にチェック
    ![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/00b00622-b6e6-3077-c513-3a8d4c20ea27.png)
    1. Generate token 押下しtokenを作成
    1. 作成されたtokenが表示されるため保管する（以降、２度と参照できないため注意）

## GitHub認証情報をJenkinsに登録
### 手順
1. Jenkinsにログイン
1. サイドメニュー「Jenkinsの管理」から「Manage Credentials」を押下
    ![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/d79ebc13-d6a9-f4cd-ee14-85fa450b8975.png)
1. 「Add credentials」から認証情報を作成
        ユーザー名：GitHubユーザー名
        パスワード：発行したtoken
        ID：認証情報のID（任意の値）
        ![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118252/eb7154a7-08fb-ae00-cce9-609d90a01700.png)

1. 認証情報登録完了！

1. [Jenkinsfileからジョブを作成](https://qiita.com/karaage578tech/items/7a959afda009be4a3623)
mocopiを買う前に調べたこと

2023年あけましておめでとうございます。

早速ですが、ソニーから面白いデバイスが発売されました。

**mocopi** ですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/a1ce25b0-7832-fa10-b526-27bb0a12c222.png)

これはVR用のモーションキャプチャらしいのですが。
多分ですね、もっと違う使い方が出来るとですね、思っているのですよ。

どんなもんって？？

**「俺のこの手が真っ赤に燃える！」**　的な奴ですね（AA略）

さて、一体この装置、どんな仕組みなのか、調べていきたいと思います。

なお、著者が買うのは３月頃の予定です（それまで残ってればよいが）

# 販売サイト

https://pur.store.sony.jp/mocopi/products/mocopi/QM-SS1_purchase/

**商品合計金額　　　49,500 円(税込)** 

同梱物：
　センサー6個
 　ヘッドバンド
　リストバンド2個
　アンクルバンド2個 
　クリップ
　充電ケース
　取扱説明書

成程。良いですね。

# 開発情報

https://www.sony.net/Products/mocopi-dev/jp/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/d566cfb7-99a7-7c91-6af8-a884f6beef45.png)

ふむふむ。背骨の演算が面白そうですね。実際は６個のセンサで補完しあってボーンの位置を推定しているのでしょう。
センサーは６点なので、ボーンの推定はスマートフォンアプリ側でやってそうですね。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/4bd8f481-3fa1-8fda-de03-2b4337ca4e5a.png)

ふむふむ。
この図に書いていないですが、

**センサーｘ６**　ー＞　**スマートフォン**　ー＞　**WiFi(5GHz推奨)**　ー＞　**ＰＣ**

と言った形でしょうか。
**WiFi(5GHz推奨)** と記載があるので、これはとても賢い事です。
きっとセンサーはBLEを使用しているのでしょう。６個となればそれなりの帯域を食います。そのため、他の2.5GHzのデバイスは切っておいた方が良いでしょう。WiFiの他に、無線マウスや無線キーボードも注意が必要かも。

**スマフォからUDPでボーンのデータを送信しPCで描画しているようです。**

あれ？何か図がおかしくない？ポート二つ開けてるし・・・


え？？？？


何と、この図、**2台用** の図でした。２台で遊ぶ事を前提にしたシステム図でした・・・

**す、すげぇぇぇ・・・・**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/b34fa28f-78cc-b429-967b-531aa56fbe7c.png)


通常、加速度センサとジャイロセンサは計算の仕組み上**積分計算**を行います。
積分計算は、繰り返し計算をしていくと誤差も一緒に増大すると言う厄介な計算方式ですが、
ソニーさん強いですね。AIを取り込んで補正と関節位置の推定まで行っていますね。

**す、すげぇぇぇ・・・・**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/2b6b97d4-fff7-b604-e676-a4b0844a350a.png)

SDKはUnityやMotionBuilderもあったりします。

が、注意が必要です。

**スマフォアプリからが前提です。**

スマフォ側でBLEの処理とAI推定処理をしてるので、安易に省略は難しそうですね。

逆に言えば、そこそこな性能を持ったスマフォが必要になりますが、考えてみればiPhone13Proで推定するよりかはお安い機材なのではと思ったりもしたり。


# 結論

**mocopi**の良い所

・センサーが６個もある！
・スマフォでAI推定！
・UDPで送信する仕組みもちゃんとある！
・Unityに連携が出来る！

面白いかもですね。VR以外にロボットやコントローラとしての道もあると思いました。
ではでは。
学習記録　Jenkins編 まとめ記事

## 概要
GitHubで管理されているJenkinsfileからJenkinsジョブを作成

## 作成手順
1. [JenkinsにGitHub認証情報を登録してJenkinsfileからジョブを作成できるようにする](https://qiita.com/karaage578tech/private/e6d6f53baf977cf4556b)
1. [JenkinsジョブをJenkinsfileから作成する](https://qiita.com/karaage578tech/items/7a959afda009be4a3623)
1. [用途に合わせてジョブの処理内容を記載する](https://qiita.com/karaage578tech/private/1178d1176741e5b0da7c)

## 備忘
### [便利なJenkinsプラグイン](https://qiita.com/karaage578tech/items/2a7de8c89aa846a2c4a5)
全ロボに行ってきたよという話

# はじめに
2023年1月21日と22日にあった全国ロボコン交流会というものに行ってみました。

https://zenrobo.jp/

もともと弊学は他高専との交流が浅く、技術継承も疎かになっており、なんとかこの状況を抜け出そう！という考えでとりあえずカンファレンスに行こうということになり、今回の参加に至らました。

今回で全国ロボコン交流会というのは記念すべき第20回らしく楽しみでした。

自分自身こういったカンファレンスへの参加経験が浅く、また弊学はこれまで他校との交流会なども全くなかったため今回が自分にとっても、弊学のロボ研にとっても初めてのカンファレンスとなりました。

今回は、もし自分のように怖くてイベントにまだ参加していない人たちが参加しようかなと思えるようになって欲しいと感じて記事を書こうと思ったので、助けになれば幸いです。

# カンファレンスってなに？
カンファレンスは簡単にいうと勉強会。

その分野に興味があるひとが集まって有識者たちから学びを得るための会です。

# 感じたこと
## 資料が手に入る
勉強会なのであたりまえといえば当たり前ですが、資料が手に入ります。しかも質が高く読みやすい資料ばかりでした。
## コミュニティーが手に入る
実際自分は会場に入って数分でdiscordを追加させていただきました。みなさん交流会なので人との繋がりを持とうと意識している方ばかりなので自分のようなコミュ障でもコミュニティーに参加することが簡単にできるんだなと感じました。交流会を通じての交流は実際開催日だけではなくて、交流会では継続的に交流する場を手に入れることができるのはとても強いと感じました。
## 特典がもらえる
全ロボでは企業さんや全ロボの運営さんたちから特典がもらえました。結構かっこいい定規などももらえました！

## 友達が増える
これは二つ目の延長線上のような感じなのですが、友達が増えました！自分と一緒に行っていた友達は徹夜でロボコンのことについて語りあっていました。朝にはラジオ体操もしていてとても良い雰囲気だと思いました。

# 必要品

基本的に運営からの連絡やしおりなどに書いてありますが個人的になくて公開しそうなもの、したものをあげておきます。

- 名刺(自分を比較的簡単に相手に知ってもらうためには名刺はとても有効です。ぜひこだわりの名刺をもっていって相手を驚かせましょう！)
- ナイロン袋(ナイロン袋は靴などを入れる時に便利です。他にも色々と使える場面が多いので持っていきましょう。)

# カンファレンスはどのような人におすすめか
1. この分野興味あるけどなにから始めればいいのかわからない人
1. 今活動しているけどコミュニティーをもっていない人
1. オタク

# まとめ
今回は初めての交流会で全国ロボコン交流会というものに行ってみたよというお話でした。  

普段あまり文章を書く機会がないため読みにくい記事になってしまっていると思いますが、記事の内容がわかりにくいと思った人もとりあえずカンファレンスがどのような感じなのかすこしでも参考になれば幸いです。一緒に行った同級生も「なんでもっと早くこなかったんだろう」と後悔していました。そのくらい参加するのと参加しないのとでは違うと僕自身も感じましたので、ぜひ早いうちに参加して欲しいと思いました。
【Linux】コピー

# コピー

## ディレクトリのコピー
* ```dir1```を```/home/dir2```の中にペーストしたい
```
cp -r dir1 /home/dir2
```
:::note info
-rオプションは「再起的」を意味するので、dir1の中のにあるディレクトリの中身もコピーしてくれる。
:::
【JS】非同期処理とは


# 非同期処理とは

非同期処理とは、あるタスクを実行している最中に、その処理を止めることなく別のタスクを実行できる方式を指します。特にJavaScriptではAjax（Asynchronous JavaScript and XML）という技術を用いた非同期処理が有名です。
JavaScriptは外部のAPIを叩く時などは基本的に非同期処理を行います。


画面を表示するときに、DBからデータを取得してから表示しようとするとデータを取得できるまでの間、白い画面が出ていることになります。（画面表示の処理に至っていない。）非同期処理をすることで、画面を表示させつつデータを取得できたら画面が補足されるということが可能になります。


非同期処理は、処理を一度バックグラウンドに移して実行しています。
しかし、バックグラウンド動かしている処理の中でも、「ある処理が終わったらこの処理を実行したい」ということがあります。（つまり、非同期で動かす処理の順番を制御したい。ある処理が終わるのを待ちたい。）

そこで使うのが、`Promise`や`async/await`です。


# async/await


直感的でわかりやすいので多くの場合、`async/await`が使われます。


```:async/awaitの使い方
・非同期処理を伴う関数定義にasyncをつける。
・非同期処理を伴う関数実行時にawaitをつける。
・awaitはasync付きの関数内でしか使えない。
```


# まとめ

Javascriptで外部APIを叩く処理を行うときは非同期処理になる。このときに非同期処理が完了するのを待ちたい場合には`async/await`を使って制御する。
Flutter - const警告を非表示にする方法

ウィジェットを追加するたびに「constが足りないよ♥♥♥」という警告(Warning)が出て「うわぁ、ウザっ」と思ってしまったので（笑）、設定をいじって非表示にする方法をメモッておきました。デバッグする際はデフォルトに戻すことを推奨します。

## const警告を非表示にする方法

`analysis_options.yaml`という警告表示に関するプレファレンスのファイルがあるので、そこを弄ります。24行目に  `rules:`というクラスがあるのでここをちょこっと変更します。それだけです。

```dart
  rules:
    prefer_const_constructors:false #この行を追加するだけ
```

![スクリーンショット 2023-01-22 212824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/e94750ea-8e8b-d696-358b-951499635ab5.png)

次回は名刺交換ができるアプリのコードの公開を目指します。頑張りますね :)
IoTシステムの全体像① 〜データ収集〜

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# IoTシステムの全体像
IoTシステムでは次のような順でデータが流れていきます。
`①データ収集 -> ②データ通信 -> ③データ可視化 -> ④データ蓄積 -> ⑤データ分析 -> ⑥データ活用`
6つの記事に渡ってそれぞれのセグメントについてまとめていきますが、この記事では「①データ収集」について記述します。

# データ収集器
IoTシステムにおけるデータ収集器として、メインとなるのはセンサーとカメラです。この2つについて説明していきます。

## ■センサー
センサーと一纏めに言いましたが、「光センサー、加速度センサー、音センサー、振動センサー、温度センサー、圧力センサー」など様々な種類のセンサーがあります。
例えば、光センサーによってセンサー部を通過した製品数をカウントすることで、__良品数や不良品数をカウント__ したり、工作機械のベアリングの近くに振動センサーを設置して、__機械の異常を事前に検知(予知保全)__ することで、設備のトラブル停止が発生する前に修理できるようにします。

## ■カメラ
カメラもデータ収集器として、IoTシステムに使用することができます。
例えば、定期的に人が目視点検する必要がある設備を常時撮影することで、その __設備まで行くことなく点検__ することができます。特に高所や危険箇所等の簡単に立ち入ることができない箇所で効果を発揮します。また、カメラで撮影したデータを蓄積してAIで解析することで、__不良品の検知__ をすることもできます。

## 収集したデータの行方
次の「②データ通信」の記事で、収集したデータの送受信については記載しますが、その前にセンサーやカメラから取得したデータ(電気信号)の行方について説明します。
これらのデータは直接ネットワークを介してPCまで飛ぶというよりも、`一度PLCに入りPLCからEthernetケーブルや無線でPCまで飛ばされる`ことが一般的です。また、__エッジIoT__ と言って、それぞれのPLCでデータの整形や取捨選択を行ってからPCまでデータを飛ばすことで、ネットワークやサーバーの負荷を削減する技術もあります。

# 終わりに
IoTシステムの全体像①として、データ収集についてまとめました。IoTがここまで発展した背景にはデータ収集器が大きく関わっています。
IoTシステムでは収集したいデータが増加するほど、データ収集器も増加します。以前までであれば、データ収集器が高価だったため簡単にIoTシステムの構築をすることができなかったのですが、スマホ等の電子端末の普及により大量生産の技術が発展し、センサーが安価になったことで、IoTシステムを構築しやすくなりました。


最後までお付き合いくださりありがとうございました。
【資格】Oracle SQL Silver(1Z0-071-JPN) に受かりました

# はじめに
今回は「Oracle SQL Silver(1Z0-071-JPN)」に合格したので、記録として記事を書こうかと思います。
事前取得が必要な資格はないので、手軽に受けられるかと思います。

(ちなみに自分はOracle系の資格が苦手らしく、いつも苦戦しています...)

# 勉強期間
合計2ヶ月半くらいです。
途中で基本情報技術者試験の受験があり、途中で中止して、基本情報技術者試験の勉強に切り替えたで少し時間がかかってます。

# レベル感
JavaSilverも持っているのですが、それよりも難しく感じました。
なぜかというとSQLに関しては実務経験もなく、自宅でSQLを組むということも特になかったので、
全然頭に入らず、イメージもつかない。。。と言った感じでした。
スキル不足ですね。

もっと実務経験がある方であれば、余裕かと思います。

# 資格勉強
勉強する際に使ったものは以下になります。

- オラクルマスター教科書 Silver SQL Oracle Database SQL
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3086650/1942c3c3-2e38-b901-488a-49291a52f41a.png)

https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E6%95%99%E7%A7%91%E6%9B%B8-Silver-SQL-Oracle-Database/dp/4798172367

- Ping-t(すごく助かった！)
https://mondai.ping-t.com/g

この黒本実は大変良いのですが、索引やユーザの権限あたりの問題数が少なく、そのあたりの網羅性が少ないといったイメージ。
そこをping-tで補おうかと思ったのですが、なかなか難しく、本番では合格ギリギリでした。

SQLはもちろん、それ以外の部分
- データディクショナリ
- ユーザ、権限およびロール
- 索引

などなど、SQL以外の部分も多く出題されるので、全体的にしっかり取り組んだほうが良いです。(当然ですが。)

# 最後に
記事を書きなれていないので、内容がない記事になっていますが、こんな感じで。
もう少し書きなれたいな～

ではでは、次は応用情報技術者かJavaGoldあたりを目指したいかな

# 後日談
そういえば取得しました↓
[【資格】Java Gold（Java SE 11 Programmer II (1Z0-816-JPN)）に受かりました](https://qiita.com/wanwan0000/items/aa4df732e4d5048ac2d0)
Google Play Consoleで新しいサブスクリプションの基本プラン作成時に「 予期しないエラーが発生しました。もう一度お試しください」

Google Play Consoleで新しいサブスクリプションの基本プランの値段付けが終わって保存しようとしたら、

「予期しないエラーが発生しました。もう一度お試しください」と表示されました。

ブラウザのキャッシュやクッキーを削除しても解決しませんでした。

# 解決策

国 /　地域の公開設定の管理

と書いてあるボタンをクリック

チェックボックスを全て外し、日本だけ有効にする。
UniTaskを使えば並列処理で外部機器からデータを簡単に取得できますの紹介

北陽の側域センサーを利用するにあたり、データ取得部分をUnityのMainThreadから切り離して取得することで、fpsを向上させるコードを書きました。外部装置と連携する際に、Threadingして並列処理でデータを取得したいケースはよくあるパターンかなと思いますが、UniTaskを利用すれば手軽に書くことができます。

その際に二点ほど気を付けるところがあります。
1. 外から見えるデータを書き込むときはロックする
2. ThreadのMain・ThreadPoolを切り替える

この2点を踏まえて、Sample Codeをみてください。

# 省略型のSample Code

```C#
using ... // 省略

public class Sensor : MonoBehaviour
{
    // 今回はセンサーで距離が取れる想定で、
    // このクラスの外側からはこのDistancesを使って距離情報にアクセスしてもらう
    public List<long> Distances => distances;
    private List<long> distances = new ();
    // その他は省略
    private object lookObj = new ();
    private CancellationTokenSource updateDataCanceler;

    void Start()
    {
        // 外部機器に接続するところ、場合によって異なるので無視して良い
        Open();

        updateDataCanceler = new CancellationTokenSource();
        // データ取得するためのスレッド開始、ここではまだMainThread
        UpdateDataOnThread().Forget();
    }

    private void OnDestroy()
    {
        // UnityEditorなどで停止するときに合わせてスレッドを停止させる
        updateDataCanceler.Cancel();

        // 外部機器との接続を閉じるところ、場合によって異なるので無視してよい
        Close();
    }

    // 外部機器との・・・略！
    private void Open() { ... }
    private void Close() { ... }
 
    // データ更新処理をループで回し続けるメソッド
    // cancelation tokenでキャンセルされまで実行し続ける
    private async UniTask UpdateDataOnThread()
    {
        // 注意①：下記章を参照
        while (!updateDataCanceler.IsCancellationRequested)
        {
            // 切り替え：この処理の後からUnityのメインスレッド外
            await UniTask.SwitchToThreadPool();

            // データ更新する実処理
            UpdateData();

            // 切り替え：この処理の後からUnityのメインスレッド内
            await UniTask.SwitchToMainThread();
        }
    }
    
    private List<long> temp = new ();
    private void UpdateData()
    {
        try
        {
            var data = urg.ReadLine();
            // まずはこのクラス内でしかアクセスできないtempを更新する
            if (!SCIP_Reader.MD(data, ref timeStamp, ref temp)) return;
            if (temp.Count == 0) return;

            // 外からdistancesがアクセスされている可能性があるのでlockして更新する
            lock (lookObj)
            {
                distances = temp.Select(t => t).ToList();
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
}
```

## 注意①
ループ内でMainThreadとThreadPoolとのスイッチングをしないと、Unityの実行を止めたときに必ずUnityが固まってしまいました。おそらくUnityの停止処理からのキャンセルと、ThreadPool内の処理の連携がうまくいっていないと推測し、性能的に特に影響がなかったので、ループ内で都度Threadingを切り替えることで回避するようにしています。

# 前提
* Unity 2021.3.11f1
* UniTask 2.3.3
* 北陽センサー UBG-04LX-F01

# 全コード・リポジトリ
* [Sensor.cs](https://github.com/machidyo/Shoot/blob/master/Assets/Scripts/Sensor.cs)
* [リポジトリ](https://github.com/machidyo/Shoot)
【雑記】これ以上心臓に負荷をかけるな【光で目覚めよう】

# はじめに

**突然ですが、朝は何時に起きていますか？**

「7時」
「リモートワークだから8時50分まで寝てるW」
「朝活しているから6時」
「テキトウ」

ほとんどの社会人がこんな感じだと思います。
そこでもう一つ質問します。

**皆さんアラームをかけていますか？**
かけているとしたら、スマホのアラームを設定している人が多いのはないでしょうか。
あれはとても心臓に悪いです。体験している人ならご存知かもしれませんが、アラーム音がなったときの「**ﾋﾞｸｩｩ!!**」となったあと、爆速で刻む心臓の鼓動が今でも思い出せます。

今回はそんな **心臓に負荷をかける起床方法はやめないか？** といった雑記です。
技術記事とは何ら関係の内容に見えますが、朝はやはり気持ちよく起床し仕事や休みの日を満足度が高いものにしたいと思っています。


補足しておくと「○○大学の研究によると～」的な文言は一切使いません。
実際にそういった研究があるかもしれませんが、研究結果で示されたところで、自分の体ベースで変わったのを実感しないと理解していただけない判断しました。

なのでこの記事では特に記載していません。私の体感をお話しますので、気になる場合はご自身で調べていただけると幸いです。

# 前提として

気持ちよく起床するためには生活習慣の改善が不可欠です。
しかしながらそちらに話題を振っていくと、それだけで別の内容となってしまうため今回は割愛します。

そのためこの記事の対象としている読者は下記のとおりです。

- スマホのアラーム音で起きている人
    - その上で何かしらの改善がしたいけど、なにを改善すれば分からない人

こういった人を対象にして、こうしたらいいんじゃないかな？という具体的なプランを提示していきたいと思います。
ものによっては難易度が高いので、できることから試していただけると幸いです。

# 改善案

## 光で起きる目覚まし時計を買う

私が最近まで利用していたものがこちらです。
![スクリーンショット 2023-01-17 073529.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837411/452d06c1-b390-68b3-4e35-901be9ad12b8.png)

起床時間の少し前から暖かい光(電球色)を発し、光による起床を促します。
7時に起きるとしたら20分前くらいから点灯しますので、その間に起床できた時点でその日は勝利確定です。

アラームとしての基本的な使い方以外にも、暖色系の色を発するため、間接照明としても重宝します。

## 時間になったら部屋の明かりを自動で点灯する

この記事を書いた理由の一つです。
スマートリモコンを用いて、決まった時間に電気をつけるように設定することで、強制的に明かりでの起床を促します。
「スマートリモコンってなんぞや？」と思う人は超ざっくりいうと **「赤外線信号を代わりに発するもの」** って感じです。なので赤外線を発するものであればなんでも自動でやってくれます。

有名なものでいうと2つ挙げられます。
- SwitchBot
- Nature Remo
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837411/8a8e7705-ccf5-530f-ff3d-b05246865fa6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837411/a09afe38-356f-4249-76df-fc7b4d4e4002.png)

スマートリモコンを利用してみて良いと思った点は以下のとおりです。

### スマホで操作できる

電気の消灯以外に「やべ、エアコン消し忘れた…」となってもスマホで操作できるため、消し忘れがなくなります。

### あらゆるデバイスを日時や時間指定できる

先述通り、決まった時間に明かりをつけてくれるので実質的なアラームの役割を果たしています。
明るくなったら起き、暗くなったら眠るといった人間本来の生活を取り戻せます。

### 赤外線信号を発するものであればなんでも操作できる

部屋にある赤外線信号を発するものであれば全て操作できるので、エアコン等も自由に日時指定できます。

### 音声アシスタントを導入することで、声だけで操作できる

私はAmazon Alexaを利用していますが、スマートリモコンと連携させると「Alexa、エアコンつけて」や「Alexa、電気つけて」と言うだけで赤外線信号を発し端末の操作ができます。
個人的にはスマートリモコンと音声アシスタントはセットだろと思っているのでオススメです。

### 結局どっち買えばいいの？？

私は両方とも利用しましたが、 正直どちらでも良いと思います。
しかし、以下に当てはまる場合はSwitchBotを買うことを推奨します。
- **部屋の明かりがリモコン操作できないもの(部屋のスイッチやヒモで電気を点滅させるもの)** 
- 部屋のありとあらゆるものを自動化させたい人
- SwitchBotカーテンを利用している人

赤外線信号で操作できないような機器は別売りのSwitchBot ボットが必要になります。

## (難)朝日が入る部屋に引っ越す

私が前に住んでいた家では朝日が入り込むため、寝る時にカーテンを少し開けてました。日の光は強制的に起きるきっかけにもなります。

しかしカーテンを開けて寝るには防犯上のリスクもあるため、SwitchBotカーテン等の決まった時間にカーテンを自動で開閉させるデバイスを一緒に使うことが望ましいです。


## (難)生活習慣を改善する

どんなに対策しようにも睡眠時間が少なかったり、運動不足や食生活によって朝の目覚めは変わってきます。
年齢、仕事、環境によって取り組めることは変わると思うので、ここでは一例として紹介します。

私は21歳→23歳時に86kg→68kgまで体重を落としましたが、そのときにやっていたものが以下の5点になります。

- 起床時間と睡眠時間を固定する(7時起き、24時迄に寝る)
- タンパク質や野菜中心の食生活で、炭水化物の摂取は夕食のみにする
- 毎日15〜20分の散歩と極力歩く
- 基本、間食をしない
- 基本、お茶や水しか飲まない

難易度が一番高いですが、どんな小手先の技術を使うよりも一番効果があるので試せるものからやってみてください。

# 終わりに

結論として**規則正しい生活をこころがけましょう**ということです。

なんだか「スマホのアラームは辞めよう」といったことを伝えたかったのですが、結果として健康的な生活を送ろうといった趣旨の内容になってしまいました。
実際のところ目覚めが良ければアラーム音でびっくりすることもなくなりますし、なにより1日を快適に過ごせます。

この投稿が皆様の勉強や仕事に役立てると幸いです。
ありがとうございました。
【備忘録】GitHub Flowとは

# GitHub Flowとは？
### GitHub社が実践しているワークフローのこと
masterブランチからブランチを切る（ここではfeatureブランチとする）
↓
featureブランチで作業を行う
↓
プルリクエストをする
↓
レビュー
↓
承認されたらmasterブランチにマージしてリリース

このような非常にシンプルなワークフローで、GitHub Flowという名前を知らない人でも多くの人が実践しているワークフローだと思う。

## GitHub Flowを実践するときに意識するポイント
- masterブランチは常に本番環境と同じ状態に
- 開発はmasterブランチから新しいブランチを切ってスタートする
- 作成したブランチ上で作業してコミット
- こまめなpush
- masterにまーずするためにプルリクエストを行う
- テストとデプロイは自動化する

## Git Flowにおけるブランチとその役割
### masterブランチ
- リリース時に初めてコミットされるブランチ
- masterの先頭は常にサービスの最新のリリースになっていなければならない
- リリースごとにタグを打つ
### developブランチ
- masterからブランチを切る
- 実際の開発を行うためのブランチ
### featureブランチ
- 複数人でデベロップを開発する際に使用するブランチ
- developからブランチを切る
- 一つの機能につき一つのfeatureブランチを作成
- 大きな機能ではfeatureから更にfeatureを切ることもある
### releaseブランチ（stagingブランチ）
- developからmasterへmergeするための準備を行うブランチ
- プロジェクトにより使い方は様々
### hotfixブランチ
- masterブランチで発生した緊急性の高いバグを修正するためのブランチ
- develop以外で唯一masterから切られるブランチ
- 修正が完了したらmasterおよびdevelopにmerge
- hotofixからmasterを更新したらpatchバージョンを上げる

## 最後に
とても初歩的な内容ですが、gitの使い方を徹底することはチーム開発を行う上でとても重要だと思うので、備忘録的な感じで記事に残しておきました。
SSMSを利用してデッドロックを調査したい

デッドロックを調査するにあたって、SSMSを利用することがあったので、手順を自分用にまとめておきたいと思います。

① オブジェクトエクスプローラーで、調査対象のDB > 管理 > 拡張イベント > セッション > system_health > packageX.event_file を選択します。 

![スクリーンショット 2022-10-19 182628.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/fd7255a0-cce0-3482-5087-19ce1a8bfcd1.png)


② イベントの一覧が表示されるので、ここから対象のデッドロックイベントを探します。目検してもよいのですが、イベント数が多い場合はフィルタリング機能を利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/261650e3-61f3-1125-fa00-1a39a4191fbc.png)


③ 拡張イベント > フィルター を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/e0092d17-2013-4b6e-baae-fa9ce6841ea6.png)

④ 以下を入力し、OKボタンを押下します。

- フィールド: name
- 演算子: =
- 値: xml_deadlock_report

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/1012e71d-16a6-fbd1-5cb8-85872ff16be9.png)


⑤ フィルタリングされたデッドロックイベントの中から、調査したいデッドロックイベントを選択すると、詳細タグとデッドロックタグが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/9293576f-4a21-e3cc-61e5-001532140a00.png)

⑥ デッドロックタグを選択すると、デッドロックの詳細がグラフィカルに表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/c556b312-263a-ae19-b97e-68a268f40edd.png)

⑦ より詳細を確認したい場合は、詳細タグの値をクリックすると、デッドロックの詳細がxml形式で表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/daf46c59-fae6-76a1-7e40-1a2effa850d6.png)

__環境情報__

![SSMS_Version.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/f64a7d6c-f1b7-eeea-120b-e3b89c889a11.png)
AtCoder ABC286-G のグラフを図示してみる

# はじめに

[ウルシステムズプログラミングコンテスト2023\(AtCoder Beginner Contest 286\) \- AtCoder](https://atcoder.jp/contests/abc286) 2023/01/21 お疲れさまでした。

今回の G 問題は一見難しそうですが、気づくと簡単というものでした。グラフでざっくり図示してみます。

# TL;DR

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118172/2cfce03e-4401-d88b-e87d-ed2db4153640.png)

# 入力例1 

以下のグラフが与えられます。
実線を 1 度ずつ通る方法はあるか、という問題です。破線は通らなくても良いし、複数回通っても良いです。

```mermaid
flowchart TB
    1---3
    2---3
    3-.-4
    4---5
    4---6
    5-.-6
```

`1 → 3 → 4 → 5 → 6 → 4 → 3 → 2` のような経路があります。

```mermaid
flowchart TB
    1--->3
    3--->2
    3-.->4
    4-.->3
    4--->5
    6--->4
    5-.->6
```

## 破線をつぶす

破線の中は自由に行き来できるということは、破線でつながったノードは一つにまとめて考えられます。

```mermaid
flowchart TB
    1---3
    2---3
    subgraph 3,4
    3-.-4
    end
    4---5
    4---6
    subgraph 5,6
    5-.-6
    end
```

たとえば自由に行き来できる `3,4` のノードをひとつにまとめて、`1`, `2`, `5`, `6` 行きの 4本の経路が伸びている、と考えられます。 

`5,6` も同様にまとめられます。まとめると次のようになります。

```mermaid
flowchart TB
    1---3,4
    2---3,4
    3,4---5,6
    3,4---5,6
```

こうなると普通の一筆書き問題です。 奇数本のエッジが出ているノードは `1`, `2` の 2つで、これが始終点となります。 `1 → 3,4 → 5,6 → 3,4 → 2` のような経路があります。


# 入力例2 

```mermaid
flowchart TB
    1---2
    1---3
    1---4
    1-.-5
    1-.-6
```

## 破線をつぶす

```mermaid
flowchart TB
    1---2
    1---3
    1---4
    subgraph 1,5,6
    1-.-5
    1-.-6
    end
```

```mermaid
flowchart TB
    1,5,6---2
    1,5,6---3
    1,5,6---4
```

奇数本のエッジが出ているノードは `1,5,6`, `2`, `3`, `4` の 4つです。このノードが 4つ以上ある場合は、一筆書きできません。

# 実装方針

破線でつながったノードの組を UnionFind に登録していけば、破線をつぶしたノード群が得られます。

このノード群に対して実線のエッジ数をそれぞれ数えます。エッジ数が奇数のノードが 0 個または 2 個なら一筆書きできる、それ以上なら一筆書きできないと答えます。終了。

Rust 解答例: [提出 \#38232470 \- ウルシステムズプログラミングコンテスト2023\(AtCoder Beginner Contest 286\)](https://atcoder.jp/contests/abc286/submissions/38232470)


# 最後に

コンテスト中に F 問題を飛ばして先に G 問題に挑む勇気はありませんでした。
Miroはまず何から始めたらいいのか？

## はじめに

他人に自分の考えを説明する際、言葉だけで説明するのではなく図も使って説明をすることがあるかと思います。
予め資料を用意する事もあるかと思いますが、毎回十分な準備ができる場面ばかりではありません。
他にも議論の場で参加者から出た意見を上手くまとめられず、会議が迷子になることもあるかと思います。

このような場面を補佐するツールの一つに、オンラインホワイトボードツール[「Miro」](https://miro.com/ja/)があります。

本記事では、Miro を実際に使用して便利に思った点をご紹介します。

## そもそも Miro とは

Miro はオンラインホワイトボードとして、リモートや対面での会議においてチームでの共同作業を活性化することが目的のホワイトボードアプリです。

個人のリテラシーに関係なく直感的な使用ができ、誰とでも情報を共有またはリアルタイムでの共同作業を実現することが可能であることが良さの一つだと言われています。

## まずは基本のホワイトボードから

Miro には 300 種類以上のテンプレートが用意されていますが、まずは標準のホワイトボードに直接描いていく方が、描く作業よりも議論の方に集中できるので良いかと思います。
![miroWhereStart_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/63541360-9380-de08-6ee0-97fcf459d42e.png)

議題例は Qiita に記事を投稿する流れです。
まず（画像１）のような流れを描いて説明したとします。
その際（画像２）のように、ワンタッチで綺麗な図を描くことができるため、説明する方に集中することができます。

（画像１）
![miroWhereStart_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/5ce95213-49f0-d9d9-db7f-0c92b2920fb2.png)

（画像２）
![miroWhereStart_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/0d61f6f5-0ef5-f25f-4691-740a0f6062fd.png)


説明後、参加者から頂いたアドバイスを図に追記します。
その際もコネクタを自由に付け替えできるため、フローの途中への挿入もスムーズに行うことができます。

他にも（画像３）のように視覚的に分かり易くする機能や便利な機能が備わっているので、議論に上がった内容を参加者全員で共有しやすくなるかと思います。

（画像３）
![miroWhereStart_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/f44786ab-36a6-6b40-49ac-32135baaa634.png)

## ダウンロード

Miro[（公式サイト）](https://miro.com/ja/)

ご参考になれば幸いです。最後までお読み頂きありがとうございます。


## 関連した投稿

[Miroのボードは無料版だと全世界に公開される？](https://qiita.com/tamaday/items/82e7b9dfd70692488dd2)
[Miroでシステム化要件【画面イメージ／画面レイアウト】](https://qiita.com/tamaday/items/b46413b5620849c89b08)
[Miroでシステム化要件【動く画面遷移図】](https://qiita.com/tamaday/items/94af9158e79eec21a71e)
[Miroでファイルをエクスポートする方法](https://qiita.com/tamaday/items/cd3bfd4cb1a15360fe63)
【HTML】form 内で button 要素を押した場合に必ずsubmitしてしまう原因

# はじめに
だいぶ初歩的な部分ではありますが、ちょっとハマったのでメモ。

# 事象
form内にあるbuttonのclickイベント時にjQueryで処理を実行していたが、何らかの別のイベントも発火していたらしく意図した挙動になっていなかった。

# 原因
form内にあるbuttonでtype属性指定なしだと、submitイベントが発火する仕様があるとのことでそれが原因だった。
```html:qiita.html
<button>ボタン</button>
```

# 対策
type属性をbuttonに設定すると、submitイベントが発火しなくなるとのことで解決！
```html:qiita.html
<button type='button'>ボタン</button>
```

# 最後に
割と単純なことではあったが、ハマってしまった。。。

# 参考
https://kosiro.tech/front-end/html-button-1.html
【UserLAnd】UbuntuでNode.js環境構築

# はじめに
家にPCがないのでスマホ（Android）で開発環境を構築しようと考えました。

# 動作環境
* Sony Xperia 10 IV
* Android OS 12
* UserLAnd 3.1.4
* Ubuntu 20.04.5 LTS
* Nvm 0.39.3
* Node.js 18.13.0

# nvmをインストール
そのままapt installするとNode.jsのバージョンがnvmからインストールします。
```bash
$ curl -k -LO https://raw.githubusercontent.com/creationix/nvm/master/install.sh
```
install.shを編集（curlに「-k」オプションを付与）してUserLAndを再起動します。
* 編集前
```bash
nvm_download() {
  if nvm_has "curl"; then
    curl --fail --compressed -q "$@"
```
* 編集後
```bash
nvm_download() {
  if nvm_has "curl"; then
    curl -k --fail --compressed -q "$@"
```
install.shを実行します。
```bash
$ bash install.sh
```

# Node.jsをインストール
~/.nvm/nvm.shを編集（curlに「-k」オプションを付与）してUserLAndを再起動します。
* 編集前
```bash
nvm_download() {
  local CURL_COMPRESSED_FLAG
  if nvm_has "curl"; then
    if nvm_curl_use_compression; then
      CURL_COMPRESSED_FLAG="--compressed"
    fi
    curl --fail ${CURL_COMPRESSED_FLAG:-} -q "$@"
```
* 編集後
```bash
nvm_download() {
  local CURL_COMPRESSED_FLAG
  if nvm_has "curl"; then
    if nvm_curl_use_compression; then
      CURL_COMPRESSED_FLAG="--compressed"
    fi
    curl -k --fail ${CURL_COMPRESSED_FLAG:-} -q "$@"
```
Node.jsの最新LTSバージョンをインストールします。
```bash
$ nvm install --lts
```

# Node.jsのバージョンを確認
Node.jsのバージョンを確認します。
```bash
$ node --version
v18.13.0
```

# npmを最新化
付属のnpmは古いことが多いのでパッケージを更新します。
```bash
$ npm update -g npm
```

# npmのバージョンを確認
npmのバージョンを確認します。
```bash
$ npm --version
9.3.1
```
pythonで数字のファイル名を１つずつずらして名前変更

1.txt ⇒ 2.txt
2.txt ⇒ 3.txt
3.txt ⇒ 4.txt

もっと良いやり方あったら教えてくださいm(_ _)m

```python
import os
path = "./dirname"
folderfile = os.listdir(path)
file = [f for f in folderfile if os.path.isfile(os.path.join(path, f))]
newlist = sorted(file, reverse=True)
for f in newlist:
    basename_without_ext = int(os.path.splitext(os.path.basename(f))[0])
    before_name = os.path.join(path,f)
    after_name  = os.path.join(path, str(basename_without_ext + 1) + os.path.splitext(os.path.basename(f))[1])
    os.rename(before_name,after_name)
```
ObsidianのTrackerプラグインで活動時間のグラフを表示する

## 概要
デイリーノートのフロントマターに起床時間、就寝時間を記録すると、以下のようなグラフが表示されるようにした。
![tracker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269407/4705cad0-0920-719a-a4c0-eacd41634f31.png)
## 使用するプラグイン
- Tracker

https://github.com/pyrochlore/obsidian-tracker

## グラフ表示用ノート
~~~
```tracker
searchType: frontmatter
searchTarget: 就寝, 起床
startDate: 2023-01-01
endDate: 2023-01-31
folder: DailyNote
valueShift: -24:00, -24:00 
shiftOnlyValueLargerThan: 04:00, 04:00
datasetName: 就寝, 起床
line:
    title: "活動時間"
    yAxisLabel: "Time (24h)"
    lineColor: blue, red
    showPoint: true
    showLegend: true
    yMin: -24:00
summary:
	template: "平均活動時間:{{(average(dataset(0))-average(dataset(1)))/3600}}時間\n平均睡眠時間:{{24-(average(dataset(0))-average(dataset(1)))/3600}}時間"
```
~~~
## 記録ルール
- デイリーノートのフロントマターに起床時間、就寝時間を記入する。
  - 午前4時までには寝ること！
~~~
---
起床: 06:00
就寝: 00:30
---
~~~
以上
【UserLAnd】UbuntuでGit環境構築

# はじめに
家にPCがないのでスマホ（Android）で開発環境を構築しようと考えました。

# 動作環境
* Sony Xperia 10 IV
* Android OS 12
* UserLAnd 3.1.4
* Ubuntu 20.04.5 LTS
* Git 2.39.0

# リポジトリを追加
そのままapt installするとGitのバージョンが古いのでリポジトリを追加します。
```bash
$ sudo apt install software-properties-common
$ sudo add-apt-repository ppa:git-core/ppa
```

# Gitをインストール
Gitをインストールします。
```bash
$ sudo apt install git
```

# Gitのバージョンを確認
Gitのバージョンを確認します。
```bash
$ git --version
git version 2.39.0
```

# ユーザー名とEmailアドレスを設定
Gitで使用するユーザー名とEmailアドレスを設定します。
```bash
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
```
JetpackComposeでタップしている間だけテキストの色が変わる方法

JetpackComposeでタップしている間だけテキストの色が変わる方法の簡単なサンプルを紹介いたします。

# 実装サンプル
```ClickText.kt
@Composable
fun ClickText(
    modifier: Modifier = Modifier,
    onClick: () -> Unit = {},
    text: String,
    interactionSource: MutableInteractionSource =
        remember { MutableInteractionSource() }
) {
    val isLinkTextPressed by interactionSource.collectIsPressedAsState()
    Text(
        modifier = modifier
            .clickable(
                onClick = { onClick.invoke() },
                indication = null,
                interactionSource = interactionSource
            ),
        text = text,
        style = Typography().body2.copy(
            color = if (isLinkTextPressed) {
                Color(0x8000FF00)
            } else {
                Color(0xFF00FF00)
            }
        )
    )
}
```

`interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }`

操作の状態に関する物です。詳しくはリファレンスにあります。



`val isLinkTextPressed by interactionSource.collectIsPressedAsState()`
今回はタップされて居るかどうかなのでcollectIsPressedAsStateを使用します。

あとは`Modifierのclickable`に設定します。
その後`isLinkTextPressed`の状態を見てカラーを設定すれば終わります。



# リファレンス
https://developer.android.com/jetpack/compose/handling-interaction?hl=ja#interaction-state
【Kotlin Server】Resourcesリポジトリに配置したJsonファイルを参照する方法

# はじめに
Ktorを導入しているサーバーサイドの対応をお手伝いしているのですが、Resourcesファイル内のjsonファイルに参照する必要がありました。
実装自体は非常にシンプルなのですが、備忘録的にまとめておこうと思います。

# 参照方法
参照方法は非常に簡単です。
任意の箇所で以下を実装するだけになります。

```
val jsonText = this::class.java.classLoader.getResource("Test.json")?.readText()
```
以上になります。
上記で取得したjson文字列を任意のライブラリを使用しパースしていただければ良いかと思います。

# さいごに
今年に入ってアプリとサーバー半々くらいで活動しています。
こういったシンプルなロジックであったとしても検索コストはかかってしまうので、どんどんまとめて効率的に作業を進めていきたいと思います。
Storybook + Vite + Typescriptでtsconfig.jsonに記載しているPathAliasが正しく動作しない問題

## 解決方法
storybookの設定ファイルでviteの設定ファイルを読み込む準備をする。
mergeConfigのpluginsを追加するところで、`vite-tsconfig-paths`のプラグインを追加する。

```typescript:.storybook/main.ts
const tsconfigPaths = require("vite-tsconfig-paths").default;

...

async viteFinal(config, { configType }) {
    // Add your configuration here
    const { config: userConfig } = await loadConfigFromFile(
      configType,
      path.resolve(__dirname, "../vite.config.ts")
    );
    
    // ここでtsconfigの情報をマージし、pathaliasを有効にする
    return mergeConfig(config, {
      ...userConfig,
      plugins: [tsconfigPaths()],
    });
  },
```

参考：https://github.com/storybookjs/builder-vite/issues/85#issuecomment-900831050
yarn workspace + eslint でモジュールエラーになる

ルートに workspace 共通で使用するライブラリを用意していると、eslint が正しく参照できずエラー(import/no-extraneous-dependencies)になる。
これを解決するために eslint のルールを変更する。
```javascript:eslintrc.js
module.exports = {
  ...

  rules: {
    "import/no-extraneous-dependencies": [
      "error",
      {
        // プロジェクトから見てルートを指定
        packageDir: "../../",
      },
    ],
  }
}
```

参考：https://stackoverflow.com/a/45841939
【AWS】Lambda関数のトリガーを同じS3にした時にハマった話

タイトルの通りです。
エラー解消のため、調査したので備忘録となります。

結論
======
- AWS Step Functionsを使う

https://aws.amazon.com/jp/step-functions/

経緯
======
- Lambda関数のトリガーでS3バケットをしていたところ、以下のエラーが表示。
```
Configuration is ambiguously defined.
Cannot have overlapping suffixes in two rules
if the prefixes are overlapping for the same event type. 
```
Google翻訳の結果
```
構成の定義があいまいです。
プレフィックスが同じイベントタイプで重複している場合、
2つのルールでサフィックスを重複させることはできません。
```
つまり、同じ条件のS3トリガーを作成することができない。
この場合、AWS StepFunctionsを使うこととなる。

対処法
======
色々調査した結果、以下の投稿者様の記事が参考になったのでご紹介。

#### 考え方

https://bftnagoya.hateblo.jp/entry/2021/12/09/103727

#### 設定方法

https://qiita.com/miyuki_samitani/items/6c58d107cdc86d938fe3

https://aws.amazon.com/jp/premiumsupport/knowledge-center/lambda-s3-event-configuration-error/

#### S3トリガー設定の後処理

https://qiita.com/mattun_evo/items/cbbed21280d620f9030a


上記の記事を書いていただいた皆様、ありがとうございます。
助かりました。
Googleプロジェクト管理：チームの有効性に影響を与える5つの要因

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/dc97f9d2-8c30-5310-a190-3fb484c9c091.png" width="800">

# チームの有効性に影響を与える5つの要因

チームのメンバー全員を同時に動機づける方法を決定するためには、チームのメンバーについて学ぶ必要があります。Googleの研究者たちは、チームの有効性に影響を与える5つの要因を特定したのです。

***重要な順***

1. 心理的安全性（Psychological safety）
1. 信頼性（Dependability）
1. 構造と明確さ（Structure and clarity）
1. 意味（Meaning）
1. 影響（Impact）

## <font color="MediumBlue">1.心理的安全性</font>

心理的安全性とは、対人関係のリスクを負うことによって生じる、個人の知覚のことである。言い換えれば、彼らはチーム内でリスクを取っても安全だと考えており、無知、無能、否定的、破壊的というレッテルを貼られるリスクはないと考えているのです。

心理的安全性が高いチームでは、***<font color="MediumVioletRed">チームメイトは仲間の周りでリスクを取ることに抵抗がなく、異なる意見を求め、人間関係の衝突が起きても解決する</font>*** ことができます。

例えば、

- Googleの私のチームでは、「直接的で親切であれ」と言うのが好きです。私たちは、安全、安心、そして平和な共有空間を維持しながら、互いに責任を負えるようなチーム文化を築くために、本当に努力してきました。
- 既成概念にとらわれないアイデアをディレクターに提案するなど、リスクをとる機会があったとき、この相互尊重の文化が、イライラしたり、恥をかくかもしれないという心配をしたりせずに、直接フィードバックを得るための土台をすでに作ってくれていることがわかりました。これは、チームの心理的安全性を高く保つ上で、非常に重要なことです。

## <font color="MediumBlue">2.信頼性</font>

信頼できるチームでは、メンバーは信頼でき、時間通りに仕事を完了する。

信頼できるチームを作るには、期待を設定し、交渉し、それに応えるという組み合わせが必要です。そう、あなたのチームは彼らに設定された期待に応える必要があるのです。同時に、プロジェクトマネージャーとして、あなたはチームと双方向の関係を築く必要があるのです。

あなたは、***<font color="MediumVioletRed">期待を明確に伝え、必要なときにチームが安心してあなたと交渉できる</font>*** ようにしなければならない。

例えば、

- あなたのチームのある人は、納期が競合する2つ以上のプロジェクトに携わっている可能性があります。もし彼らが自分自身の制約をあなたと共有することを恐れているなら、両方のプロジェクトでの仕事に支障をきたすかもしれません。
- あるいは、もし彼らが懸念を抱いてあなたに相談し、優先順位についてオープンに理解し交渉すれば、彼らの負担を軽減することができるかもしれない。

## <font color="MediumBlue">3.構造と明確さ</font>

個人が仕事の期待、その期待に応える方法、そのパフォーマンスの結果についての知識を理解することである。チームメンバーはそれぞれ、自分の役割、計画、目標について明確な感覚を持っている。そして、自分の仕事がグループにどのような影響を与えるかについて、感覚的に理解している。プロジェクトマネージャーであるあなたは、チームに構造的な感覚と明確さを育む手助けをすることができます。

例えば、

- プロジェクトのトラッキングの構造がずさんで、整理されておらず、まとまりがない場合、チームのアウトプットもずさんで、整理されておらず、まとまりがないものになりがちです。これはチーム内に緊張をもたらす可能性がある。
- 代わりに、プロジェクトトラッキングに熱心に取り組めば、チームは明確になり、より一体感を感じ、効果的にコラボレーションできるようになります。


## <font color="MediumBlue">4.意味</font>

Googleの研究者は、意味を「仕事そのもの、または仕事の結果のどちらかに目的意識を見出すこと」と定義しています。

例えば、チームメイトは、

- 自分たちを経済的に支援すること
- チームの目標達成を支援すること
- 自分たちの製品が新しいユーザーコミュニティーに届くこと

を望むことに意味を見いだすかもしれません。

## <font color="MediumBlue">5.影響</font>

Googleの研究者は、影響を「自分の仕事の結果が重要であり、変化を生み出すと信じること」と定義しています。

プロジェクト・マネージャーとしてのあなたの役割は、個々のチームメイトがチーム内外でどのように影響を与えているかを確認するのを助けることです。プロジェクト・トラッキングは、進捗と影響を可視化するための有用なツールです。

例えば、
- マイルストーンを達成することで、個々のタスクがプロジェクトの大きな目標にどのように貢献しているかをチームに示すことができます。
- 私のチームはGoogle Mapsのルーティングにフォーカスしています。大きな目的は、人々が時間通りに目的地に到着できるようにすることです。そのために、私たちが行うすべての作業は、その体験を少しずつ良くしていくことです。
【vb.net】VBSを実行

## `概要`
##### vb.netのコンソールアプリからVBSを実行する

## `実装`

```vb:vb
    Sub RunVBSFile()
        Dim appPath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
        Dim appDir As String = System.IO.Path.GetDirectoryName(appPath)
        Dim filePath As String = System.IO.Path.Combine(appDir, "test.vbs")
        Dim process As New Process()
        process.StartInfo.FileName = "cscript.exe"
        process.StartInfo.Arguments = filePath
        process.Start()
        process.WaitForExit()
        Dim exitCode As Integer = process.ExitCode
        Console.WriteLine("Exit code: " & exitCode)
    End Sub
```
【vb.net】powershellスクリプトを実行

## `概要`
##### vb.netのコンソールアプリからpowershellスクリプトを実行する

## `実装`

```vb:vb
    Sub RunPowerShellScript()
        Dim script As String = "Write-Host 'Hello, from PowerShell!'"
        Dim psi As New ProcessStartInfo("powershell.exe", "-ExecutionPolicy Bypass -Command " & script)
        psi.RedirectStandardOutput = True
        psi.UseShellExecute = False
        psi.CreateNoWindow = True
        Dim process As Process = Process.Start(psi)
        Dim output As String = process.StandardOutput.ReadToEnd()
        Console.WriteLine(output)
    End Sub
```
【vb.net】ps1ファイルを実行

## `概要`
##### vb.netのコンソールアプリからps1ファイルを実行する

## `実装`

```vb:vb
    Sub RunPS1File()
        Dim filePath As String = "C:\test.ps1"
        Dim psi As New ProcessStartInfo("powershell.exe", "-ExecutionPolicy Bypass -File " & filePath)
        psi.RedirectStandardOutput = True
        psi.UseShellExecute = False
        psi.CreateNoWindow = True
        Dim process As Process = Process.Start(psi)
        Dim output As String = process.StandardOutput.ReadToEnd()
        Console.WriteLine(output)
    End Sub
```
【Xcode】MacOSアプリをリリースしようとしたらエラーが出た

# はじめに
久しぶりにMacOSアプリをリリースしようとしたらエラーが出たので記録しておきます。

# エラー
![スクリーンショット 2023-01-22 16.46.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4039c88e-c2c9-bd5c-9ec3-f0b2cd02ca26.png)
```
The product archive is invalid. The Info.plist must contain a LSApplicationCategoryType key, whose value is the UTI for a valid category. For more details, see "Submitting your Mac apps to the App Store". (ID: 54c62bd4-c581-4e3e-bdb3-f2c526f64d9c)
```

# 解決方法
① プロジェクトを選択します
② ターゲットを選択します
③ 「General」を選択します
④ 「App Category」をタップします
![スクリーンショット 2023-01-22 17.00.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f5965468-2c45-33f0-5907-e60dc1d40a69.png)

⑤ カテゴリーの中から自分のアプリに合うものを選択します
![スクリーンショット 2023-01-22 18.28.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/3f5f7229-f685-97f3-f8ae-e8a6b12dd506.png)

# おわり
もう1度「Archive」を行うと通るようになります。
VS Code拡張機能でファイルをドラッグアンドドロップしたエディタを特定する方法

## TL;DR

```ts
export class HogehogeDropProvider
    implements vscode.DocumentDropEditProvider
{
    async provideDocumentDropEdits(
        _document: vscode.TextDocument,
    ): Promise<vscode.DocumentDropEdit> {
        // 開いているエディタの中から、ドロップ先のエディタを特定する
        // プロバイダが返してきたTextDocumentの内容と一致するエディタを見つけてくる
        // 複数あるときは先頭のエディタをドロップしたエディタとする
        const editor = vscode.window.visibleTextEditors.filter(v => v.document === _document)[0];

        // ドロップ位置とファイル終端に同時に挿入する
        editor?.edit((editBuilder: vscode.TextEditorEdit) => {
            // ファイルの末尾に挿入する。
            editBuilder.insert(new vscode.Position(editor.document.lineCount, 0), "ここがファイルの終端");
        });

        // 上の処理で挿入位置やactiveEditorがずれるのでここでは空文字列を返しておく
        return {
            insertText: ""
        };
    }
}
```